mirror of
https://gitlab.com/phoenix-dvpmt/mmocore.git
synced 2024-11-24 00:15:16 +01:00
!skill refactor
This commit is contained in:
parent
c1a98bc5a5
commit
8525a1c56d
2
pom.xml
2
pom.xml
@ -131,7 +131,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.lumine</groupId>
|
<groupId>io.lumine</groupId>
|
||||||
<artifactId>MythicLib</artifactId>
|
<artifactId>MythicLib</artifactId>
|
||||||
<version>1.1.0</version>
|
<version>1.1.2</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
@ -32,10 +32,7 @@ import net.Indyuce.mmocore.comp.region.WorldGuardRegionHandler;
|
|||||||
import net.Indyuce.mmocore.comp.vault.VaultEconomy;
|
import net.Indyuce.mmocore.comp.vault.VaultEconomy;
|
||||||
import net.Indyuce.mmocore.comp.vault.VaultMMOLoader;
|
import net.Indyuce.mmocore.comp.vault.VaultMMOLoader;
|
||||||
import net.Indyuce.mmocore.listener.*;
|
import net.Indyuce.mmocore.listener.*;
|
||||||
import net.Indyuce.mmocore.listener.option.DeathExperienceLoss;
|
import net.Indyuce.mmocore.listener.option.*;
|
||||||
import net.Indyuce.mmocore.listener.option.NoSpawnerEXP;
|
|
||||||
import net.Indyuce.mmocore.listener.option.RedirectVanillaExp;
|
|
||||||
import net.Indyuce.mmocore.listener.option.VanillaExperienceOverride;
|
|
||||||
import net.Indyuce.mmocore.listener.profession.FishingListener;
|
import net.Indyuce.mmocore.listener.profession.FishingListener;
|
||||||
import net.Indyuce.mmocore.listener.profession.PlayerCollectStats;
|
import net.Indyuce.mmocore.listener.profession.PlayerCollectStats;
|
||||||
import net.Indyuce.mmocore.manager.ExperienceManager;
|
import net.Indyuce.mmocore.manager.ExperienceManager;
|
||||||
@ -232,6 +229,9 @@ public class MMOCore extends LuminePlugin {
|
|||||||
if (getConfig().getBoolean("death-exp-loss.enabled"))
|
if (getConfig().getBoolean("death-exp-loss.enabled"))
|
||||||
Bukkit.getPluginManager().registerEvents(new DeathExperienceLoss(), this);
|
Bukkit.getPluginManager().registerEvents(new DeathExperienceLoss(), this);
|
||||||
|
|
||||||
|
if (getConfig().getBoolean("shift-click-player-profile-check"))
|
||||||
|
Bukkit.getPluginManager().registerEvents(new PlayerProfileCheck(), this);
|
||||||
|
|
||||||
Bukkit.getPluginManager().registerEvents(new WaypointsListener(), this);
|
Bukkit.getPluginManager().registerEvents(new WaypointsListener(), this);
|
||||||
Bukkit.getPluginManager().registerEvents(new PlayerListener(), this);
|
Bukkit.getPluginManager().registerEvents(new PlayerListener(), this);
|
||||||
Bukkit.getPluginManager().registerEvents(new GoldPouchesListener(), this);
|
Bukkit.getPluginManager().registerEvents(new GoldPouchesListener(), this);
|
||||||
|
@ -1,17 +1,13 @@
|
|||||||
package net.Indyuce.mmocore.api.event;
|
package net.Indyuce.mmocore.api.event;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import net.Indyuce.mmocore.api.block.BlockInfo;
|
||||||
import java.util.List;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.event.Cancellable;
|
import org.bukkit.event.Cancellable;
|
||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import net.Indyuce.mmocore.api.block.BlockInfo;
|
import java.util.List;
|
||||||
import net.Indyuce.mmocore.api.droptable.condition.ConditionInstance;
|
|
||||||
import net.Indyuce.mmocore.api.loot.LootBuilder;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
|
|
||||||
public class CustomBlockMineEvent extends PlayerDataEvent implements Cancellable {
|
public class CustomBlockMineEvent extends PlayerDataEvent implements Cancellable {
|
||||||
private static final HandlerList handlers = new HandlerList();
|
private static final HandlerList handlers = new HandlerList();
|
||||||
@ -20,19 +16,15 @@ public class CustomBlockMineEvent extends PlayerDataEvent implements Cancellable
|
|||||||
private final BlockInfo info;
|
private final BlockInfo info;
|
||||||
private final List<ItemStack> drops;
|
private final List<ItemStack> drops;
|
||||||
|
|
||||||
@Deprecated
|
private boolean cancelled;
|
||||||
private boolean canBreak;
|
|
||||||
private boolean cancelled = false;
|
|
||||||
|
|
||||||
public CustomBlockMineEvent(PlayerData player, Block block, BlockInfo info, boolean canBreak) {
|
public CustomBlockMineEvent(PlayerData player, Block block, BlockInfo info, List<ItemStack> drops, boolean cancelled) {
|
||||||
super(player);
|
super(player);
|
||||||
|
|
||||||
this.block = block;
|
this.block = block;
|
||||||
this.info = info;
|
this.info = info;
|
||||||
this.drops = (info.hasDropTable() && player.isOnline() && info.getDropTable().areConditionsMet(new ConditionInstance(player.getPlayer())))
|
this.drops = drops;
|
||||||
? info.collectDrops(new LootBuilder(player, 0))
|
this.cancelled = cancelled;
|
||||||
: new ArrayList<>();
|
|
||||||
this.canBreak = canBreak;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Block getBlock() {
|
public Block getBlock() {
|
||||||
@ -47,16 +39,6 @@ public class CustomBlockMineEvent extends PlayerDataEvent implements Cancellable
|
|||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public boolean canBreak() {
|
|
||||||
return canBreak;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void setCanBreak(boolean value) {
|
|
||||||
canBreak = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCancelled() {
|
public boolean isCancelled() {
|
||||||
return cancelled;
|
return cancelled;
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
package net.Indyuce.mmocore.api.event;
|
package net.Indyuce.mmocore.api.event;
|
||||||
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.skill.Skill.SkillInfo;
|
import net.Indyuce.mmocore.skill.Skill.SkillInfo;
|
||||||
import net.Indyuce.mmocore.api.skill.SkillResult;
|
import net.Indyuce.mmocore.skill.metadata.SkillMetadata;
|
||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
|
|
||||||
public class PlayerPostCastSkillEvent extends PlayerDataEvent {
|
public class PlayerPostCastSkillEvent extends PlayerDataEvent {
|
||||||
private static final HandlerList handlers = new HandlerList();
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
|
||||||
private final SkillInfo skill;
|
private final SkillInfo skill;
|
||||||
private final SkillResult result;
|
private final SkillMetadata result;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called right after a player casts a skill.
|
* Called right after a player casts a skill.
|
||||||
@ -18,7 +18,7 @@ public class PlayerPostCastSkillEvent extends PlayerDataEvent {
|
|||||||
* @param skill Skill being cast
|
* @param skill Skill being cast
|
||||||
* @param result SKill casting result
|
* @param result SKill casting result
|
||||||
*/
|
*/
|
||||||
public PlayerPostCastSkillEvent(PlayerData playerData, SkillInfo skill, SkillResult result) {
|
public PlayerPostCastSkillEvent(PlayerData playerData, SkillInfo skill, SkillMetadata result) {
|
||||||
super(playerData);
|
super(playerData);
|
||||||
|
|
||||||
this.skill = skill;
|
this.skill = skill;
|
||||||
@ -29,7 +29,7 @@ public class PlayerPostCastSkillEvent extends PlayerDataEvent {
|
|||||||
return skill;
|
return skill;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SkillResult getResult() {
|
public SkillMetadata getResult() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package net.Indyuce.mmocore.api.event;
|
package net.Indyuce.mmocore.api.event;
|
||||||
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.skill.Skill.SkillInfo;
|
import net.Indyuce.mmocore.skill.Skill.SkillInfo;
|
||||||
import org.bukkit.event.Cancellable;
|
import org.bukkit.event.Cancellable;
|
||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package net.Indyuce.mmocore.api.event;
|
|||||||
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
|
import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
|
||||||
|
import net.Indyuce.mmocore.skill.list.Neptune_Gift;
|
||||||
import org.bukkit.event.Cancellable;
|
import org.bukkit.event.Cancellable;
|
||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
|
|
||||||
@ -27,7 +28,7 @@ public class PlayerResourceUpdateEvent extends PlayerDataEvent implements Cancel
|
|||||||
* Called when a player gains some resource back. This can
|
* Called when a player gains some resource back. This can
|
||||||
* be used to handle stats like health or mana regeneration.
|
* be used to handle stats like health or mana regeneration.
|
||||||
* <p>
|
* <p>
|
||||||
* Example use: {@link net.Indyuce.mmocore.skill.Neptune_Gift} which is a skill
|
* Example use: {@link Neptune_Gift} which is a skill
|
||||||
* that temporarily increases resource regeneration for a short amount of time.
|
* that temporarily increases resource regeneration for a short amount of time.
|
||||||
*
|
*
|
||||||
* @param playerData Player regenerating
|
* @param playerData Player regenerating
|
||||||
|
@ -23,6 +23,7 @@ import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
|||||||
import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect;
|
import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect;
|
||||||
import net.Indyuce.mmocore.listener.SpellCast.SkillCasting;
|
import net.Indyuce.mmocore.listener.SpellCast.SkillCasting;
|
||||||
import net.Indyuce.mmocore.manager.SoundManager;
|
import net.Indyuce.mmocore.manager.SoundManager;
|
||||||
|
import net.Indyuce.mmocore.skill.CasterMetadata;
|
||||||
import net.Indyuce.mmocore.skill.PlayerSkillData;
|
import net.Indyuce.mmocore.skill.PlayerSkillData;
|
||||||
import net.Indyuce.mmocore.skill.Skill;
|
import net.Indyuce.mmocore.skill.Skill;
|
||||||
import net.Indyuce.mmocore.skill.Skill.SkillInfo;
|
import net.Indyuce.mmocore.skill.Skill.SkillInfo;
|
||||||
@ -819,7 +820,8 @@ public class PlayerData extends OfflinePlayerData {
|
|||||||
return new SkillMetadata(this, skill, CancelReason.OTHER);
|
return new SkillMetadata(this, skill, CancelReason.OTHER);
|
||||||
|
|
||||||
// Check for mana/stamina/cooldown and cast skill
|
// Check for mana/stamina/cooldown and cast skill
|
||||||
SkillMetadata cast = skill.getSkill().whenCast(this, skill);
|
CasterMetadata casterMeta = new CasterMetadata(this);
|
||||||
|
SkillMetadata cast = skill.getSkill().whenCast(casterMeta, skill);
|
||||||
|
|
||||||
// Send failure messages
|
// Send failure messages
|
||||||
if (!cast.isSuccessful()) {
|
if (!cast.isSuccessful()) {
|
||||||
|
@ -14,8 +14,8 @@ import net.Indyuce.mmocore.api.player.profess.resource.ManaDisplayOptions;
|
|||||||
import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
|
import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
|
||||||
import net.Indyuce.mmocore.api.player.profess.resource.ResourceHandler;
|
import net.Indyuce.mmocore.api.player.profess.resource.ResourceHandler;
|
||||||
import net.Indyuce.mmocore.api.player.stats.StatType;
|
import net.Indyuce.mmocore.api.player.stats.StatType;
|
||||||
import net.Indyuce.mmocore.api.skill.Skill;
|
import net.Indyuce.mmocore.skill.Skill;
|
||||||
import net.Indyuce.mmocore.api.skill.Skill.SkillInfo;
|
import net.Indyuce.mmocore.skill.Skill.SkillInfo;
|
||||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
import net.Indyuce.mmocore.api.util.math.particle.CastingParticle;
|
import net.Indyuce.mmocore.api.util.math.particle.CastingParticle;
|
||||||
|
@ -13,7 +13,7 @@ import com.google.gson.JsonObject;
|
|||||||
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
|
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
|
||||||
import net.Indyuce.mmocore.api.skill.Skill;
|
import net.Indyuce.mmocore.skill.Skill;
|
||||||
import net.Indyuce.mmocore.manager.data.PlayerDataManager.DefaultPlayerData;
|
import net.Indyuce.mmocore.manager.data.PlayerDataManager.DefaultPlayerData;
|
||||||
|
|
||||||
public class SavedClassInformation {
|
public class SavedClassInformation {
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
package net.Indyuce.mmocore.api.player.profess.event.trigger;
|
package net.Indyuce.mmocore.api.player.profess.event.trigger;
|
||||||
|
|
||||||
import org.bukkit.event.EventHandler;
|
import io.lumine.mythic.lib.api.event.PlayerAttackEvent;
|
||||||
import org.bukkit.event.EventPriority;
|
import io.lumine.mythic.lib.damage.DamageType;
|
||||||
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
|
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
|
||||||
import net.Indyuce.mmocore.api.player.profess.event.EventTriggerHandler;
|
import net.Indyuce.mmocore.api.player.profess.event.EventTriggerHandler;
|
||||||
import io.lumine.mythic.lib.api.DamageType;
|
import org.bukkit.event.EventHandler;
|
||||||
import io.lumine.mythic.lib.api.event.PlayerAttackEvent;
|
import org.bukkit.event.EventPriority;
|
||||||
|
|
||||||
public class AttackEventTrigger implements EventTriggerHandler {
|
public class AttackEventTrigger implements EventTriggerHandler {
|
||||||
|
|
||||||
@ -16,7 +15,7 @@ public class AttackEventTrigger implements EventTriggerHandler {
|
|||||||
return event.endsWith("-damage");
|
return event.endsWith("-damage");
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
public void a(PlayerAttackEvent event) {
|
public void a(PlayerAttackEvent event) {
|
||||||
// We don't want players dying by themselves when using an enderpearl.
|
// We don't want players dying by themselves when using an enderpearl.
|
||||||
if (event.getPlayer().equals(event.getEntity())) return;
|
if (event.getPlayer().equals(event.getEntity())) return;
|
||||||
@ -24,7 +23,7 @@ public class AttackEventTrigger implements EventTriggerHandler {
|
|||||||
PlayerData player = PlayerData.get(event.getData().getUniqueId());
|
PlayerData player = PlayerData.get(event.getData().getUniqueId());
|
||||||
PlayerClass profess = player.getProfess();
|
PlayerClass profess = player.getProfess();
|
||||||
|
|
||||||
for (DamageType type : event.getAttack().getTypes()) {
|
for (DamageType type : event.getAttack().getDamage().collectTypes()) {
|
||||||
String path = type.getPath() + "-damage";
|
String path = type.getPath() + "-damage";
|
||||||
if (profess.hasEventTriggers(path))
|
if (profess.hasEventTriggers(path))
|
||||||
profess.getEventTriggers(path).getTriggers().forEach(trigger -> trigger.apply(player));
|
profess.getEventTriggers(path).getTriggers().forEach(trigger -> trigger.apply(player));
|
||||||
|
@ -1,105 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.api.skill;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.api.skill.Skill.SkillInfo;
|
|
||||||
import net.Indyuce.mmocore.comp.flags.FlagPlugin.CustomFlag;
|
|
||||||
|
|
||||||
public class SkillResult {
|
|
||||||
private final SkillInfo skill;
|
|
||||||
private final int level;
|
|
||||||
private final double mana, cooldown, stamina;
|
|
||||||
|
|
||||||
private CancelReason cancelReason;
|
|
||||||
|
|
||||||
public SkillResult(PlayerData data, SkillInfo skill) {
|
|
||||||
this.skill = skill;
|
|
||||||
|
|
||||||
level = data.getSkillLevel(skill.getSkill());
|
|
||||||
cooldown = (skill.getSkill().hasModifier("cooldown") ? data.getSkillData().getCooldown(skill) : 0);
|
|
||||||
mana = (skill.getSkill().hasModifier("mana") ? skill.getModifier("mana", level) : 0);
|
|
||||||
stamina = (skill.getSkill().hasModifier("stamina") ? skill.getModifier("stamina", level) : 0);
|
|
||||||
cancelReason = !data.hasSkillUnlocked(skill) ? CancelReason.LOCKED
|
|
||||||
: cooldown > 0 ? CancelReason.COOLDOWN
|
|
||||||
: mana > data.getMana() ? CancelReason.MANA
|
|
||||||
: stamina > data.getStamina() ? CancelReason.STAMINA
|
|
||||||
: !MMOCore.plugin.flagPlugin.isFlagAllowed(data.getPlayer(), CustomFlag.SKILLS)
|
|
||||||
? CancelReason.FLAG
|
|
||||||
: null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SkillResult(PlayerData data, SkillInfo skill, CancelReason reason) {
|
|
||||||
this.skill = skill;
|
|
||||||
this.cancelReason = reason;
|
|
||||||
|
|
||||||
level = data.getSkillLevel(skill.getSkill());
|
|
||||||
cooldown = skill.getSkill().hasModifier("cooldown") ? data.getSkillData().getCooldown(skill) : 0;
|
|
||||||
mana = skill.getSkill().hasModifier("mana") ? skill.getModifier("mana", level) : 0;
|
|
||||||
stamina = (skill.getSkill().hasModifier("stamina") ? skill.getModifier("stamina", level) : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Skill getSkill() {
|
|
||||||
return skill.getSkill();
|
|
||||||
}
|
|
||||||
|
|
||||||
public SkillInfo getInfo() {
|
|
||||||
return skill;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLevel() {
|
|
||||||
return level;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getStaminaCost() {
|
|
||||||
return stamina;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getManaCost() {
|
|
||||||
return mana;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getCooldown() {
|
|
||||||
return cooldown;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSuccessful() {
|
|
||||||
return cancelReason == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CancelReason getCancelReason() {
|
|
||||||
return cancelReason;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void abort() {
|
|
||||||
abort(CancelReason.OTHER);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void abort(CancelReason reason) {
|
|
||||||
cancelReason = reason;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getModifier(String modifier) {
|
|
||||||
return skill.getModifier(modifier, level);
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum CancelReason {
|
|
||||||
|
|
||||||
// skill flag
|
|
||||||
FLAG,
|
|
||||||
|
|
||||||
// not enough mana
|
|
||||||
MANA,
|
|
||||||
|
|
||||||
// not enough stamina
|
|
||||||
STAMINA,
|
|
||||||
|
|
||||||
// skill still on cooldown
|
|
||||||
COOLDOWN,
|
|
||||||
|
|
||||||
// skill still not unlocked
|
|
||||||
LOCKED,
|
|
||||||
|
|
||||||
// no reason specified
|
|
||||||
OTHER
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,53 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.api.skill.result;
|
|
||||||
|
|
||||||
import org.bukkit.FluidCollisionMode;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.util.RayTraceResult;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.api.skill.Skill.SkillInfo;
|
|
||||||
import net.Indyuce.mmocore.api.skill.SkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
|
||||||
|
|
||||||
public class LocationSkillResult extends SkillResult {
|
|
||||||
private Location loc;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param data Player casting the skill
|
|
||||||
* @param skill Skill being cast
|
|
||||||
* @param range Skill raycast range
|
|
||||||
*/
|
|
||||||
public LocationSkillResult(PlayerData data, SkillInfo skill, double range) {
|
|
||||||
this(data, skill, range, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param data Player casting the skill
|
|
||||||
* @param skill Skill being cast
|
|
||||||
* @param range Skill raycast range
|
|
||||||
* @param buff If the skill is a buff ie if it can be cast on party members
|
|
||||||
*/
|
|
||||||
public LocationSkillResult(PlayerData data, SkillInfo skill, double range, boolean buff) {
|
|
||||||
super(data, skill);
|
|
||||||
|
|
||||||
if (isSuccessful()) {
|
|
||||||
|
|
||||||
RayTraceResult result = data.getPlayer().getWorld().rayTrace(data.getPlayer().getEyeLocation(),
|
|
||||||
data.getPlayer().getEyeLocation().getDirection(), range, FluidCollisionMode.ALWAYS, true, 1.0D,
|
|
||||||
entity -> MMOCoreUtils.canTarget(data, entity, buff));
|
|
||||||
if (result == null)
|
|
||||||
abort(CancelReason.OTHER);
|
|
||||||
else
|
|
||||||
loc = result.getHitBlock() != null ? result.getHitBlock().getLocation()
|
|
||||||
: result.getHitEntity() != null ? result.getHitEntity().getLocation() : null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasHit() {
|
|
||||||
return loc != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Location getHit() {
|
|
||||||
return loc;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.api.skill.result;
|
|
||||||
|
|
||||||
import org.bukkit.entity.LivingEntity;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.api.skill.Skill.SkillInfo;
|
|
||||||
import net.Indyuce.mmocore.api.skill.SkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
|
||||||
import io.lumine.mythic.lib.MythicLib;
|
|
||||||
import io.lumine.mythic.lib.api.MMORayTraceResult;
|
|
||||||
|
|
||||||
public class TargetSkillResult extends SkillResult {
|
|
||||||
private LivingEntity target;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param data Player casting the skill
|
|
||||||
* @param skill Skill being cast
|
|
||||||
* @param range Skill raycast range
|
|
||||||
*/
|
|
||||||
public TargetSkillResult(PlayerData data, SkillInfo skill, double range) {
|
|
||||||
this(data, skill, range, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param data Player casting the skill
|
|
||||||
* @param skill Skill being cast
|
|
||||||
* @param range Skill raycast range
|
|
||||||
* @param buff If the skill is a buff ie if it can be cast on party members
|
|
||||||
*/
|
|
||||||
public TargetSkillResult(PlayerData data, SkillInfo skill, double range, boolean buff) {
|
|
||||||
super(data, skill);
|
|
||||||
|
|
||||||
if (isSuccessful()) {
|
|
||||||
MMORayTraceResult result = MythicLib.plugin.getVersion().getWrapper().rayTrace(data.getPlayer(), range,
|
|
||||||
entity -> MMOCoreUtils.canTarget(data, entity, buff));
|
|
||||||
if (!result.hasHit())
|
|
||||||
abort();
|
|
||||||
else
|
|
||||||
target = result.getHit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check skill result abort reason instead
|
|
||||||
@Deprecated
|
|
||||||
public boolean hasTarget() {
|
|
||||||
return target != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LivingEntity getTarget() {
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
}
|
|
@ -21,7 +21,7 @@ public class ListCommandTreeNode extends CommandTreeNode {
|
|||||||
return CommandResult.FAILURE;
|
return CommandResult.FAILURE;
|
||||||
|
|
||||||
sender.sendMessage(ChatColor.YELLOW + "----------------------------------------------------");
|
sender.sendMessage(ChatColor.YELLOW + "----------------------------------------------------");
|
||||||
for (Booster booster : MMOCore.plugin.boosterManager.getBoosters())
|
for (Booster booster : MMOCore.plugin.boosterManager.getActive())
|
||||||
if (!booster.isTimedOut())
|
if (!booster.isTimedOut())
|
||||||
MythicLib.plugin.getVersion().getWrapper().sendJson((Player) sender, "{\"text\":\"" + ChatColor.YELLOW + "- " + ChatColor.GOLD
|
MythicLib.plugin.getVersion().getWrapper().sendJson((Player) sender, "{\"text\":\"" + ChatColor.YELLOW + "- " + ChatColor.GOLD
|
||||||
+ MythicLib.plugin.getMMOConfig().decimal.format((1 + booster.getExtra())) + "x" + ChatColor.YELLOW + " Booster - "
|
+ MythicLib.plugin.getMMOConfig().decimal.format((1 + booster.getExtra())) + "x" + ChatColor.YELLOW + " Booster - "
|
||||||
|
@ -16,7 +16,7 @@ public class RemoveCommandTreeNode extends CommandTreeNode {
|
|||||||
super(parent, "remove");
|
super(parent, "remove");
|
||||||
|
|
||||||
addParameter(new Parameter("<id>",
|
addParameter(new Parameter("<id>",
|
||||||
(explorer, list) -> MMOCore.plugin.boosterManager.getBoosters().forEach(booster -> list.add("" + booster.getUniqueId().toString()))));
|
(explorer, list) -> MMOCore.plugin.boosterManager.getActive().forEach(booster -> list.add("" + booster.getUniqueId().toString()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -32,7 +32,7 @@ public class RemoveCommandTreeNode extends CommandTreeNode {
|
|||||||
return CommandResult.FAILURE;
|
return CommandResult.FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Iterator<Booster> iterator = MMOCore.plugin.boosterManager.getBoosters().iterator(); iterator.hasNext();) {
|
for (Iterator<Booster> iterator = MMOCore.plugin.boosterManager.getActive().iterator(); iterator.hasNext();) {
|
||||||
Booster booster = iterator.next();
|
Booster booster = iterator.next();
|
||||||
if (booster.getUniqueId().equals(uuid)) {
|
if (booster.getUniqueId().equals(uuid)) {
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
package net.Indyuce.mmocore.comp.mythicmobs;
|
package net.Indyuce.mmocore.comp.mythicmobs;
|
||||||
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
|
|
||||||
import io.lumine.xikage.mythicmobs.MythicMobs;
|
import io.lumine.xikage.mythicmobs.MythicMobs;
|
||||||
import io.lumine.xikage.mythicmobs.api.bukkit.events.MythicDropLoadEvent;
|
import io.lumine.xikage.mythicmobs.api.bukkit.events.MythicDropLoadEvent;
|
||||||
import io.lumine.xikage.mythicmobs.api.bukkit.events.MythicReloadedEvent;
|
import io.lumine.xikage.mythicmobs.api.bukkit.events.MythicReloadedEvent;
|
||||||
@ -10,6 +7,8 @@ import io.lumine.xikage.mythicmobs.skills.placeholders.Placeholder;
|
|||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.comp.mythicmobs.load.CurrencyItemDrop;
|
import net.Indyuce.mmocore.comp.mythicmobs.load.CurrencyItemDrop;
|
||||||
import net.Indyuce.mmocore.comp.mythicmobs.load.GoldPouchDrop;
|
import net.Indyuce.mmocore.comp.mythicmobs.load.GoldPouchDrop;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
public class MythicMobsDrops implements Listener {
|
public class MythicMobsDrops implements Listener {
|
||||||
public MythicMobsDrops() {
|
public MythicMobsDrops() {
|
||||||
@ -41,8 +40,9 @@ public class MythicMobsDrops implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void registerPlaceholders() {
|
private void registerPlaceholders() {
|
||||||
MythicMobs.inst().getPlaceholderManager().register("mmocore.skill", Placeholder.meta((metadata, arg) -> String.valueOf(PlayerData.get(metadata.getCaster().getEntity().getUniqueId()).getSkillData().getCachedModifier(arg))));
|
// TODO
|
||||||
MythicMobs.inst().getPlaceholderManager().register("mmocore.skill.int", Placeholder.meta((metadata, arg) -> String.valueOf((int) PlayerData.get(metadata.getCaster().getEntity().getUniqueId()).getSkillData().getCachedModifier(arg))));
|
/*MythicMobs.inst().getPlaceholderManager().register("mmocore.skill", Placeholder.meta((metadata, arg) -> String.valueOf(PlayerData.get(metadata.getCaster().getEntity().getUniqueId()).getSkillData().getCachedModifier(arg))));
|
||||||
|
MythicMobs.inst().getPlaceholderManager().register("mmocore.skill.int", Placeholder.meta((metadata, arg) -> String.valueOf((int) PlayerData.get(metadata.getCaster().getEntity().getUniqueId()).getSkillData().getCachedModifier(arg))));*/
|
||||||
MythicMobs.inst().getPlaceholderManager().register("mmocore.mana", Placeholder.meta((metadata, arg) -> String.valueOf((int) PlayerData.get(metadata.getCaster().getEntity().getUniqueId()).getMana())));
|
MythicMobs.inst().getPlaceholderManager().register("mmocore.mana", Placeholder.meta((metadata, arg) -> String.valueOf((int) PlayerData.get(metadata.getCaster().getEntity().getUniqueId()).getMana())));
|
||||||
MythicMobs.inst().getPlaceholderManager().register("mmocore.stamina", Placeholder.meta((metadata, arg) -> String.valueOf((int) PlayerData.get(metadata.getCaster().getEntity().getUniqueId()).getStamina())));
|
MythicMobs.inst().getPlaceholderManager().register("mmocore.stamina", Placeholder.meta((metadata, arg) -> String.valueOf((int) PlayerData.get(metadata.getCaster().getEntity().getUniqueId()).getStamina())));
|
||||||
}
|
}
|
||||||
|
@ -2,30 +2,35 @@ package net.Indyuce.mmocore.comp.mythicmobs.skill;
|
|||||||
|
|
||||||
import io.lumine.mythic.lib.api.util.EnumUtils;
|
import io.lumine.mythic.lib.api.util.EnumUtils;
|
||||||
import io.lumine.xikage.mythicmobs.MythicMobs;
|
import io.lumine.xikage.mythicmobs.MythicMobs;
|
||||||
|
import io.lumine.xikage.mythicmobs.adapters.AbstractEntity;
|
||||||
|
import io.lumine.xikage.mythicmobs.adapters.AbstractLocation;
|
||||||
|
import io.lumine.xikage.mythicmobs.adapters.bukkit.BukkitAdapter;
|
||||||
|
import io.lumine.xikage.mythicmobs.mobs.GenericCaster;
|
||||||
|
import io.lumine.xikage.mythicmobs.skills.SkillCaster;
|
||||||
|
import io.lumine.xikage.mythicmobs.skills.SkillTrigger;
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.api.skill.Skill;
|
|
||||||
import net.Indyuce.mmocore.api.skill.SkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.skill.SkillResult.CancelReason;
|
|
||||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.IntegerLinearValue;
|
import net.Indyuce.mmocore.api.util.math.formula.IntegerLinearValue;
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
import net.Indyuce.mmocore.comp.anticheat.CheatType;
|
import net.Indyuce.mmocore.comp.anticheat.CheatType;
|
||||||
|
import net.Indyuce.mmocore.skill.CasterMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.Skill;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.SkillMetadata;
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.entity.Entity;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
public class MythicMobSkill extends Skill {
|
public class MythicMobSkill extends Skill {
|
||||||
private final io.lumine.xikage.mythicmobs.skills.Skill skill;
|
private final io.lumine.xikage.mythicmobs.skills.Skill skill;
|
||||||
private final Map<CheatType, Integer> antiCheat = new HashMap<>();
|
private final Map<CheatType, Integer> antiCheat = new HashMap<>();
|
||||||
|
|
||||||
//private final BiFunction<PlayerDataManager, SkillInfo, SkillResult> cast;
|
|
||||||
|
|
||||||
public MythicMobSkill(String id, FileConfiguration config) {
|
public MythicMobSkill(String id, FileConfiguration config) {
|
||||||
super(id);
|
super(id);
|
||||||
|
|
||||||
@ -64,10 +69,6 @@ public class MythicMobSkill extends Skill {
|
|||||||
setPassive();
|
setPassive();
|
||||||
Bukkit.getPluginManager().registerEvents(passiveType.get().getHandler(this), MMOCore.plugin);
|
Bukkit.getPluginManager().registerEvents(passiveType.get().getHandler(this), MMOCore.plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
// cast = config.getBoolean("target") ? (data, info) -> new
|
|
||||||
// TargetSkillResult(data, info, def(config.getDouble("range"), 50)) :
|
|
||||||
// (data, info) -> new SkillResult(data, info);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<CheatType, Integer> getAntiCheat() {
|
public Map<CheatType, Integer> getAntiCheat() {
|
||||||
@ -78,27 +79,31 @@ public class MythicMobSkill extends Skill {
|
|||||||
return skill.getInternalName();
|
return skill.getInternalName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public io.lumine.xikage.mythicmobs.skills.Skill getSkill() {
|
||||||
|
return skill;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SkillResult whenCast(PlayerData data, SkillInfo skill) {
|
public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) {
|
||||||
SkillResult cast = new SkillResult(data, skill);
|
SkillMetadata cast = new SkillMetadata(caster, skill);
|
||||||
if (!cast.isSuccessful() || !data.isOnline() || isPassive())
|
if (!cast.isSuccessful() || isPassive())
|
||||||
return cast;
|
return cast;
|
||||||
|
|
||||||
List<Entity> targets = new ArrayList<>();
|
HashSet<AbstractEntity> targetEntities = new HashSet<>();
|
||||||
// targets.add(cast instanceof TargetSkillResult ? ((TargetSkillResult)
|
HashSet<AbstractLocation> targetLocations = new HashSet<>();
|
||||||
// cast).getTarget() : stats.getPlayer());
|
|
||||||
targets.add(data.getPlayer());
|
|
||||||
|
|
||||||
/*
|
AbstractEntity trigger = BukkitAdapter.adapt(caster.getPlayer());
|
||||||
* cache placeholders so they can be retrieved later by MythicMobs math
|
SkillCaster skillCaster = new GenericCaster(trigger);
|
||||||
* formulas
|
io.lumine.xikage.mythicmobs.skills.SkillMetadata skillMeta = new io.lumine.xikage.mythicmobs.skills.SkillMetadata(SkillTrigger.API, skillCaster, trigger, BukkitAdapter.adapt(caster.getPlayer().getEyeLocation()), targetEntities, targetLocations, 1);
|
||||||
*/
|
|
||||||
data.getSkillData().cacheModifiers(this, cast);
|
// Disable anticheat
|
||||||
if (MMOCore.plugin.hasAntiCheat())
|
if (MMOCore.plugin.hasAntiCheat())
|
||||||
MMOCore.plugin.antiCheatSupport.disableAntiCheat(data.getPlayer(), antiCheat);
|
MMOCore.plugin.antiCheatSupport.disableAntiCheat(caster.getPlayer(), antiCheat);
|
||||||
if (!MythicMobs.inst().getAPIHelper().castSkill(data.getPlayer(), this.skill.getInternalName(), data.getPlayer(),
|
|
||||||
data.getPlayer().getEyeLocation(), targets, null, 1))
|
if (this.skill.usable(skillMeta, SkillTrigger.API))
|
||||||
cast.abort(CancelReason.OTHER);
|
this.skill.execute(skillMeta);
|
||||||
|
else
|
||||||
|
cast.abort();
|
||||||
|
|
||||||
return cast;
|
return cast;
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,20 @@
|
|||||||
package net.Indyuce.mmocore.comp.mythicmobs.skill;
|
package net.Indyuce.mmocore.comp.mythicmobs.skill;
|
||||||
|
|
||||||
import io.lumine.xikage.mythicmobs.MythicMobs;
|
import io.lumine.xikage.mythicmobs.adapters.AbstractEntity;
|
||||||
|
import io.lumine.xikage.mythicmobs.adapters.AbstractLocation;
|
||||||
|
import io.lumine.xikage.mythicmobs.adapters.bukkit.BukkitAdapter;
|
||||||
|
import io.lumine.xikage.mythicmobs.mobs.GenericCaster;
|
||||||
|
import io.lumine.xikage.mythicmobs.skills.SkillCaster;
|
||||||
|
import io.lumine.xikage.mythicmobs.skills.SkillTrigger;
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.skill.SkillResult;
|
import net.Indyuce.mmocore.skill.CasterMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.Skill;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.SkillMetadata;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.HashSet;
|
||||||
|
|
||||||
public abstract class PassiveMythicMobSkillHandler implements Listener {
|
public abstract class PassiveMythicMobSkillHandler implements Listener {
|
||||||
protected final MythicMobSkill skill;
|
protected final MythicMobSkill skill;
|
||||||
@ -19,22 +26,40 @@ public abstract class PassiveMythicMobSkillHandler implements Listener {
|
|||||||
this.skill = skill;
|
this.skill = skill;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void castSkill(PlayerData data) {
|
public SkillMetadata castSkill(PlayerData data) {
|
||||||
castSkill(data, data.getPlayer());
|
return castSkill(data, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void castSkill(PlayerData data, Entity target) {
|
public SkillMetadata castSkill(PlayerData playerData, Entity target) {
|
||||||
if (!data.getProfess().hasSkill(skill.getId()))
|
if (!playerData.getProfess().hasSkill(skill))
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
SkillResult cast = data.cast(data.getProfess().getSkill(skill.getId()));
|
Skill.SkillInfo skill = playerData.getProfess().getSkill(this.skill);
|
||||||
if (!cast.isSuccessful())
|
CasterMetadata caster = new CasterMetadata(playerData);
|
||||||
return;
|
SkillMetadata cast = new SkillMetadata(caster, skill);
|
||||||
|
if (!cast.isSuccessful() || this.skill.isPassive())
|
||||||
|
return cast;
|
||||||
|
|
||||||
data.getSkillData().cacheModifiers(skill.getInternalName(), cast);
|
HashSet<AbstractEntity> targetEntities = new HashSet<>();
|
||||||
|
HashSet<AbstractLocation> targetLocations = new HashSet<>();
|
||||||
|
|
||||||
|
// The only difference
|
||||||
|
if (target != null)
|
||||||
|
targetEntities.add(BukkitAdapter.adapt(target));
|
||||||
|
|
||||||
|
AbstractEntity trigger = BukkitAdapter.adapt(caster.getPlayer());
|
||||||
|
SkillCaster skillCaster = new GenericCaster(trigger);
|
||||||
|
io.lumine.xikage.mythicmobs.skills.SkillMetadata skillMeta = new io.lumine.xikage.mythicmobs.skills.SkillMetadata(SkillTrigger.API, skillCaster, trigger, BukkitAdapter.adapt(caster.getPlayer().getEyeLocation()), targetEntities, targetLocations, 1);
|
||||||
|
|
||||||
|
// Disable anticheat
|
||||||
if (MMOCore.plugin.hasAntiCheat())
|
if (MMOCore.plugin.hasAntiCheat())
|
||||||
MMOCore.plugin.antiCheatSupport.disableAntiCheat(data.getPlayer(), skill.getAntiCheat());
|
MMOCore.plugin.antiCheatSupport.disableAntiCheat(caster.getPlayer(), this.skill.getAntiCheat());
|
||||||
MythicMobs.inst().getAPIHelper().castSkill(data.getPlayer(), skill.getInternalName(), target,
|
|
||||||
data.getPlayer().getEyeLocation(), Collections.singletonList(data.getPlayer()), null, 1);
|
if (this.skill.getSkill().usable(skillMeta, SkillTrigger.API))
|
||||||
|
this.skill.getSkill().execute(skillMeta);
|
||||||
|
else
|
||||||
|
cast.abort();
|
||||||
|
|
||||||
|
return cast;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,8 @@ public class PlayerDamageSkillHandler extends PassiveMythicMobSkillHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
private void event(EntityDamageEvent e) {
|
private void event(EntityDamageEvent event) {
|
||||||
if (e.getEntityType() == EntityType.PLAYER && !e.getEntity().hasMetadata("NPC"))
|
if (event.getEntityType() == EntityType.PLAYER && !event.getEntity().hasMetadata("NPC"))
|
||||||
castSkill(PlayerData.get((Player) e.getEntity()));
|
castSkill(PlayerData.get((Player) event.getEntity()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ import net.Indyuce.mmocore.api.player.stats.StatType;
|
|||||||
import net.Indyuce.mmocore.api.util.math.format.DelayFormat;
|
import net.Indyuce.mmocore.api.util.math.format.DelayFormat;
|
||||||
import net.Indyuce.mmocore.gui.api.EditableInventory;
|
import net.Indyuce.mmocore.gui.api.EditableInventory;
|
||||||
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
|
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
|
||||||
import net.Indyuce.mmocore.gui.api.PluginInventory;
|
|
||||||
import net.Indyuce.mmocore.gui.api.item.InventoryItem;
|
import net.Indyuce.mmocore.gui.api.item.InventoryItem;
|
||||||
import net.Indyuce.mmocore.gui.api.item.Placeholders;
|
import net.Indyuce.mmocore.gui.api.item.Placeholders;
|
||||||
import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
|
import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
|
||||||
@ -43,7 +42,7 @@ public class PlayerStats extends EditableInventory {
|
|||||||
@Override
|
@Override
|
||||||
public boolean canDisplay(PlayerStatsInventory inv) {
|
public boolean canDisplay(PlayerStatsInventory inv) {
|
||||||
InventoryItem boost = inv.getByFunction("boost");
|
InventoryItem boost = inv.getByFunction("boost");
|
||||||
return boost != null && inv.boostOffset + boost.getSlots().size() < MMOCore.plugin.boosterManager.getBoosters().size();
|
return boost != null && inv.boostOffset + boost.getSlots().size() < MMOCore.plugin.boosterManager.getActive().size();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -304,7 +303,7 @@ public class PlayerStats extends EditableInventory {
|
|||||||
@Override
|
@Override
|
||||||
public ItemStack display(PlayerStatsInventory inv, int n) {
|
public ItemStack display(PlayerStatsInventory inv, int n) {
|
||||||
int offset = inv.boostOffset;
|
int offset = inv.boostOffset;
|
||||||
if (n + offset >= MMOCore.plugin.boosterManager.getBoosters().size())
|
if (n + offset >= MMOCore.plugin.boosterManager.getActive().size())
|
||||||
return noBoost.display(inv, n);
|
return noBoost.display(inv, n);
|
||||||
|
|
||||||
Booster boost = MMOCore.plugin.boosterManager.get(inv.boostOffset + n);
|
Booster boost = MMOCore.plugin.boosterManager.get(inv.boostOffset + n);
|
||||||
|
@ -5,8 +5,8 @@ import io.lumine.mythic.lib.api.item.ItemTag;
|
|||||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.skill.Skill;
|
import net.Indyuce.mmocore.skill.Skill;
|
||||||
import net.Indyuce.mmocore.api.skill.Skill.SkillInfo;
|
import net.Indyuce.mmocore.skill.Skill.SkillInfo;
|
||||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||||
import net.Indyuce.mmocore.gui.api.EditableInventory;
|
import net.Indyuce.mmocore.gui.api.EditableInventory;
|
||||||
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
|
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
package net.Indyuce.mmocore.gui.api;
|
package net.Indyuce.mmocore.gui.api;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import io.lumine.mythic.lib.MythicLib;
|
||||||
import java.util.List;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import net.Indyuce.mmocore.gui.api.item.InventoryItem;
|
||||||
|
import net.Indyuce.mmocore.gui.api.item.TriggerItem;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
import org.bukkit.inventory.Inventory;
|
import org.bukkit.inventory.Inventory;
|
||||||
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import java.util.ArrayList;
|
||||||
import net.Indyuce.mmocore.gui.api.item.InventoryItem;
|
import java.util.List;
|
||||||
import net.Indyuce.mmocore.gui.api.item.TriggerItem;
|
|
||||||
import io.lumine.mythic.lib.MythicLib;
|
|
||||||
|
|
||||||
public abstract class GeneratedInventory extends PluginInventory {
|
public abstract class GeneratedInventory extends PluginInventory {
|
||||||
private final EditableInventory editable;
|
private final EditableInventory editable;
|
||||||
@ -44,9 +43,10 @@ public abstract class GeneratedInventory extends PluginInventory {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* this method must use an ordered collection because of GUI items
|
* This method must use an ordered collection because
|
||||||
* overriding possibilities.
|
* of GUI items overriding possibilities. Hence the use
|
||||||
|
* of an array list instead of a set
|
||||||
*/
|
*/
|
||||||
public void addLoaded(InventoryItem item) {
|
public void addLoaded(InventoryItem item) {
|
||||||
loaded.add(0, item);
|
loaded.add(0, item);
|
||||||
@ -66,7 +66,7 @@ public abstract class GeneratedInventory extends PluginInventory {
|
|||||||
public void open() {
|
public void open() {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* very important, in order to prevent ghost items, the loaded items map
|
* Very important, in order to prevent ghost items, the loaded items map
|
||||||
* must be cleared when the inventory is updated or open at least twice
|
* must be cleared when the inventory is updated or open at least twice
|
||||||
*/
|
*/
|
||||||
loaded.clear();
|
loaded.clear();
|
||||||
|
@ -13,7 +13,7 @@ import org.bukkit.scheduler.BukkitRunnable;
|
|||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.skill.Skill.SkillInfo;
|
import net.Indyuce.mmocore.skill.Skill.SkillInfo;
|
||||||
import net.Indyuce.mmocore.manager.ConfigManager;
|
import net.Indyuce.mmocore.manager.ConfigManager;
|
||||||
import net.Indyuce.mmocore.manager.SoundManager;
|
import net.Indyuce.mmocore.manager.SoundManager;
|
||||||
|
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
package net.Indyuce.mmocore.listener.option;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.MythicLib;
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import net.Indyuce.mmocore.manager.InventoryManager;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||||
|
import org.bukkit.inventory.Inventory;
|
||||||
|
|
||||||
|
public class PlayerProfileCheck implements Listener {
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void a(PlayerInteractEntityEvent event) {
|
||||||
|
if (event.getRightClicked().getType() != EntityType.PLAYER || MythicLib.plugin.getEntities().findCustom(event.getRightClicked()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This works because the PlayerStats class DOES NOT utilize
|
||||||
|
* at all the player instance saved in the InventoryClickEvent
|
||||||
|
*
|
||||||
|
* Opening inventories like that to other players does NOT
|
||||||
|
* necessarily works for any other custom inventory.
|
||||||
|
* */
|
||||||
|
Inventory inv = InventoryManager.PLAYER_STATS.newInventory(PlayerData.get(event.getRightClicked().getUniqueId())).getInventory();
|
||||||
|
event.getPlayer().openInventory(inv);
|
||||||
|
}
|
||||||
|
}
|
@ -17,7 +17,7 @@ import org.bukkit.configuration.file.YamlConfiguration;
|
|||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.ConfigFile;
|
import net.Indyuce.mmocore.api.ConfigFile;
|
||||||
import net.Indyuce.mmocore.api.skill.Skill;
|
import net.Indyuce.mmocore.skill.Skill;
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
import net.Indyuce.mmocore.comp.mythicmobs.skill.MythicMobSkill;
|
import net.Indyuce.mmocore.comp.mythicmobs.skill.MythicMobSkill;
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ public class SkillManager {
|
|||||||
JarFile jarFile = new JarFile(MMOCore.plugin.getJarFile());
|
JarFile jarFile = new JarFile(MMOCore.plugin.getJarFile());
|
||||||
JarEntry entry;
|
JarEntry entry;
|
||||||
for (Enumeration<JarEntry> en = jarFile.entries(); en.hasMoreElements();)
|
for (Enumeration<JarEntry> en = jarFile.entries(); en.hasMoreElements();)
|
||||||
if ((entry = en.nextElement()).getName().startsWith("net/Indyuce/mmocore/skill/")
|
if ((entry = en.nextElement()).getName().startsWith("net/Indyuce/mmocore/skill/list/")
|
||||||
&& !entry.isDirectory() && !entry.getName().contains("$"))
|
&& !entry.isDirectory() && !entry.getName().contains("$"))
|
||||||
register((Skill) Class.forName(entry.getName().replace("/", ".").replace(".class", ""))
|
register((Skill) Class.forName(entry.getName().replace("/", ".").replace(".class", ""))
|
||||||
.newInstance());
|
.newInstance());
|
||||||
|
@ -41,7 +41,7 @@ public class BoosterManager {
|
|||||||
/**
|
/**
|
||||||
* Cleans timed out boosters from the MMOCore registry
|
* Cleans timed out boosters from the MMOCore registry
|
||||||
*/
|
*/
|
||||||
public void flush() {
|
private void flush() {
|
||||||
map.removeIf(Booster::isTimedOut);
|
map.removeIf(Booster::isTimedOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,14 +66,7 @@ public class BoosterManager {
|
|||||||
* @return Collection of currently registered boosters. Some of them can be
|
* @return Collection of currently registered boosters. Some of them can be
|
||||||
* expired but are not unregistered yet!
|
* expired but are not unregistered yet!
|
||||||
*/
|
*/
|
||||||
public List<Booster> getBoosters() {
|
public List<Booster> getActive() {
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Same as {@link #getBoosters()} but does not include timed out boosters
|
|
||||||
*/
|
|
||||||
public List<Booster> getActiveBoosters() {
|
|
||||||
return map.stream().filter((b) -> !b.isTimedOut()).collect(Collectors.toList());
|
return map.stream().filter((b) -> !b.isTimedOut()).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,88 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.skill;
|
|
||||||
|
|
||||||
import io.lumine.mythic.lib.api.DamageType;
|
|
||||||
import io.lumine.mythic.lib.api.event.PlayerAttackEvent;
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
|
||||||
import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.api.player.stats.StatType;
|
|
||||||
import net.Indyuce.mmocore.api.skill.Skill;
|
|
||||||
import net.Indyuce.mmocore.api.skill.SkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.particle.ParabolicProjectile;
|
|
||||||
import org.bukkit.*;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
|
|
||||||
public class Ambers extends Skill implements Listener {
|
|
||||||
public Ambers() {
|
|
||||||
super();
|
|
||||||
setMaterial(Material.EMERALD);
|
|
||||||
setLore("Dealing magic damage has &630% &7chance", "of dropping an amber on the ground.", "", "When picked up, ambers stack and",
|
|
||||||
"refund &9{percent}% &7of your missing mana.", "", "&oAmbers can be used in other damaging skills.",
|
|
||||||
"&oThe more you collect, the more powerful the skills.", "", "&e{cooldown}s Cooldown");
|
|
||||||
setPassive();
|
|
||||||
|
|
||||||
addModifier("cooldown", new LinearValue(3, -.1, 1, 3));
|
|
||||||
addModifier("percent", new LinearValue(10, .1, 10, 20));
|
|
||||||
|
|
||||||
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void a(PlayerAttackEvent event) {
|
|
||||||
PlayerData data = PlayerData.get(event.getData().getUniqueId());
|
|
||||||
if (!event.getAttack().hasType(DamageType.SKILL) || !data.getProfess().hasSkill(this))
|
|
||||||
return;
|
|
||||||
|
|
||||||
SkillResult cast = data.cast(this);
|
|
||||||
if (!cast.isSuccessful())
|
|
||||||
return;
|
|
||||||
|
|
||||||
Location loc = event.getEntity().getLocation();
|
|
||||||
double a = random.nextDouble() * 2 * Math.PI;
|
|
||||||
|
|
||||||
new Amber(data, loc.add(0, event.getEntity().getHeight() / 2, 0), loc.clone().add(4 * Math.cos(a), 0, 4 * Math.sin(a)), cast.getModifier("percent"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Amber extends BukkitRunnable {
|
|
||||||
private final Location loc;
|
|
||||||
private final PlayerData data;
|
|
||||||
private final double percent;
|
|
||||||
|
|
||||||
private int j;
|
|
||||||
|
|
||||||
private Amber(PlayerData data, Location source, Location loc, double percent) {
|
|
||||||
this.loc = loc;
|
|
||||||
this.data = data;
|
|
||||||
this.percent = percent / 100;
|
|
||||||
|
|
||||||
final Amber amber = this;
|
|
||||||
new ParabolicProjectile(source, loc, Particle.REDSTONE, () -> amber.runTaskTimer(MMOCore.plugin, 0, 3), 1, Color.ORANGE, 1.3f);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if(!data.isOnline()) return;
|
|
||||||
if (j++ > 66 || !data.getPlayer().getWorld().equals(loc.getWorld())) {
|
|
||||||
cancel();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.getPlayer().getLocation().distanceSquared(loc) < 2) {
|
|
||||||
|
|
||||||
data.getPlayer().playSound(data.getPlayer().getLocation(), Sound.BLOCK_END_PORTAL_FRAME_FILL, 1, 1);
|
|
||||||
// data.getSkillData().ambers++;
|
|
||||||
data.giveMana((data.getStats().getStat(StatType.MAX_MANA) - data.getMana()) * percent, PlayerResourceUpdateEvent.UpdateReason.SKILL_REGENERATION);
|
|
||||||
|
|
||||||
cancel();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int j = 0; j < 5; j++)
|
|
||||||
loc.getWorld().spawnParticle(Particle.SPELL_MOB, loc, 0, 1, 0.647, 0, 1);
|
|
||||||
loc.getWorld().spawnParticle(Particle.REDSTONE, loc, 1, new Particle.DustOptions(Color.ORANGE, 1.3f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.skill;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.Particle;
|
|
||||||
import org.bukkit.Sound;
|
|
||||||
import org.bukkit.entity.LivingEntity;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.api.skill.Skill;
|
|
||||||
import net.Indyuce.mmocore.api.skill.SkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
|
||||||
import io.lumine.mythic.lib.api.DamageType;
|
|
||||||
import io.lumine.mythic.lib.api.event.PlayerAttackEvent;
|
|
||||||
|
|
||||||
public class Backstab extends Skill implements Listener {
|
|
||||||
public Backstab() {
|
|
||||||
super();
|
|
||||||
setMaterial(Material.FLINT);
|
|
||||||
setLore("Backstabs deal &c{extra}%&7 damage.", "", "&9Costs {mana} {mana_name}");
|
|
||||||
setPassive();
|
|
||||||
|
|
||||||
addModifier("cooldown", new LinearValue(0, 0));
|
|
||||||
addModifier("mana", new LinearValue(8, 1));
|
|
||||||
addModifier("extra", new LinearValue(50, 20));
|
|
||||||
|
|
||||||
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void a(PlayerAttackEvent event) {
|
|
||||||
PlayerData data = PlayerData.get(event.getData().getUniqueId());
|
|
||||||
LivingEntity target = event.getEntity();
|
|
||||||
if (data.isInCombat() || !event.getAttack().hasType(DamageType.WEAPON)
|
|
||||||
|| event.getPlayer().getEyeLocation().getDirection().angle(target.getEyeLocation().getDirection()) > Math.PI / 6
|
|
||||||
|| !data.getProfess().hasSkill(this))
|
|
||||||
return;
|
|
||||||
|
|
||||||
SkillResult cast = data.cast(this);
|
|
||||||
if (!cast.isSuccessful())
|
|
||||||
return;
|
|
||||||
|
|
||||||
data.cast(cast.getInfo());
|
|
||||||
event.getAttack().multiplyDamage(1 + cast.getModifier("extra") / 100);
|
|
||||||
target.getWorld().spawnParticle(Particle.CRIT, target.getLocation().add(0, target.getHeight() / 2, 0), 32, 0, 0, 0, .05);
|
|
||||||
target.getWorld().playSound(target.getLocation(), Sound.ENTITY_ENDERMAN_HURT, 1, 1.5f);
|
|
||||||
}
|
|
||||||
}
|
|
57
src/main/java/net/Indyuce/mmocore/skill/CasterMetadata.java
Normal file
57
src/main/java/net/Indyuce/mmocore/skill/CasterMetadata.java
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package net.Indyuce.mmocore.skill;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.MythicLib;
|
||||||
|
import io.lumine.mythic.lib.api.player.EquipmentSlot;
|
||||||
|
import io.lumine.mythic.lib.api.stat.StatMap;
|
||||||
|
import io.lumine.mythic.lib.damage.AttackMetadata;
|
||||||
|
import io.lumine.mythic.lib.damage.DamageMetadata;
|
||||||
|
import io.lumine.mythic.lib.damage.DamageType;
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
public class CasterMetadata {
|
||||||
|
private final Player player;
|
||||||
|
private final PlayerData caster;
|
||||||
|
private final StatMap.CachedStatMap stats;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiated every time a player casts a skill. This is
|
||||||
|
* used to temporarily cache the player's statistics
|
||||||
|
*
|
||||||
|
* @param caster Player casting the skill
|
||||||
|
*/
|
||||||
|
public CasterMetadata(PlayerData caster) {
|
||||||
|
this.player = caster.getPlayer();
|
||||||
|
this.caster = caster;
|
||||||
|
this.stats = caster.getMMOPlayerData().getStatMap().cache(EquipmentSlot.MAIN_HAND);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Player getPlayer() {
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlayerData getPlayerData() {
|
||||||
|
return caster;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatMap.CachedStatMap getStats() {
|
||||||
|
return stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility method that makes a player deal damage to a specific
|
||||||
|
* entity. This creates the attackMetadata based on the data
|
||||||
|
* stored by the CasterMetadata, and calls it using MythicLib
|
||||||
|
* damage manager
|
||||||
|
*
|
||||||
|
* @param target Target entity
|
||||||
|
* @param damage Damage dealt
|
||||||
|
* @param types Type of target
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public void attack(LivingEntity target, double damage, DamageType... types) {
|
||||||
|
AttackMetadata attackMeta = new AttackMetadata(new DamageMetadata(damage, types), stats);
|
||||||
|
MythicLib.plugin.getDamage().damage(attackMeta, target);
|
||||||
|
}
|
||||||
|
}
|
@ -1,59 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.skill;
|
|
||||||
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.Particle;
|
|
||||||
import org.bukkit.Sound;
|
|
||||||
import org.bukkit.entity.LivingEntity;
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.api.skill.Skill;
|
|
||||||
import net.Indyuce.mmocore.api.skill.SkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.skill.result.TargetSkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
|
||||||
import io.lumine.mythic.lib.MythicLib;
|
|
||||||
import io.lumine.mythic.lib.api.AttackResult;
|
|
||||||
import io.lumine.mythic.lib.api.DamageType;
|
|
||||||
|
|
||||||
public class Combo_Attack extends Skill {
|
|
||||||
public Combo_Attack() {
|
|
||||||
super();
|
|
||||||
setMaterial(Material.IRON_SWORD);
|
|
||||||
setLore("Violenty slashes your target &8{count}", "times for a total of &8{damage} &7damage.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}");
|
|
||||||
|
|
||||||
addModifier("cooldown", new LinearValue(20, -.1, 5, 20));
|
|
||||||
addModifier("damage", new LinearValue(9, .3));
|
|
||||||
addModifier("count", new LinearValue(3, .2));
|
|
||||||
addModifier("mana", new LinearValue(10, -.1, 3, 5));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SkillResult whenCast(PlayerData data, SkillInfo skill) {
|
|
||||||
TargetSkillResult cast = new TargetSkillResult(data, skill, 3);
|
|
||||||
if (!cast.isSuccessful())
|
|
||||||
return cast;
|
|
||||||
|
|
||||||
new BukkitRunnable() {
|
|
||||||
final int count = (int) cast.getModifier("count");
|
|
||||||
final double damage = cast.getModifier("damage") / count;
|
|
||||||
final LivingEntity target = cast.getTarget();
|
|
||||||
|
|
||||||
int c;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if(!data.isOnline()) return;
|
|
||||||
if (c++ > count) {
|
|
||||||
cancel();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
target.getWorld().playSound(target.getLocation(), Sound.ENTITY_PLAYER_ATTACK_KNOCKBACK, 1, 2);
|
|
||||||
target.getWorld().spawnParticle(Particle.CRIT, target.getLocation().add(0, target.getHeight() / 2, 0), 24, 0, 0, 0, .7);
|
|
||||||
MythicLib.plugin.getDamage().damage(data.getPlayer(), target, new AttackResult(damage, DamageType.SKILL, DamageType.PHYSICAL));
|
|
||||||
}
|
|
||||||
}.runTaskTimer(MMOCore.plugin, 0, 5);
|
|
||||||
return cast;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,106 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.skill;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Particle;
|
|
||||||
import org.bukkit.Sound;
|
|
||||||
import org.bukkit.entity.LivingEntity;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.HandlerList;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
|
||||||
import org.bukkit.potion.PotionEffect;
|
|
||||||
import org.bukkit.potion.PotionEffectType;
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.api.skill.Skill;
|
|
||||||
import net.Indyuce.mmocore.api.skill.SkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.skill.result.TargetSkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
|
||||||
import io.lumine.mythic.lib.version.VersionMaterial;
|
|
||||||
import io.lumine.mythic.lib.version.VersionSound;
|
|
||||||
|
|
||||||
public class Control extends Skill {
|
|
||||||
public Control() {
|
|
||||||
super();
|
|
||||||
setMaterial(VersionMaterial.MAGENTA_DYE.toMaterial());
|
|
||||||
setLore("Your target is temporarily slowed for &8{duration} &7seconds.", "As soon as you left click, it gets", "pushed back where you are looking at.", "Knockback force: &f{knockback}%", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}");
|
|
||||||
|
|
||||||
addModifier("cooldown", new LinearValue(18, -.3, 10, 20));
|
|
||||||
addModifier("mana", new LinearValue(15, 1.5));
|
|
||||||
addModifier("knockback", new LinearValue(30, 3));
|
|
||||||
addModifier("duration", new LinearValue(2, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SkillResult whenCast(PlayerData data, SkillInfo skill) {
|
|
||||||
TargetSkillResult cast = new TargetSkillResult(data, skill, 7);
|
|
||||||
if (!cast.isSuccessful())
|
|
||||||
return cast;
|
|
||||||
|
|
||||||
if(data.isOnline())
|
|
||||||
data.getPlayer().getWorld().playSound(data.getPlayer().getLocation(), Sound.BLOCK_END_PORTAL_FRAME_FILL, 1, 1);
|
|
||||||
cast.getTarget().addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 20 * 2, 0));
|
|
||||||
new TelekinesyRunnable(data, cast.getTarget(), cast.getModifier("knockback") / 100, cast.getModifier("duration"));
|
|
||||||
return cast;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class TelekinesyRunnable extends BukkitRunnable implements Listener {
|
|
||||||
private final LivingEntity entity;
|
|
||||||
private final PlayerData data;
|
|
||||||
|
|
||||||
private final double f, d;
|
|
||||||
|
|
||||||
private int j;
|
|
||||||
|
|
||||||
public TelekinesyRunnable(PlayerData data, LivingEntity entity, double force, double duration) {
|
|
||||||
this.entity = entity;
|
|
||||||
this.data = data;
|
|
||||||
|
|
||||||
d = duration * 20;
|
|
||||||
f = force;
|
|
||||||
|
|
||||||
runTaskTimer(MMOCore.plugin, 0, 1);
|
|
||||||
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void a(PlayerInteractEvent event) {
|
|
||||||
if(!data.isOnline()) return;
|
|
||||||
if (event.getPlayer().equals(data.getPlayer()) && event.getAction().name().contains("LEFT_CLICK")) {
|
|
||||||
Vector vec = data.getPlayer().getEyeLocation().getDirection().multiply(3 * f);
|
|
||||||
vec.setY(Math.max(.5, vec.getY() / 2));
|
|
||||||
entity.setVelocity(vec);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* try not to interfere with other potion effects
|
|
||||||
*/
|
|
||||||
PotionEffect effect = entity.getPotionEffect(PotionEffectType.SLOW);
|
|
||||||
if (effect.getDuration() < d && effect.getAmplifier() == 0)
|
|
||||||
entity.removePotionEffect(PotionEffectType.SLOW);
|
|
||||||
|
|
||||||
entity.getWorld().spawnParticle(Particle.SPELL_WITCH, entity.getLocation().add(0, entity.getHeight() / 2, 0), 16);
|
|
||||||
entity.getWorld().playSound(entity.getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 2, 1);
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (!data.isOnline() || entity.isDead() || j++ >= d) {
|
|
||||||
close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
double a = (double) j / 3;
|
|
||||||
entity.getWorld().spawnParticle(Particle.SPELL_WITCH, entity.getLocation().add(Math.cos(a), entity.getHeight() / 2, Math.sin(a)), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void close() {
|
|
||||||
cancel();
|
|
||||||
HandlerList.unregisterAll(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,50 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.skill;
|
|
||||||
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.Particle;
|
|
||||||
import org.bukkit.Sound;
|
|
||||||
import org.bukkit.attribute.Attribute;
|
|
||||||
import org.bukkit.entity.LivingEntity;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.api.skill.Skill;
|
|
||||||
import net.Indyuce.mmocore.api.skill.SkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.skill.result.TargetSkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
|
||||||
import io.lumine.mythic.lib.MythicLib;
|
|
||||||
import io.lumine.mythic.lib.api.AttackResult;
|
|
||||||
import io.lumine.mythic.lib.api.DamageType;
|
|
||||||
|
|
||||||
public class Deep_Wound extends Skill {
|
|
||||||
public Deep_Wound() {
|
|
||||||
super();
|
|
||||||
setMaterial(Material.REDSTONE);
|
|
||||||
setLore("You puncture your target, dealing &c{damage} &7damage.", "Damage is increased up to &c+{extra}% &7based",
|
|
||||||
"on your target's missing health.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}");
|
|
||||||
|
|
||||||
addModifier("cooldown", new LinearValue(20, -.1, 5, 20));
|
|
||||||
addModifier("mana", new LinearValue(8, 3));
|
|
||||||
addModifier("damage", new LinearValue(5, 1.5));
|
|
||||||
addModifier("extra", new LinearValue(50, 20));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SkillResult whenCast(PlayerData data, SkillInfo skill) {
|
|
||||||
TargetSkillResult cast = new TargetSkillResult(data, skill, 3);
|
|
||||||
if (!cast.isSuccessful() || !data.isOnline())
|
|
||||||
return cast;
|
|
||||||
|
|
||||||
LivingEntity target = cast.getTarget();
|
|
||||||
target.getWorld().playSound(target.getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 2, 2);
|
|
||||||
target.getWorld().spawnParticle(Particle.CRIT, target.getLocation().add(0, target.getHeight() / 2, 0), 32, 0, 0, 0, .7);
|
|
||||||
target.getWorld().spawnParticle(Particle.BLOCK_CRACK, target.getLocation().add(0, target.getHeight() / 2, 0), 32, 0, 0, 0, 2,
|
|
||||||
Material.REDSTONE_BLOCK.createBlockData());
|
|
||||||
|
|
||||||
double max = target.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
|
|
||||||
double ratio = (max - target.getHealth()) / max;
|
|
||||||
|
|
||||||
double damage = cast.getModifier("damage") * (1 + cast.getModifier("extra") * ratio / 100);
|
|
||||||
MythicLib.plugin.getDamage().damage(data.getPlayer(), target, new AttackResult(damage, DamageType.SKILL, DamageType.PHYSICAL));
|
|
||||||
return cast;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,122 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.skill;
|
|
||||||
|
|
||||||
import io.lumine.mythic.lib.MythicLib;
|
|
||||||
import io.lumine.mythic.lib.api.AttackResult;
|
|
||||||
import io.lumine.mythic.lib.api.DamageType;
|
|
||||||
import io.lumine.mythic.lib.api.event.PlayerAttackEvent;
|
|
||||||
import io.lumine.mythic.lib.version.VersionMaterial;
|
|
||||||
import io.lumine.mythic.lib.version.VersionSound;
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.api.skill.Skill;
|
|
||||||
import net.Indyuce.mmocore.api.skill.SkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.Particle;
|
|
||||||
import org.bukkit.Sound;
|
|
||||||
import org.bukkit.entity.Entity;
|
|
||||||
import org.bukkit.entity.LivingEntity;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
|
|
||||||
public class Empowered_Attack extends Skill {
|
|
||||||
private static final double perb = 5;
|
|
||||||
|
|
||||||
public Empowered_Attack() {
|
|
||||||
super();
|
|
||||||
setMaterial(VersionMaterial.BONE_MEAL.toMaterial());
|
|
||||||
setLore("You charge your weapon with lightning.", "Your next attack deals &f{extra}% &7extra damage", "and spreads to enemies within &f{radius} &7blocks", "for &f{ratio}% &7of the initial damage.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}");
|
|
||||||
|
|
||||||
addModifier("cooldown", new LinearValue(10, -.2, 5, 10));
|
|
||||||
addModifier("mana", new LinearValue(4, 1));
|
|
||||||
addModifier("radius", new LinearValue(4, 0));
|
|
||||||
addModifier("ratio", new LinearValue(30, 10, 30, 100));
|
|
||||||
addModifier("extra", new LinearValue(30, 8));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SkillResult whenCast(PlayerData data, SkillInfo skill) {
|
|
||||||
SkillResult cast = new SkillResult(data, skill);
|
|
||||||
if (!cast.isSuccessful())
|
|
||||||
return cast;
|
|
||||||
|
|
||||||
if(data.isOnline())
|
|
||||||
data.getPlayer().playSound(data.getPlayer().getLocation(), Sound.BLOCK_END_PORTAL_FRAME_FILL, 1, 1);
|
|
||||||
new EmpoweredAttack(data, cast.getModifier("extra"), cast.getModifier("ratio"), cast.getModifier("radius"));
|
|
||||||
return cast;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void drawVector(Location loc, Vector vec) {
|
|
||||||
|
|
||||||
double steps = vec.length() * perb;
|
|
||||||
Vector v = vec.clone().normalize().multiply((double) 1 / perb);
|
|
||||||
|
|
||||||
for (int j = 0; j < Math.min(steps, 124); j++)
|
|
||||||
loc.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, loc.add(v), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class EmpoweredAttack implements Listener {
|
|
||||||
private final PlayerData player;
|
|
||||||
private final double c, r, rad;
|
|
||||||
|
|
||||||
public EmpoweredAttack(PlayerData player, double extra, double ratio, double radius) {
|
|
||||||
this.player = player;
|
|
||||||
this.c = 1 + extra / 100;
|
|
||||||
this.r = ratio / 100;
|
|
||||||
this.rad = radius;
|
|
||||||
|
|
||||||
if(player.isOnline())
|
|
||||||
new SmallParticleEffect(player.getPlayer(), Particle.FIREWORKS_SPARK);
|
|
||||||
|
|
||||||
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
|
||||||
Bukkit.getScheduler().scheduleSyncDelayedTask(MMOCore.plugin, this::close, 80);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void close() {
|
|
||||||
PlayerAttackEvent.getHandlerList().unregister(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void a(PlayerAttackEvent event) {
|
|
||||||
if(!player.isOnline()) return;
|
|
||||||
if (event.getPlayer().equals(player.getPlayer()) && event.getAttack().hasType(DamageType.WEAPON)) {
|
|
||||||
close();
|
|
||||||
|
|
||||||
Entity target = event.getEntity();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* play lightning effect
|
|
||||||
*/
|
|
||||||
final Location loc = target.getLocation().add(0, target.getHeight() / 2, 0);
|
|
||||||
for (int j = 0; j < 3; j++) {
|
|
||||||
Location clone = loc.clone();
|
|
||||||
double a = random.nextDouble() * Math.PI * 2;
|
|
||||||
loc.add(Math.cos(a), 5, Math.sin(a));
|
|
||||||
drawVector(clone, loc.clone().subtract(clone).toVector());
|
|
||||||
}
|
|
||||||
|
|
||||||
target.getWorld().playSound(target.getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 2, .5f);
|
|
||||||
target.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, target.getLocation().add(0, target.getHeight() / 2, 0), 32, 0, 0, 0, .2);
|
|
||||||
|
|
||||||
double sweep = event.getAttack().getDamage() * r;
|
|
||||||
Location src = target.getLocation().add(0, target.getHeight() / 2, 0);
|
|
||||||
|
|
||||||
for (Entity entity : target.getNearbyEntities(rad, rad, rad))
|
|
||||||
if (MMOCoreUtils.canTarget(player, entity)) {
|
|
||||||
drawVector(src, entity.getLocation().add(0, entity.getHeight() / 2, 0).subtract(src).toVector());
|
|
||||||
MythicLib.plugin.getDamage().damage(player.getPlayer(), (LivingEntity) entity, new AttackResult(sweep, DamageType.SKILL, DamageType.PHYSICAL));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* apply damage afterwards otherwise the damage dealt to nearby
|
|
||||||
* entities scale with the extra ability damage.
|
|
||||||
*/
|
|
||||||
event.getAttack().multiplyDamage(1 + c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,84 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.skill;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.Particle;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.entity.EntityDamageEvent;
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.api.skill.Skill;
|
|
||||||
import net.Indyuce.mmocore.api.skill.SkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect;
|
|
||||||
import io.lumine.mythic.lib.api.DamageType;
|
|
||||||
import io.lumine.mythic.lib.api.event.PlayerAttackEvent;
|
|
||||||
import io.lumine.mythic.lib.version.VersionSound;
|
|
||||||
|
|
||||||
public class Evade extends Skill {
|
|
||||||
public Evade() {
|
|
||||||
super();
|
|
||||||
setMaterial(Material.LEATHER_BOOTS);
|
|
||||||
setLore("You become imune to damage for &8{duration} &7seconds.", "Cancels when dealing weapon damage.", "", "&e{cooldown}s Cooldown",
|
|
||||||
"&9Costs {mana} {mana_name}");
|
|
||||||
|
|
||||||
addModifier("cooldown", new LinearValue(20, 0));
|
|
||||||
addModifier("mana", new LinearValue(8, 3));
|
|
||||||
addModifier("duration", new LinearValue(2, .3, 2, 10));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SkillResult whenCast(PlayerData data, SkillInfo skill) {
|
|
||||||
SkillResult cast = new SkillResult(data, skill);
|
|
||||||
if (!cast.isSuccessful())
|
|
||||||
return cast;
|
|
||||||
if(data.isOnline()) {
|
|
||||||
data.getPlayer().getWorld().playSound(data.getPlayer().getLocation(), VersionSound.ENTITY_ENDERMAN_TELEPORT.toSound(), 1, 2);
|
|
||||||
new SmallParticleEffect(data.getPlayer(), Particle.CLOUD);
|
|
||||||
}
|
|
||||||
new EvadeSkill(data, cast.getModifier("duration"));
|
|
||||||
return cast;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class EvadeSkill extends BukkitRunnable implements Listener {
|
|
||||||
private final PlayerData data;
|
|
||||||
|
|
||||||
public EvadeSkill(PlayerData data, double duration) {
|
|
||||||
this.data = data;
|
|
||||||
|
|
||||||
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
|
||||||
runTaskTimer(MMOCore.plugin, 0, 1);
|
|
||||||
Bukkit.getScheduler().runTaskLater(MMOCore.plugin, this::close, (long) (duration * 20));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void close() {
|
|
||||||
cancel();
|
|
||||||
EntityDamageEvent.getHandlerList().unregister(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOW)
|
|
||||||
public void a(EntityDamageEvent event) {
|
|
||||||
if(!data.isOnline()) return;
|
|
||||||
if (event.getEntity().equals(data.getPlayer()))
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST)
|
|
||||||
public void b(PlayerAttackEvent event) {
|
|
||||||
if (event.getAttack().hasType(DamageType.WEAPON) && !event.isCancelled() && PlayerData.get(event.getData().getUniqueId()).equals(data))
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (!data.isOnline() || data.getPlayer().isDead())
|
|
||||||
close();
|
|
||||||
else
|
|
||||||
data.getPlayer().getWorld().spawnParticle(Particle.CLOUD, data.getPlayer().getLocation().add(0, 1, 0), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.skill;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.api.skill.Skill;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
|
||||||
import io.lumine.mythic.lib.api.event.PlayerAttackEvent;
|
|
||||||
|
|
||||||
public class Fire_Berserker extends Skill implements Listener {
|
|
||||||
public Fire_Berserker() {
|
|
||||||
super();
|
|
||||||
setMaterial(Material.FLINT_AND_STEEL);
|
|
||||||
setLore("You deal &c{extra}% &7more damage when on fire.");
|
|
||||||
setPassive();
|
|
||||||
|
|
||||||
addModifier("extra", new LinearValue(10, 5));
|
|
||||||
// addModifier("duration", new LinearValue(10, .1));
|
|
||||||
// addModifier("cooldown", new LinearValue(30, 0));
|
|
||||||
|
|
||||||
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
|
||||||
public void a(PlayerAttackEvent event) {
|
|
||||||
PlayerData data = PlayerData.get(event.getData().getUniqueId());
|
|
||||||
if (event.getPlayer().getFireTicks() > 0) {
|
|
||||||
Optional<SkillInfo> skill = data.getProfess().findSkill(this);
|
|
||||||
skill.ifPresent(skillInfo -> event.getAttack().multiplyDamage(1 + skillInfo.getModifier("extra", data.getSkillLevel(this)) / 100));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,165 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.skill;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.Particle;
|
|
||||||
import org.bukkit.Sound;
|
|
||||||
import org.bukkit.entity.Entity;
|
|
||||||
import org.bukkit.entity.LivingEntity;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.HandlerList;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
|
||||||
import org.bukkit.potion.PotionEffect;
|
|
||||||
import org.bukkit.potion.PotionEffectType;
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.api.skill.Skill;
|
|
||||||
import net.Indyuce.mmocore.api.skill.SkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.VectorRotation;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
|
||||||
import io.lumine.mythic.lib.MythicLib;
|
|
||||||
import io.lumine.mythic.lib.api.AttackResult;
|
|
||||||
import io.lumine.mythic.lib.api.DamageType;
|
|
||||||
import io.lumine.mythic.lib.version.VersionMaterial;
|
|
||||||
import io.lumine.mythic.lib.version.VersionSound;
|
|
||||||
|
|
||||||
public class Fire_Rage extends Skill {
|
|
||||||
public Fire_Rage() {
|
|
||||||
super();
|
|
||||||
setMaterial(VersionMaterial.FIRE_CHARGE.toMaterial());
|
|
||||||
setLore("For {duration} seconds, you slow down and are able", "to cast up to {count} fireballs by left clicking.", "", "Fireballs deal &c{damage} &7damage upon contact", "and ignite your target for &c{ignite} &7seconds.", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}");
|
|
||||||
|
|
||||||
addModifier("duration", new LinearValue(8, 0));
|
|
||||||
addModifier("count", new LinearValue(4, 0));
|
|
||||||
addModifier("mana", new LinearValue(15, 1));
|
|
||||||
addModifier("damage", new LinearValue(5, 3));
|
|
||||||
addModifier("ignite", new LinearValue(2, .1));
|
|
||||||
addModifier("cooldown", new LinearValue(9, -.1, 1, 5));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SkillResult whenCast(PlayerData data, SkillInfo skill) {
|
|
||||||
SkillResult cast = new SkillResult(data, skill);
|
|
||||||
if (!cast.isSuccessful())
|
|
||||||
return cast;
|
|
||||||
|
|
||||||
new Rage(data, cast);
|
|
||||||
return cast;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Rage extends BukkitRunnable implements Listener {
|
|
||||||
private final PlayerData data;
|
|
||||||
private final int count, ignite;
|
|
||||||
private final double damage;
|
|
||||||
|
|
||||||
private int c;
|
|
||||||
private double b;
|
|
||||||
private long last = System.currentTimeMillis();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* time the player needs to wait before firing two fireballs.
|
|
||||||
*/
|
|
||||||
private static final long timeOut = 700;
|
|
||||||
|
|
||||||
public Rage(PlayerData data, SkillResult cast) {
|
|
||||||
this.data = data;
|
|
||||||
this.ignite = (int) (20 * cast.getModifier("ignite"));
|
|
||||||
this.damage = cast.getModifier("damage");
|
|
||||||
c = count = (int) cast.getModifier("count");
|
|
||||||
|
|
||||||
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
|
||||||
Bukkit.getScheduler().runTaskLater(MMOCore.plugin, this::close, (long) (cast.getModifier("duration") * 20));
|
|
||||||
runTaskTimer(MMOCore.plugin, 0, 1);
|
|
||||||
|
|
||||||
if(data.isOnline()) {
|
|
||||||
data.getPlayer().removePotionEffect(PotionEffectType.SLOW);
|
|
||||||
data.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.SLOW, (int) (cast.getModifier("duration") * 20), 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void a(PlayerInteractEvent event) {
|
|
||||||
if(!data.isOnline()) return;
|
|
||||||
if (event.getPlayer().equals(data.getPlayer()) && event.getAction().name().contains("LEFT_CLICK") && (System.currentTimeMillis() - last) > timeOut) {
|
|
||||||
last = System.currentTimeMillis();
|
|
||||||
castEffect();
|
|
||||||
fireball(c < 2);
|
|
||||||
if (c-- < 2)
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void castEffect() {
|
|
||||||
if(!data.isOnline()) return;
|
|
||||||
VectorRotation rotation = new VectorRotation(data.getPlayer().getEyeLocation());
|
|
||||||
for (double a = 0; a < Math.PI * 2; a += Math.PI / 13) {
|
|
||||||
Vector vec = rotation.rotate(new Vector(Math.cos(a), Math.sin(a), 0)).add(data.getPlayer().getEyeLocation().getDirection().multiply(.5)).multiply(.3);
|
|
||||||
data.getPlayer().getWorld().spawnParticle(Particle.FLAME, data.getPlayer().getLocation().add(0, 1.3, 0).add(data.getPlayer().getEyeLocation().getDirection().multiply(.5)), 0, vec.getX(), vec.getY(), vec.getZ(), .3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void close() {
|
|
||||||
if (isCancelled())
|
|
||||||
return;
|
|
||||||
|
|
||||||
cancel();
|
|
||||||
HandlerList.unregisterAll(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void fireball(boolean last) {
|
|
||||||
if(!data.isOnline()) return;
|
|
||||||
if (last) {
|
|
||||||
data.getPlayer().removePotionEffect(PotionEffectType.SLOW);
|
|
||||||
data.getPlayer().removePotionEffect(PotionEffectType.SLOW);
|
|
||||||
}
|
|
||||||
|
|
||||||
data.getPlayer().getWorld().playSound(data.getPlayer().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 1, last ? 0 : 1);
|
|
||||||
new BukkitRunnable() {
|
|
||||||
int j = 0;
|
|
||||||
final Vector vec = data.getPlayer().getEyeLocation().getDirection();
|
|
||||||
final Location loc = data.getPlayer().getLocation().add(0, 1.3, 0);
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
if (j++ > 40)
|
|
||||||
cancel();
|
|
||||||
|
|
||||||
loc.add(vec);
|
|
||||||
|
|
||||||
if (j % 2 == 0)
|
|
||||||
loc.getWorld().playSound(loc, Sound.BLOCK_FIRE_AMBIENT, 2, 1);
|
|
||||||
loc.getWorld().spawnParticle(Particle.FLAME, loc, 4, .1, .1, .1, 0);
|
|
||||||
loc.getWorld().spawnParticle(Particle.LAVA, loc, 0);
|
|
||||||
|
|
||||||
for (Entity target : MMOCoreUtils.getNearbyChunkEntities(loc))
|
|
||||||
if (MythicLib.plugin.getVersion().getWrapper().isInBoundingBox(target, loc) && MMOCoreUtils.canTarget(data, target)) {
|
|
||||||
loc.getWorld().spawnParticle(Particle.LAVA, loc, 8);
|
|
||||||
loc.getWorld().spawnParticle(Particle.FLAME, loc, 32, 0, 0, 0, .1);
|
|
||||||
loc.getWorld().playSound(loc, Sound.ENTITY_BLAZE_HURT, 2, 1);
|
|
||||||
target.setFireTicks(target.getFireTicks() + ignite);
|
|
||||||
MythicLib.plugin.getDamage().damage(data.getPlayer(), (LivingEntity) target, new AttackResult(damage, DamageType.SKILL, DamageType.PROJECTILE, DamageType.MAGIC));
|
|
||||||
cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.runTaskTimer(MMOCore.plugin, 0, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (data.getPlayer().isDead() || !data.getPlayer().isOnline()) {
|
|
||||||
close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
b += Math.PI / 30;
|
|
||||||
for (int j = 0; j < c; j++) {
|
|
||||||
double a = Math.PI * 2 * j / count + b;
|
|
||||||
data.getPlayer().spawnParticle(Particle.FLAME, data.getPlayer().getLocation().add(Math.cos(a) * 1.5, 1 + Math.sin(a * 1.5) * .7, Math.sin(a) * 1.5), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,105 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.skill;
|
|
||||||
|
|
||||||
import io.lumine.mythic.lib.MythicLib;
|
|
||||||
import io.lumine.mythic.lib.api.AttackResult;
|
|
||||||
import io.lumine.mythic.lib.api.DamageType;
|
|
||||||
import io.lumine.mythic.lib.api.MMORayTraceResult;
|
|
||||||
import io.lumine.mythic.lib.version.VersionMaterial;
|
|
||||||
import io.lumine.mythic.lib.version.VersionSound;
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.api.skill.Skill;
|
|
||||||
import net.Indyuce.mmocore.api.skill.SkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.Particle;
|
|
||||||
import org.bukkit.Sound;
|
|
||||||
import org.bukkit.entity.Entity;
|
|
||||||
import org.bukkit.entity.LivingEntity;
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
|
|
||||||
public class Fireball extends Skill {
|
|
||||||
public Fireball() {
|
|
||||||
super();
|
|
||||||
setMaterial(VersionMaterial.FIRE_CHARGE.toMaterial());
|
|
||||||
setLore("Casts a deadly fireball onto your", "target, dealing &c{damage} &7damage upon contact", "and igniting it for &c{ignite} &7seconds.", "", "Shatters into 3 blazing hot shards which stick", "to walls and explode 3 seconds later, dealing", "&c{ratio}% &7of the initial spell damage.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}");
|
|
||||||
|
|
||||||
addModifier("mana", new LinearValue(15, 1));
|
|
||||||
addModifier("damage", new LinearValue(5, 3));
|
|
||||||
addModifier("ignite", new LinearValue(2, .1));
|
|
||||||
addModifier("ratio", new LinearValue(50, 3));
|
|
||||||
addModifier("cooldown", new LinearValue(9, -.1, 1, 5));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SkillResult whenCast(PlayerData data, SkillInfo skill) {
|
|
||||||
SkillResult cast = new SkillResult(data, skill);
|
|
||||||
if (!cast.isSuccessful() || !data.isOnline())
|
|
||||||
return cast;
|
|
||||||
|
|
||||||
data.getPlayer().getWorld().playSound(data.getPlayer().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 1, 1);
|
|
||||||
new BukkitRunnable() {
|
|
||||||
int j = 0;
|
|
||||||
final Vector vec = data.getPlayer().getEyeLocation().getDirection();
|
|
||||||
final Location loc = data.getPlayer().getLocation().add(0, 1.3, 0);
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
if (j++ > 40) {
|
|
||||||
cancel();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
loc.add(vec);
|
|
||||||
|
|
||||||
if (j % 3 == 0)
|
|
||||||
loc.getWorld().playSound(loc, Sound.BLOCK_FIRE_AMBIENT, 2, 1);
|
|
||||||
loc.getWorld().spawnParticle(Particle.FLAME, loc, 4, .02, .02, .02, 0);
|
|
||||||
loc.getWorld().spawnParticle(Particle.LAVA, loc, 0);
|
|
||||||
|
|
||||||
for (Entity target : MMOCoreUtils.getNearbyChunkEntities(loc))
|
|
||||||
if (MythicLib.plugin.getVersion().getWrapper().isInBoundingBox(target, loc) && MMOCoreUtils.canTarget(data, target)) {
|
|
||||||
loc.getWorld().spawnParticle(Particle.LAVA, loc, 8);
|
|
||||||
loc.getWorld().spawnParticle(Particle.FLAME, loc, 32, 0, 0, 0, .1);
|
|
||||||
loc.getWorld().playSound(loc, Sound.ENTITY_BLAZE_HURT, 2, 1);
|
|
||||||
target.setFireTicks((int) (target.getFireTicks() + cast.getModifier("ignite") * 20));
|
|
||||||
double damage = cast.getModifier("damage");
|
|
||||||
MythicLib.plugin.getDamage().damage(data.getPlayer(), (LivingEntity) target, new AttackResult(damage, DamageType.SKILL, DamageType.PROJECTILE, DamageType.MAGIC));
|
|
||||||
|
|
||||||
new BukkitRunnable() {
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (i++ > 2) {
|
|
||||||
cancel();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
double range = 2.5 * (1 + random.nextDouble());
|
|
||||||
Vector dir = randomDirection();
|
|
||||||
loc.getWorld().playSound(loc, Sound.ENTITY_BLAZE_HURT, 2, 1.5f);
|
|
||||||
|
|
||||||
MMORayTraceResult result = MythicLib.plugin.getVersion().getWrapper().rayTrace(loc, dir, range, entity -> MMOCoreUtils.canTarget(data, entity));
|
|
||||||
if (result.hasHit())
|
|
||||||
MythicLib.plugin.getDamage().damage(data.getPlayer(), result.getHit(), new AttackResult(damage, DamageType.SKILL, DamageType.PROJECTILE, DamageType.MAGIC));
|
|
||||||
result.draw(loc.clone(), dir, 8, tick -> tick.getWorld().spawnParticle(Particle.FLAME, tick, 0));
|
|
||||||
|
|
||||||
}
|
|
||||||
}.runTaskTimer(MMOCore.plugin, 3, 3);
|
|
||||||
|
|
||||||
cancel();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.runTaskTimer(MMOCore.plugin, 0, 1);
|
|
||||||
return cast;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Vector randomDirection() {
|
|
||||||
double x = random.nextDouble() - .5, y = (random.nextDouble() - .2) / 2, z = random.nextDouble() - .5;
|
|
||||||
Vector dir = new Vector(x, y, z);
|
|
||||||
return dir.lengthSquared() == 0 ? new Vector(1, 0, 0) : dir.normalize();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,53 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.skill;
|
|
||||||
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.Particle;
|
|
||||||
import org.bukkit.Sound;
|
|
||||||
import org.bukkit.entity.LivingEntity;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.api.skill.Skill;
|
|
||||||
import net.Indyuce.mmocore.api.skill.SkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.skill.result.TargetSkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect;
|
|
||||||
import io.lumine.mythic.lib.MythicLib;
|
|
||||||
import io.lumine.mythic.lib.api.AttackResult;
|
|
||||||
import io.lumine.mythic.lib.api.DamageType;
|
|
||||||
|
|
||||||
public class Furtive_Strike extends Skill {
|
|
||||||
public Furtive_Strike() {
|
|
||||||
super();
|
|
||||||
setMaterial(Material.COAL);
|
|
||||||
setLore("Deals &c{damage} &7damage, increased by &c{extra}% &7if", "there are not any enemies within &c{radius} &7blocks.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}");
|
|
||||||
|
|
||||||
addModifier("cooldown", new LinearValue(20, -.1, 5, 20));
|
|
||||||
addModifier("mana", new LinearValue(8, 3));
|
|
||||||
addModifier("damage", new LinearValue(5, 1.5));
|
|
||||||
addModifier("extra", new LinearValue(50, 20));
|
|
||||||
addModifier("radius", new LinearValue(7, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SkillResult whenCast(PlayerData data, SkillInfo skill) {
|
|
||||||
TargetSkillResult cast = new TargetSkillResult(data, skill, 3);
|
|
||||||
if (!cast.isSuccessful() || !data.isOnline())
|
|
||||||
return cast;
|
|
||||||
|
|
||||||
LivingEntity target = cast.getTarget();
|
|
||||||
target.getWorld().playSound(target.getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 2, 1.5f);
|
|
||||||
target.getWorld().spawnParticle(Particle.CRIT, target.getLocation().add(0, target.getHeight() / 2, 0), 32, 0, 0, 0, .5);
|
|
||||||
target.getWorld().spawnParticle(Particle.SMOKE_NORMAL, target.getLocation().add(0, target.getHeight() / 2, 0), 64, 0, 0, 0, .08);
|
|
||||||
|
|
||||||
double damage = cast.getModifier("damage");
|
|
||||||
|
|
||||||
double radius = cast.getModifier("radius");
|
|
||||||
if (target.getNearbyEntities(radius, radius, radius).stream().allMatch(entity -> entity.equals(data.getPlayer()))) {
|
|
||||||
new SmallParticleEffect(target, Particle.SPELL_WITCH);
|
|
||||||
damage *= 1 + cast.getModifier("extra") / 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
MythicLib.plugin.getDamage().damage(data.getPlayer(), target, new AttackResult(damage, DamageType.SKILL, DamageType.PHYSICAL));
|
|
||||||
return cast;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.skill;
|
|
||||||
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.Particle;
|
|
||||||
import org.bukkit.Sound;
|
|
||||||
import org.bukkit.attribute.Attribute;
|
|
||||||
import org.bukkit.entity.LivingEntity;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.api.skill.Skill;
|
|
||||||
import net.Indyuce.mmocore.api.skill.SkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.skill.result.TargetSkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect;
|
|
||||||
|
|
||||||
public class Greater_Healings extends Skill {
|
|
||||||
public Greater_Healings() {
|
|
||||||
super();
|
|
||||||
setMaterial(Material.GOLDEN_APPLE);
|
|
||||||
setLore("Instantly grants &a{heal} &7HP to the", "target. Sneak to cast it on yourself.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}");
|
|
||||||
|
|
||||||
addModifier("mana", new LinearValue(4, 2));
|
|
||||||
addModifier("heal", new LinearValue(10, 4));
|
|
||||||
addModifier("cooldown", new LinearValue(9, -.1, 1, 5));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SkillResult whenCast(PlayerData data, SkillInfo skill) {
|
|
||||||
SkillResult cast = data.getPlayer().isSneaking() ? new SkillResult(data, skill) : new TargetSkillResult(data, skill, 50, true);
|
|
||||||
if (!cast.isSuccessful())
|
|
||||||
return cast;
|
|
||||||
|
|
||||||
LivingEntity target = cast instanceof TargetSkillResult ? ((TargetSkillResult) cast).getTarget() : data.getPlayer();
|
|
||||||
|
|
||||||
double max = target.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
|
|
||||||
target.setHealth(Math.min(max, target.getHealth() + cast.getModifier("heal")));
|
|
||||||
|
|
||||||
new SmallParticleEffect(target, Particle.HEART, 1);
|
|
||||||
target.getWorld().playSound(target.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 2, 2);
|
|
||||||
return cast;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,105 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.skill;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Particle;
|
|
||||||
import org.bukkit.Sound;
|
|
||||||
import org.bukkit.attribute.Attribute;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.HandlerList;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.entity.EntityDamageEvent;
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.api.skill.Skill;
|
|
||||||
import net.Indyuce.mmocore.api.skill.SkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.skill.result.TargetSkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
|
||||||
import io.lumine.mythic.lib.version.VersionMaterial;
|
|
||||||
|
|
||||||
public class Human_Shield extends Skill {
|
|
||||||
public Human_Shield() {
|
|
||||||
super();
|
|
||||||
setMaterial(VersionMaterial.TOTEM_OF_UNDYING.toMaterial());
|
|
||||||
setLore("Casts a protection charm onto target ally,", "reducing damage taken by &a{reduction}%&7.", "&a{redirect}% &7of this damage is redirected to you.", "Charm is cancelled when reaching &c{low}%&7 health.", "Lasts &a{duration} &7seconds.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}");
|
|
||||||
|
|
||||||
addModifier("cooldown", new LinearValue(18, -.3, 14, 18));
|
|
||||||
addModifier("mana", new LinearValue(15, 1.5));
|
|
||||||
addModifier("reduction", new LinearValue(30, 3, 30, 70));
|
|
||||||
addModifier("redirect", new LinearValue(30, -2, 20, 30));
|
|
||||||
addModifier("duration", new LinearValue(7, 0));
|
|
||||||
addModifier("low", new LinearValue(10, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SkillResult whenCast(PlayerData data, SkillInfo skill) {
|
|
||||||
TargetSkillResult cast = new TargetSkillResult(data, skill, 7, true);
|
|
||||||
if (!cast.isSuccessful())
|
|
||||||
return cast;
|
|
||||||
|
|
||||||
if (!(cast.getTarget() instanceof Player)) {
|
|
||||||
cast.abort();
|
|
||||||
return cast;
|
|
||||||
}
|
|
||||||
|
|
||||||
data.getPlayer().getWorld().playSound(data.getPlayer().getLocation(), Sound.ENTITY_BLAZE_AMBIENT, 1, 1);
|
|
||||||
new HumanShield(data, (Player) cast.getTarget(), cast.getModifier("reduction"), cast.getModifier("redirect"), cast.getModifier("duration"), cast.getModifier("low"));
|
|
||||||
return cast;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class HumanShield extends BukkitRunnable implements Listener {
|
|
||||||
private final PlayerData data;
|
|
||||||
private final Player target;
|
|
||||||
private final double r, rd, d, l;
|
|
||||||
|
|
||||||
private int j;
|
|
||||||
|
|
||||||
public HumanShield(PlayerData data, Player target, double reduction, double redirect, double duration, double low) {
|
|
||||||
this.target = target;
|
|
||||||
this.data = data;
|
|
||||||
|
|
||||||
r = 1 - Math.min(1, reduction / 100);
|
|
||||||
rd = redirect / 100;
|
|
||||||
d = duration * 20;
|
|
||||||
l = low / 100;
|
|
||||||
|
|
||||||
runTaskTimer(MMOCore.plugin, 0, 1);
|
|
||||||
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void a(EntityDamageEvent event) {
|
|
||||||
if (event.getEntity().equals(target)) {
|
|
||||||
|
|
||||||
double damage = event.getDamage() * r;
|
|
||||||
event.setDamage(damage);
|
|
||||||
|
|
||||||
double health = data.getPlayer().getHealth() - damage * rd;
|
|
||||||
if (health > data.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue() * l)
|
|
||||||
data.getPlayer().setHealth(health);
|
|
||||||
else {
|
|
||||||
data.getPlayer().setHealth(1);
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (!data.isOnline() || data.getPlayer().isDead() || !target.isOnline() || target.isDead() || j++ >= d) {
|
|
||||||
close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
double a = (double) j / 5;
|
|
||||||
target.getWorld().spawnParticle(Particle.VILLAGER_HAPPY, target.getLocation().add(Math.cos(a), 1 + Math.sin(a / 3) / 1.3, Math.sin(a)), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void close() {
|
|
||||||
cancel();
|
|
||||||
HandlerList.unregisterAll(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,80 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.skill;
|
|
||||||
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.Particle;
|
|
||||||
import org.bukkit.Sound;
|
|
||||||
import org.bukkit.entity.Entity;
|
|
||||||
import org.bukkit.entity.LivingEntity;
|
|
||||||
import org.bukkit.potion.PotionEffect;
|
|
||||||
import org.bukkit.potion.PotionEffectType;
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.api.skill.Skill;
|
|
||||||
import net.Indyuce.mmocore.api.skill.SkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.skill.result.LocationSkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.Line3D;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
|
||||||
import io.lumine.mythic.lib.MythicLib;
|
|
||||||
import io.lumine.mythic.lib.api.AttackResult;
|
|
||||||
import io.lumine.mythic.lib.api.DamageType;
|
|
||||||
import io.lumine.mythic.lib.version.VersionMaterial;
|
|
||||||
|
|
||||||
public class Ice_Spikes extends Skill {
|
|
||||||
private static final double radius = 3;
|
|
||||||
|
|
||||||
public Ice_Spikes() {
|
|
||||||
super();
|
|
||||||
setMaterial(VersionMaterial.SNOWBALL.toMaterial());
|
|
||||||
setLore("Ice spikes summon from the ground", "and shatter, each dealing &9{damage} &7damage", "to hit enemies and slowing them down", "for &9{slow} &7seconds.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}");
|
|
||||||
|
|
||||||
addModifier("cooldown", new LinearValue(6, -.1, 2, 6));
|
|
||||||
addModifier("mana", new LinearValue(20, 2));
|
|
||||||
addModifier("damage", new LinearValue(3, 1));
|
|
||||||
addModifier("slow", new LinearValue(4, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SkillResult whenCast(PlayerData data, SkillInfo skill) {
|
|
||||||
LocationSkillResult cast = new LocationSkillResult(data, skill, 20);
|
|
||||||
if (!cast.isSuccessful() || !data.isOnline())
|
|
||||||
return cast;
|
|
||||||
|
|
||||||
Location loc = cast.getHit();
|
|
||||||
double damage = cast.getModifier("damage");
|
|
||||||
int slow = (int) (20 * cast.getModifier("slow"));
|
|
||||||
|
|
||||||
new BukkitRunnable() {
|
|
||||||
int j = 0;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
|
|
||||||
if (j++ > 8) {
|
|
||||||
cancel();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Location loc1 = loc.clone().add(offset() * radius, 0, offset() * radius).add(0, 2, 0);
|
|
||||||
loc.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, loc1, 32, 0, 2, 0, 0);
|
|
||||||
loc.getWorld().spawnParticle(Particle.SNOWBALL, loc1, 32, 0, 2, 0, 0);
|
|
||||||
loc.getWorld().playSound(loc1, Sound.BLOCK_GLASS_BREAK, 2, 0);
|
|
||||||
|
|
||||||
Line3D line = new Line3D(loc.toVector(), loc.toVector().add(new Vector(0, 1, 0)));
|
|
||||||
for (Entity entity : MMOCoreUtils.getNearbyChunkEntities(loc1))
|
|
||||||
if (line.distanceSquared(entity.getLocation().toVector()) < radius && Math.abs(entity.getLocation().getY() - loc1.getY()) < 10 && MMOCoreUtils.canTarget(data, entity)) {
|
|
||||||
MythicLib.plugin.getDamage().damage(data.getPlayer(), (LivingEntity) entity, new AttackResult(damage, DamageType.SKILL, DamageType.MAGIC));
|
|
||||||
((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, slow, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.runTaskTimer(MMOCore.plugin, 0, 5);
|
|
||||||
return cast;
|
|
||||||
}
|
|
||||||
|
|
||||||
private double offset() {
|
|
||||||
return random.nextDouble() * (random.nextBoolean() ? 1 : -1);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.skill;
|
|
||||||
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.Particle;
|
|
||||||
import org.bukkit.Sound;
|
|
||||||
import org.bukkit.attribute.Attribute;
|
|
||||||
import org.bukkit.entity.LivingEntity;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.api.skill.Skill;
|
|
||||||
import net.Indyuce.mmocore.api.skill.SkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.skill.result.TargetSkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect;
|
|
||||||
|
|
||||||
public class Minor_Healings extends Skill {
|
|
||||||
public Minor_Healings() {
|
|
||||||
super();
|
|
||||||
setMaterial(Material.GOLDEN_APPLE);
|
|
||||||
setLore("Instantly grants &a{heal} &7HP to the", "target. Sneak to cast it on yourself.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}");
|
|
||||||
|
|
||||||
addModifier("mana", new LinearValue(4, 2));
|
|
||||||
addModifier("heal", new LinearValue(4, 2));
|
|
||||||
addModifier("cooldown", new LinearValue(9, -.1, 1, 5));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SkillResult whenCast(PlayerData data, SkillInfo skill) {
|
|
||||||
SkillResult cast = data.getPlayer().isSneaking() ? new SkillResult(data, skill) : new TargetSkillResult(data, skill, 50, true);
|
|
||||||
if (!cast.isSuccessful())
|
|
||||||
return cast;
|
|
||||||
|
|
||||||
LivingEntity target = cast instanceof TargetSkillResult ? ((TargetSkillResult) cast).getTarget() : data.getPlayer();
|
|
||||||
|
|
||||||
double max = target.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
|
|
||||||
target.setHealth(Math.min(max, target.getHealth() + cast.getModifier("heal")));
|
|
||||||
|
|
||||||
new SmallParticleEffect(target, Particle.HEART, 1);
|
|
||||||
target.getWorld().playSound(target.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 2, 2);
|
|
||||||
return cast;
|
|
||||||
}
|
|
||||||
}
|
|
19
src/main/java/net/Indyuce/mmocore/skill/PassiveSkill.java
Normal file
19
src/main/java/net/Indyuce/mmocore/skill/PassiveSkill.java
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package net.Indyuce.mmocore.skill;
|
||||||
|
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.SkillMetadata;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
|
public class PassiveSkill extends Skill implements Listener {
|
||||||
|
public PassiveSkill() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public PassiveSkill(String id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SkillMetadata whenCast(CasterMetadata casterMeta, SkillInfo skill) {
|
||||||
|
return new SkillMetadata(casterMeta, skill);
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,13 @@
|
|||||||
package net.Indyuce.mmocore.api.skill;
|
package net.Indyuce.mmocore.skill;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import io.lumine.mythic.utils.cooldown.CooldownMap;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.skill.Skill.SkillInfo;
|
import net.Indyuce.mmocore.skill.Skill.SkillInfo;
|
||||||
import net.Indyuce.mmocore.comp.mythicmobs.skill.MythicMobSkill;
|
import net.Indyuce.mmocore.comp.mythicmobs.skill.MythicMobSkill;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.SkillMetadata;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note: any method which return longs returns milliseconds.
|
* Note: any method which return longs returns milliseconds.
|
||||||
@ -16,15 +18,6 @@ public class PlayerSkillData {
|
|||||||
private final Map<String, Long> cooldowns = new HashMap<>();
|
private final Map<String, Long> cooldowns = new HashMap<>();
|
||||||
private final PlayerData data;
|
private final PlayerData data;
|
||||||
|
|
||||||
/**
|
|
||||||
* MythicMobs skill damage is handled via math formula which can retrieve
|
|
||||||
* PAPI placeholders. When a skill is cast, all skill modifiers are cached
|
|
||||||
* into that map: 1- for easier and faster access 2- it removes interference
|
|
||||||
* for example when stats are calculating not when the spell is cast but
|
|
||||||
* rather when the spell hits
|
|
||||||
*/
|
|
||||||
private final Map<String, CachedModifier> cache = new HashMap<>();
|
|
||||||
|
|
||||||
public PlayerSkillData(PlayerData data) {
|
public PlayerSkillData(PlayerData data) {
|
||||||
this.data = data;
|
this.data = data;
|
||||||
}
|
}
|
||||||
@ -82,66 +75,4 @@ public class PlayerSkillData {
|
|||||||
long reduction = (long) (relative ? value * (double) getCooldown(skill) : value * 1000.);
|
long reduction = (long) (relative ? value * (double) getCooldown(skill) : value * 1000.);
|
||||||
cooldowns.put(skill.getSkill().getId(), lastCast(skill.getSkill()) + reduction);
|
cooldowns.put(skill.getSkill().getId(), lastCast(skill.getSkill()) + reduction);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getCachedModifier(String name) {
|
|
||||||
return cache.containsKey(name) ? cache.get(name).getValue() : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cacheModifiers(MythicMobSkill skill, SkillResult cast) {
|
|
||||||
cacheModifiers(skill.getInternalName(), cast);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Caches all modifiers from a cast skill in the map
|
|
||||||
*
|
|
||||||
* @param skill
|
|
||||||
* Skill identifier being used as reference in the map
|
|
||||||
* @param cast
|
|
||||||
* Skill being cast
|
|
||||||
*/
|
|
||||||
public void cacheModifiers(String skill, SkillResult cast) {
|
|
||||||
for (String modifier : cast.getSkill().getModifiers())
|
|
||||||
cacheModifier(skill, modifier, cast.getModifier(modifier));
|
|
||||||
|
|
||||||
cacheModifier(skill, "level", cast.getLevel());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Caches a specific modifier
|
|
||||||
*
|
|
||||||
* @param skill
|
|
||||||
* The identifier of the skill being cast
|
|
||||||
* @param name
|
|
||||||
* Modifier name
|
|
||||||
* @param value
|
|
||||||
* Modifier value
|
|
||||||
*/
|
|
||||||
public void cacheModifier(String skill, String name, double value) {
|
|
||||||
cache.put(skill + "." + name, new CachedModifier(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Empties cached modifiers. Modifiers should time out one minute after the
|
|
||||||
* skill was cast
|
|
||||||
*/
|
|
||||||
public void refresh() {
|
|
||||||
cache.values().removeIf(CachedModifier::isTimedOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class CachedModifier {
|
|
||||||
private final long date = System.currentTimeMillis();
|
|
||||||
private final double value;
|
|
||||||
|
|
||||||
public CachedModifier(double value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isTimedOut() {
|
|
||||||
return date + 1000 * 60 < System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,139 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.skill;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Color;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.Particle;
|
|
||||||
import org.bukkit.Sound;
|
|
||||||
import org.bukkit.entity.Entity;
|
|
||||||
import org.bukkit.entity.LivingEntity;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.potion.PotionEffect;
|
|
||||||
import org.bukkit.potion.PotionEffectType;
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.api.skill.Skill;
|
|
||||||
import net.Indyuce.mmocore.api.skill.SkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.particle.ParabolicProjectile;
|
|
||||||
import io.lumine.mythic.lib.MythicLib;
|
|
||||||
import io.lumine.mythic.lib.api.AttackResult;
|
|
||||||
import io.lumine.mythic.lib.api.DamageType;
|
|
||||||
import io.lumine.mythic.lib.api.event.PlayerAttackEvent;
|
|
||||||
import io.lumine.mythic.lib.version.VersionMaterial;
|
|
||||||
import io.lumine.mythic.lib.version.VersionSound;
|
|
||||||
|
|
||||||
public class Power_Mark extends Skill implements Listener {
|
|
||||||
public Power_Mark() {
|
|
||||||
super();
|
|
||||||
setMaterial(VersionMaterial.WITHER_SKELETON_SKULL.toMaterial());
|
|
||||||
setLore("Attacking an enemy applies a deadly", "magical mark which spreads accross the", "ground. This mark accumulates &6{ratio}%", "of the damage dealt to the initial", "target over &6{duration} &7seconds.", "", "After this duration, the mark bursts, dealing", "accumulated damage to nearby enemies and", "stunning them for &6{stun}+ &7seconds.", "", "The more damage, the longer the stun.", "", "&e{cooldown}s Cooldown");
|
|
||||||
setPassive();
|
|
||||||
|
|
||||||
addModifier("stun", new LinearValue(.4, .03));
|
|
||||||
addModifier("ratio", new LinearValue(10, 5));
|
|
||||||
addModifier("duration", new LinearValue(10, .1));
|
|
||||||
addModifier("cooldown", new LinearValue(30, 0));
|
|
||||||
|
|
||||||
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void a(PlayerAttackEvent event) {
|
|
||||||
PlayerData data = PlayerData.get(event.getData().getUniqueId());
|
|
||||||
if (!event.getAttack().hasType(DamageType.WEAPON) || !data.getProfess().hasSkill(this))
|
|
||||||
return;
|
|
||||||
|
|
||||||
SkillResult cast = data.cast(this);
|
|
||||||
if (!cast.isSuccessful())
|
|
||||||
return;
|
|
||||||
|
|
||||||
new PowerMark(data, cast, event.getEntity().getLocation());
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PowerMark extends BukkitRunnable implements Listener {
|
|
||||||
private final PlayerData data;
|
|
||||||
private final Location loc;
|
|
||||||
|
|
||||||
private final double duration;
|
|
||||||
private final double ratio;
|
|
||||||
private double stun;
|
|
||||||
|
|
||||||
private double accumulate;
|
|
||||||
private int j;
|
|
||||||
|
|
||||||
public PowerMark(PlayerData data, SkillResult cast, Location loc) {
|
|
||||||
this.data = data;
|
|
||||||
this.loc = loc;
|
|
||||||
|
|
||||||
loc.getWorld().playSound(loc, Sound.BLOCK_END_PORTAL_FRAME_FILL, 2, 1);
|
|
||||||
|
|
||||||
duration = cast.getModifier("duration");
|
|
||||||
ratio = cast.getModifier("ratio") / 100;
|
|
||||||
stun = cast.getModifier("stun");
|
|
||||||
|
|
||||||
runTaskTimer(MMOCore.plugin, 0, 1);
|
|
||||||
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void unregister() {
|
|
||||||
PlayerAttackEvent.getHandlerList().unregister(this);
|
|
||||||
cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST)
|
|
||||||
public void stackDamage(PlayerAttackEvent event) {
|
|
||||||
if (!event.isCancelled() && j < 20 * (duration - 2) && radiusCheck(event.getEntity().getLocation()) && PlayerData.get(event.getData().getUniqueId()).equals(data)) {
|
|
||||||
accumulate += event.getAttack().getDamage() * ratio;
|
|
||||||
new ParabolicProjectile(event.getEntity().getLocation().add(0, event.getEntity().getHeight() / 2, 0), loc, () -> loc.getWorld().playSound(loc, Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1), Color.PURPLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean radiusCheck(Location loc) {
|
|
||||||
return loc.getWorld().equals(this.loc.getWorld()) && loc.distanceSquared(this.loc) < 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if(!data.isOnline()) return;
|
|
||||||
if (j++ > duration * 20) {
|
|
||||||
unregister();
|
|
||||||
|
|
||||||
for (double a = 0; a < Math.PI * 2; a += Math.PI * 2 / 17)
|
|
||||||
new ParabolicProjectile(loc, loc.clone().add(6 * Math.cos(a), 0, 6 * Math.sin(a)), Particle.SPELL_WITCH);
|
|
||||||
|
|
||||||
loc.getWorld().playSound(loc, Sound.ENTITY_GENERIC_EXPLODE, 2, 0);
|
|
||||||
loc.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, loc.clone().add(0, 1, 0), 16, 2, 2, 2, 0);
|
|
||||||
loc.getWorld().spawnParticle(Particle.EXPLOSION_NORMAL, loc.clone().add(0, 1, 0), 24, 0, 0, 0, .3f);
|
|
||||||
|
|
||||||
stun += Math.log(Math.max(1, accumulate - 10)) / 8;
|
|
||||||
|
|
||||||
for (Entity entity : MMOCoreUtils.getNearbyChunkEntities(loc))
|
|
||||||
if (entity.getLocation().distanceSquared(loc) < 25 && MMOCoreUtils.canTarget(data, entity)) {
|
|
||||||
((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, (int) (stun * 20), 10, false, false));
|
|
||||||
MythicLib.plugin.getDamage().damage(data.getPlayer(), (LivingEntity) entity, new AttackResult(accumulate, DamageType.SKILL, DamageType.MAGIC));
|
|
||||||
entity.setVelocity(format(entity.getLocation().subtract(loc).toVector().setY(0)).setY(.3));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (j % 2 == 0 && j > 20 * (duration - 2))
|
|
||||||
loc.getWorld().playSound(loc, VersionSound.BLOCK_NOTE_BLOCK_PLING.toSound(), 1, (float) (1 + (j - 20 * (duration - 2)) / 40));
|
|
||||||
|
|
||||||
double a = (double) j / 16;
|
|
||||||
double r = Math.sqrt(Math.min(duration * 2 - (double) j / 10, 4)) * 2;
|
|
||||||
for (double k = 0; k < Math.PI * 2; k += Math.PI * 2 / 5)
|
|
||||||
loc.getWorld().spawnParticle(Particle.SPELL_WITCH, loc.clone().add(r * Math.cos(k + a), 0, r * Math.sin(k + a)), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Vector format(Vector vec) {
|
|
||||||
return vec.length() < .01 ? new Vector(0, 0, 0) : vec.normalize();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +1,10 @@
|
|||||||
package net.Indyuce.mmocore.api.skill;
|
package net.Indyuce.mmocore.skill;
|
||||||
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.IntegerLinearValue;
|
import net.Indyuce.mmocore.api.util.math.formula.IntegerLinearValue;
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.SkillMetadata;
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
@ -133,12 +134,7 @@ public abstract class Skill {
|
|||||||
return current instanceof IntegerLinearValue ? new IntegerLinearValue(config) : new LinearValue(config);
|
return current instanceof IntegerLinearValue ? new IntegerLinearValue(config) : new LinearValue(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
public abstract SkillMetadata whenCast(CasterMetadata casterMeta, SkillInfo skill);
|
||||||
* not overriden for passive skills therefore not abstract.
|
|
||||||
*/
|
|
||||||
public SkillResult whenCast(PlayerData data, SkillInfo skill) {
|
|
||||||
return new SkillResult(data, skill);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SkillInfo newSkillInfo(ConfigurationSection config) {
|
public SkillInfo newSkillInfo(ConfigurationSection config) {
|
||||||
return new SkillInfo(config);
|
return new SkillInfo(config);
|
@ -1,50 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.skill;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.Particle;
|
|
||||||
import org.bukkit.Sound;
|
|
||||||
import org.bukkit.entity.LivingEntity;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.api.skill.Skill;
|
|
||||||
import net.Indyuce.mmocore.api.skill.SkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
|
||||||
import io.lumine.mythic.lib.api.DamageType;
|
|
||||||
import io.lumine.mythic.lib.api.event.PlayerAttackEvent;
|
|
||||||
|
|
||||||
public class Sneaky_Picky extends Skill implements Listener {
|
|
||||||
public Sneaky_Picky() {
|
|
||||||
super();
|
|
||||||
setMaterial(Material.DIAMOND_SWORD);
|
|
||||||
setLore("Your attack is empowered by &f{extra}% &7when", "delivering the first blow during a fight.", "", "&9Costs {mana} {mana_name}");
|
|
||||||
setPassive();
|
|
||||||
|
|
||||||
addModifier("cooldown", new LinearValue(0, 0));
|
|
||||||
addModifier("mana", new LinearValue(8, 1));
|
|
||||||
addModifier("extra", new LinearValue(50, 20));
|
|
||||||
|
|
||||||
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void a(PlayerAttackEvent event) {
|
|
||||||
PlayerData data = PlayerData.get(event.getData().getUniqueId());
|
|
||||||
if (!event.getAttack().hasType(DamageType.WEAPON) || data.isInCombat() || !data.getProfess().hasSkill(this))
|
|
||||||
return;
|
|
||||||
|
|
||||||
SkillResult cast = data.cast(this);
|
|
||||||
if (!cast.isSuccessful())
|
|
||||||
return;
|
|
||||||
|
|
||||||
data.cast(cast.getInfo());
|
|
||||||
|
|
||||||
event.getAttack().multiplyDamage(1 + cast.getModifier("extra") / 100);
|
|
||||||
LivingEntity target = event.getEntity();
|
|
||||||
target.getWorld().spawnParticle(Particle.SMOKE_NORMAL, target.getLocation().add(0, target.getHeight() / 2, 0), 64, 0, 0, 0, .05);
|
|
||||||
target.getWorld().playSound(target.getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 1, 2);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,99 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.skill;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.Particle;
|
|
||||||
import org.bukkit.Sound;
|
|
||||||
import org.bukkit.entity.Entity;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.HandlerList;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.api.skill.Skill;
|
|
||||||
import net.Indyuce.mmocore.api.skill.SkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.skill.result.TargetSkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.particle.ParabolicProjectile;
|
|
||||||
import io.lumine.mythic.lib.version.VersionMaterial;
|
|
||||||
import io.lumine.mythic.lib.version.VersionSound;
|
|
||||||
|
|
||||||
public class Telekinesy extends Skill {
|
|
||||||
public Telekinesy() {
|
|
||||||
super();
|
|
||||||
setMaterial(VersionMaterial.MAGENTA_DYE.toMaterial());
|
|
||||||
setLore("You take the control over your target", "for &9{duration} &7seconds. Left click to throw him.", "Knockback force: &f{knockback}%", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}");
|
|
||||||
|
|
||||||
addModifier("cooldown", new LinearValue(20, -.3, 10, 20));
|
|
||||||
addModifier("mana", new LinearValue(20, 2));
|
|
||||||
addModifier("knockback", new LinearValue(50, 10));
|
|
||||||
addModifier("duration", new LinearValue(3, .1, 3, 6));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SkillResult whenCast(PlayerData data, SkillInfo skill) {
|
|
||||||
TargetSkillResult cast = new TargetSkillResult(data, skill, 7);
|
|
||||||
if (!cast.isSuccessful() || !data.isOnline())
|
|
||||||
return cast;
|
|
||||||
|
|
||||||
data.getPlayer().getWorld().playSound(data.getPlayer().getLocation(), Sound.BLOCK_END_PORTAL_FRAME_FILL, 1, 1);
|
|
||||||
new TelekinesyRunnable(data, cast.getTarget(), cast.getModifier("duration"), cast.getModifier("knockback") / 100);
|
|
||||||
return cast;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class TelekinesyRunnable extends BukkitRunnable implements Listener {
|
|
||||||
private final Entity entity;
|
|
||||||
private final PlayerData data;
|
|
||||||
|
|
||||||
private final long duration;
|
|
||||||
private final double d, f;
|
|
||||||
|
|
||||||
private int j;
|
|
||||||
|
|
||||||
public TelekinesyRunnable(PlayerData data, Entity entity, double duration, double force) {
|
|
||||||
this.entity = entity;
|
|
||||||
this.data = data;
|
|
||||||
|
|
||||||
d = data.getPlayer().getLocation().distance(entity.getLocation());
|
|
||||||
f = force;
|
|
||||||
this.duration = (long) (20 * duration);
|
|
||||||
|
|
||||||
runTaskTimer(MMOCore.plugin, 0, 1);
|
|
||||||
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void a(PlayerInteractEvent event) {
|
|
||||||
if(!data.isOnline()) return;
|
|
||||||
if (event.getPlayer().equals(data.getPlayer()) && event.getAction().name().contains("LEFT_CLICK")) {
|
|
||||||
entity.setVelocity(data.getPlayer().getEyeLocation().getDirection().multiply(1.5 * f));
|
|
||||||
entity.getWorld().playSound(entity.getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 2, 1);
|
|
||||||
entity.getWorld().spawnParticle(Particle.SPELL_WITCH, entity.getLocation().add(0, entity.getHeight() / 2, 0), 16);
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (!data.isOnline() || entity.isDead() || j++ >= duration) {
|
|
||||||
close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (j % 8 == 0)
|
|
||||||
new ParabolicProjectile(data.getPlayer().getEyeLocation(), entity.getLocation().add(0, entity.getHeight() / 2, 0), Particle.SPELL_WITCH);
|
|
||||||
|
|
||||||
Location loc = data.getPlayer().getEyeLocation().add(data.getPlayer().getEyeLocation().getDirection().multiply(d));
|
|
||||||
entity.setVelocity(loc.subtract(entity.getLocation().add(0, entity.getHeight() / 2, 0)).toVector().multiply(2));
|
|
||||||
entity.setFallDistance(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void close() {
|
|
||||||
cancel();
|
|
||||||
HandlerList.unregisterAll(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,60 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.skill;
|
|
||||||
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.Particle;
|
|
||||||
import org.bukkit.Sound;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.api.skill.Skill;
|
|
||||||
import net.Indyuce.mmocore.api.skill.SkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.particle.ParabolicProjectile;
|
|
||||||
import io.lumine.mythic.lib.version.VersionSound;
|
|
||||||
|
|
||||||
public class Warp extends Skill {
|
|
||||||
public Warp() {
|
|
||||||
super();
|
|
||||||
setMaterial(Material.ENDER_PEARL);
|
|
||||||
setLore("Teleports you to target location.", "Max. Range: &5{range}", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}");
|
|
||||||
|
|
||||||
addModifier("cooldown", new LinearValue(15, -.3, 2, 15));
|
|
||||||
addModifier("mana", new LinearValue(8, 3));
|
|
||||||
addModifier("range", new LinearValue(16, 1, 0, 100));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SkillResult whenCast(PlayerData data, SkillInfo skill) {
|
|
||||||
WarpCast cast = new WarpCast(data, skill);
|
|
||||||
if (!cast.isSuccessful() || !data.isOnline())
|
|
||||||
return cast;
|
|
||||||
|
|
||||||
data.getPlayer().getWorld().playSound(data.getPlayer().getLocation(), Sound.BLOCK_END_PORTAL_FRAME_FILL, 1, 2);
|
|
||||||
|
|
||||||
Location loc = cast.block.getLocation().add(0, 1, 0);
|
|
||||||
loc.setYaw(data.getPlayer().getLocation().getYaw());
|
|
||||||
loc.setPitch(data.getPlayer().getLocation().getPitch());
|
|
||||||
|
|
||||||
new ParabolicProjectile(data.getPlayer().getLocation().add(0, 1, 0), loc.clone().add(0, 1, 0), () -> {
|
|
||||||
if (data.getPlayer().isOnline() && !data.getPlayer().isDead()) {
|
|
||||||
data.getPlayer().teleport(loc);
|
|
||||||
data.getPlayer().getWorld().spawnParticle(Particle.EXPLOSION_LARGE, data.getPlayer().getLocation().add(0, 1, 0), 0);
|
|
||||||
data.getPlayer().getWorld().spawnParticle(Particle.SPELL_INSTANT, data.getPlayer().getLocation().add(0, 1, 0), 32, 0, 0, 0, .1);
|
|
||||||
data.getPlayer().getWorld().playSound(data.getPlayer().getLocation(), VersionSound.ENTITY_ENDERMAN_TELEPORT.toSound(), 1, 1);
|
|
||||||
}
|
|
||||||
}, 2, Particle.SPELL_INSTANT);
|
|
||||||
return cast;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class WarpCast extends SkillResult {
|
|
||||||
private Block block;
|
|
||||||
|
|
||||||
public WarpCast(PlayerData data, SkillInfo skill) {
|
|
||||||
super(data, skill);
|
|
||||||
if(!data.isOnline()) abort();
|
|
||||||
else if (isSuccessful() && (block = data.getPlayer().getTargetBlock(null, (int) getModifier("range"))) == null)
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,77 +0,0 @@
|
|||||||
package net.Indyuce.mmocore.skill;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Particle;
|
|
||||||
import org.bukkit.entity.Entity;
|
|
||||||
import org.bukkit.entity.LivingEntity;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
|
||||||
import net.Indyuce.mmocore.api.skill.Skill;
|
|
||||||
import net.Indyuce.mmocore.api.skill.SkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.skill.result.TargetSkillResult;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.particle.ParabolicProjectile;
|
|
||||||
import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect;
|
|
||||||
import io.lumine.mythic.lib.version.VersionMaterial;
|
|
||||||
|
|
||||||
public class Weaken extends Skill {
|
|
||||||
public Weaken() {
|
|
||||||
super();
|
|
||||||
setMaterial(VersionMaterial.MAGENTA_DYE.toMaterial());
|
|
||||||
setLore("The target is weakened for", "&8{duration} &7seconds and is dealt", "&7extra &8{ratio}% &7damage.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}");
|
|
||||||
|
|
||||||
addModifier("cooldown", new LinearValue(20, -.1, 5, 20));
|
|
||||||
addModifier("mana", new LinearValue(4, 1));
|
|
||||||
addModifier("ratio", new LinearValue(30, 3));
|
|
||||||
addModifier("duration", new LinearValue(10, -.1, 5, 10));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SkillResult whenCast(PlayerData data, SkillInfo skill) {
|
|
||||||
TargetSkillResult cast = new TargetSkillResult(data, skill, 7);
|
|
||||||
if (!cast.isSuccessful() || !data.isOnline())
|
|
||||||
return cast;
|
|
||||||
|
|
||||||
LivingEntity target = cast.getTarget();
|
|
||||||
new ParabolicProjectile(data.getPlayer().getLocation().add(0, 1, 0), target.getLocation().add(0, target.getHeight() / 2, 0), randomVector(data.getPlayer()), () -> {
|
|
||||||
if (!target.isDead())
|
|
||||||
new Weakened(target, cast.getModifier("ratio"), cast.getModifier("duration"));
|
|
||||||
}, 2, Particle.SPELL_WITCH);
|
|
||||||
return cast;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Vector randomVector(Player player) {
|
|
||||||
double a = Math.toRadians(player.getEyeLocation().getYaw() + 90);
|
|
||||||
a += (random.nextBoolean() ? 1 : -1) * (random.nextDouble() + .5) * Math.PI / 6;
|
|
||||||
return new Vector(Math.cos(a), .8, Math.sin(a)).normalize().multiply(.4);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Weakened implements Listener {
|
|
||||||
private final Entity entity;
|
|
||||||
private final double c;
|
|
||||||
|
|
||||||
public Weakened(Entity entity, double ratio, double duration) {
|
|
||||||
this.entity = entity;
|
|
||||||
this.c = 1 + ratio / 100;
|
|
||||||
|
|
||||||
new SmallParticleEffect(entity, Particle.SPELL_WITCH);
|
|
||||||
|
|
||||||
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
|
||||||
Bukkit.getScheduler().scheduleSyncDelayedTask(MMOCore.plugin, () -> EntityDamageByEntityEvent.getHandlerList().unregister(this), (int) duration * 20);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void a(EntityDamageByEntityEvent event) {
|
|
||||||
if (event.getEntity().equals(entity)) {
|
|
||||||
event.getEntity().getWorld().spawnParticle(Particle.SPELL_WITCH, entity.getLocation().add(0, entity.getHeight() / 2, 0), 16, .5, .5, .5, 0);
|
|
||||||
event.setDamage(event.getDamage() * c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
88
src/main/java/net/Indyuce/mmocore/skill/list/Ambers.java
Normal file
88
src/main/java/net/Indyuce/mmocore/skill/list/Ambers.java
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
package net.Indyuce.mmocore.skill.list;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.api.event.PlayerAttackEvent;
|
||||||
|
import io.lumine.mythic.lib.damage.DamageType;
|
||||||
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
|
import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent;
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import net.Indyuce.mmocore.api.player.stats.StatType;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.particle.ParabolicProjectile;
|
||||||
|
import net.Indyuce.mmocore.skill.PassiveSkill;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.SkillMetadata;
|
||||||
|
import org.bukkit.*;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
|
||||||
|
public class Ambers extends PassiveSkill {
|
||||||
|
public Ambers() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
setMaterial(Material.EMERALD);
|
||||||
|
setLore("Dealing magic damage has &630% &7chance", "of dropping an amber on the ground.", "", "When picked up, ambers stack and",
|
||||||
|
"refund &9{percent}% &7of your missing mana.", "", "&oAmbers can be used in other damaging skills.",
|
||||||
|
"&oThe more you collect, the more powerful the skills.", "", "&e{cooldown}s Cooldown");
|
||||||
|
setPassive();
|
||||||
|
|
||||||
|
addModifier("cooldown", new LinearValue(3, -.1, 1, 3));
|
||||||
|
addModifier("percent", new LinearValue(10, .1, 10, 20));
|
||||||
|
|
||||||
|
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void a(PlayerAttackEvent event) {
|
||||||
|
PlayerData data = PlayerData.get(event.getData().getUniqueId());
|
||||||
|
if (!event.getAttack().getDamage().hasType(DamageType.SKILL) || !data.getProfess().hasSkill(this))
|
||||||
|
return;
|
||||||
|
|
||||||
|
SkillMetadata cast = data.cast(this);
|
||||||
|
if (!cast.isSuccessful())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Location loc = event.getEntity().getLocation();
|
||||||
|
double a = random.nextDouble() * 2 * Math.PI;
|
||||||
|
|
||||||
|
new Amber(data, loc.add(0, event.getEntity().getHeight() / 2, 0), loc.clone().add(4 * Math.cos(a), 0, 4 * Math.sin(a)), cast.getModifier("percent"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Amber extends BukkitRunnable {
|
||||||
|
private final Location loc;
|
||||||
|
private final PlayerData data;
|
||||||
|
private final double percent;
|
||||||
|
|
||||||
|
private int j;
|
||||||
|
|
||||||
|
private Amber(PlayerData data, Location source, Location loc, double percent) {
|
||||||
|
this.loc = loc;
|
||||||
|
this.data = data;
|
||||||
|
this.percent = percent / 100;
|
||||||
|
|
||||||
|
final Amber amber = this;
|
||||||
|
new ParabolicProjectile(source, loc, Particle.REDSTONE, () -> amber.runTaskTimer(MMOCore.plugin, 0, 3), 1, Color.ORANGE, 1.3f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (!data.isOnline()) return;
|
||||||
|
if (j++ > 66 || !data.getPlayer().getWorld().equals(loc.getWorld())) {
|
||||||
|
cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.getPlayer().getLocation().distanceSquared(loc) < 2) {
|
||||||
|
|
||||||
|
data.getPlayer().playSound(data.getPlayer().getLocation(), Sound.BLOCK_END_PORTAL_FRAME_FILL, 1, 1);
|
||||||
|
// data.getSkillData().ambers++;
|
||||||
|
data.giveMana((data.getStats().getStat(StatType.MAX_MANA) - data.getMana()) * percent, PlayerResourceUpdateEvent.UpdateReason.SKILL_REGENERATION);
|
||||||
|
|
||||||
|
cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = 0; j < 5; j++)
|
||||||
|
loc.getWorld().spawnParticle(Particle.SPELL_MOB, loc, 0, 1, 0.647, 0, 1);
|
||||||
|
loc.getWorld().spawnParticle(Particle.REDSTONE, loc, 1, new Particle.DustOptions(Color.ORANGE, 1.3f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
50
src/main/java/net/Indyuce/mmocore/skill/list/Backstab.java
Normal file
50
src/main/java/net/Indyuce/mmocore/skill/list/Backstab.java
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package net.Indyuce.mmocore.skill.list;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.api.event.PlayerAttackEvent;
|
||||||
|
import io.lumine.mythic.lib.damage.DamageType;
|
||||||
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
|
import net.Indyuce.mmocore.skill.PassiveSkill;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.SkillMetadata;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Particle;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
|
||||||
|
public class Backstab extends PassiveSkill {
|
||||||
|
public Backstab() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
setMaterial(Material.FLINT);
|
||||||
|
setLore("Backstabs deal &c{extra}%&7 damage.", "", "&9Costs {mana} {mana_name}");
|
||||||
|
setPassive();
|
||||||
|
|
||||||
|
addModifier("cooldown", new LinearValue(0, 0));
|
||||||
|
addModifier("mana", new LinearValue(8, 1));
|
||||||
|
addModifier("extra", new LinearValue(50, 20));
|
||||||
|
|
||||||
|
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void a(PlayerAttackEvent event) {
|
||||||
|
PlayerData data = PlayerData.get(event.getData().getUniqueId());
|
||||||
|
LivingEntity target = event.getEntity();
|
||||||
|
if (data.isInCombat() || !event.getAttack().getDamage().hasType(DamageType.WEAPON)
|
||||||
|
|| event.getPlayer().getEyeLocation().getDirection().angle(target.getEyeLocation().getDirection()) > Math.PI / 6
|
||||||
|
|| !data.getProfess().hasSkill(this))
|
||||||
|
return;
|
||||||
|
|
||||||
|
SkillMetadata cast = data.cast(this);
|
||||||
|
if (!cast.isSuccessful())
|
||||||
|
return;
|
||||||
|
|
||||||
|
data.cast(cast.getInfo());
|
||||||
|
event.getAttack().getDamage().multiply(1 + cast.getModifier("extra") / 100, DamageType.PHYSICAL);
|
||||||
|
target.getWorld().spawnParticle(Particle.CRIT, target.getLocation().add(0, target.getHeight() / 2, 0), 32, 0, 0, 0, .05);
|
||||||
|
target.getWorld().playSound(target.getLocation(), Sound.ENTITY_ENDERMAN_HURT, 1, 1.5f);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
package net.Indyuce.mmocore.skill.list;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.damage.DamageType;
|
||||||
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
|
import net.Indyuce.mmocore.skill.CasterMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.Skill;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.SkillMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.TargetSkillMetadata;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Particle;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
|
||||||
|
public class Combo_Attack extends Skill {
|
||||||
|
public Combo_Attack() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
setMaterial(Material.IRON_SWORD);
|
||||||
|
setLore("Violenty slashes your target &8{count}", "times for a total of &8{damage} &7damage.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}");
|
||||||
|
|
||||||
|
addModifier("cooldown", new LinearValue(20, -.1, 5, 20));
|
||||||
|
addModifier("damage", new LinearValue(9, .3));
|
||||||
|
addModifier("count", new LinearValue(3, .2));
|
||||||
|
addModifier("mana", new LinearValue(10, -.1, 3, 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) {
|
||||||
|
TargetSkillMetadata cast = new TargetSkillMetadata(caster, skill, 3);
|
||||||
|
if (!cast.isSuccessful())
|
||||||
|
return cast;
|
||||||
|
|
||||||
|
new BukkitRunnable() {
|
||||||
|
final int count = (int) cast.getModifier("count");
|
||||||
|
final double damage = cast.getModifier("damage") / count;
|
||||||
|
final LivingEntity target = cast.getTarget();
|
||||||
|
|
||||||
|
int c;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (c++ > count || caster.getPlayerData().isOnline()) {
|
||||||
|
cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
target.getWorld().playSound(target.getLocation(), Sound.ENTITY_PLAYER_ATTACK_KNOCKBACK, 1, 2);
|
||||||
|
target.getWorld().spawnParticle(Particle.CRIT, target.getLocation().add(0, target.getHeight() / 2, 0), 24, 0, 0, 0, .7);
|
||||||
|
caster.attack(target, damage, DamageType.SKILL, DamageType.PHYSICAL);
|
||||||
|
}
|
||||||
|
}.runTaskTimer(MMOCore.plugin, 0, 5);
|
||||||
|
return cast;
|
||||||
|
}
|
||||||
|
}
|
103
src/main/java/net/Indyuce/mmocore/skill/list/Control.java
Normal file
103
src/main/java/net/Indyuce/mmocore/skill/list/Control.java
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
package net.Indyuce.mmocore.skill.list;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.version.VersionMaterial;
|
||||||
|
import io.lumine.mythic.lib.version.VersionSound;
|
||||||
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
|
import net.Indyuce.mmocore.skill.CasterMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.Skill;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.SkillMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.TargetSkillMetadata;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Particle;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
import org.bukkit.potion.PotionEffect;
|
||||||
|
import org.bukkit.potion.PotionEffectType;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
public class Control extends Skill {
|
||||||
|
public Control() {
|
||||||
|
super();
|
||||||
|
setMaterial(VersionMaterial.MAGENTA_DYE.toMaterial());
|
||||||
|
setLore("Your target is temporarily slowed for &8{duration} &7seconds.", "As soon as you left click, it gets", "pushed back where you are looking at.", "Knockback force: &f{knockback}%", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}");
|
||||||
|
|
||||||
|
addModifier("cooldown", new LinearValue(18, -.3, 10, 20));
|
||||||
|
addModifier("mana", new LinearValue(15, 1.5));
|
||||||
|
addModifier("knockback", new LinearValue(30, 3));
|
||||||
|
addModifier("duration", new LinearValue(2, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) {
|
||||||
|
TargetSkillMetadata cast = new TargetSkillMetadata(caster, skill, 7);
|
||||||
|
if (!cast.isSuccessful())
|
||||||
|
return cast;
|
||||||
|
|
||||||
|
caster.getPlayer().getWorld().playSound(caster.getPlayer().getLocation(), Sound.BLOCK_END_PORTAL_FRAME_FILL, 1, 1);
|
||||||
|
cast.getTarget().addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 20 * 2, 0));
|
||||||
|
new TelekinesyRunnable(caster, cast.getTarget(), cast.getModifier("knockback") / 100, cast.getModifier("duration"));
|
||||||
|
return cast;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TelekinesyRunnable extends BukkitRunnable implements Listener {
|
||||||
|
private final LivingEntity entity;
|
||||||
|
private final CasterMetadata caster;
|
||||||
|
|
||||||
|
private final double f, d;
|
||||||
|
|
||||||
|
private int j;
|
||||||
|
|
||||||
|
public TelekinesyRunnable(CasterMetadata caster, LivingEntity entity, double force, double duration) {
|
||||||
|
this.entity = entity;
|
||||||
|
this.caster = caster;
|
||||||
|
|
||||||
|
d = duration * 20;
|
||||||
|
f = force;
|
||||||
|
|
||||||
|
runTaskTimer(MMOCore.plugin, 0, 1);
|
||||||
|
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void a(PlayerInteractEvent event) {
|
||||||
|
if (event.getPlayer().equals(caster.getPlayer()) && event.getAction().name().contains("LEFT_CLICK")) {
|
||||||
|
Vector vec = caster.getPlayer().getEyeLocation().getDirection().multiply(3 * f);
|
||||||
|
vec.setY(Math.max(.5, vec.getY() / 2));
|
||||||
|
entity.setVelocity(vec);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* try not to interfere with other potion effects
|
||||||
|
*/
|
||||||
|
PotionEffect effect = entity.getPotionEffect(PotionEffectType.SLOW);
|
||||||
|
if (effect.getDuration() < d && effect.getAmplifier() == 0)
|
||||||
|
entity.removePotionEffect(PotionEffectType.SLOW);
|
||||||
|
|
||||||
|
entity.getWorld().spawnParticle(Particle.SPELL_WITCH, entity.getLocation().add(0, entity.getHeight() / 2, 0), 16);
|
||||||
|
entity.getWorld().playSound(entity.getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 2, 1);
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (!caster.getPlayerData().isOnline() || entity.isDead() || j++ >= d) {
|
||||||
|
close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
double a = (double) j / 3;
|
||||||
|
entity.getWorld().spawnParticle(Particle.SPELL_WITCH, entity.getLocation().add(Math.cos(a), entity.getHeight() / 2, Math.sin(a)), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void close() {
|
||||||
|
cancel();
|
||||||
|
HandlerList.unregisterAll(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
47
src/main/java/net/Indyuce/mmocore/skill/list/Deep_Wound.java
Normal file
47
src/main/java/net/Indyuce/mmocore/skill/list/Deep_Wound.java
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package net.Indyuce.mmocore.skill.list;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.damage.DamageType;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
|
import net.Indyuce.mmocore.skill.CasterMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.Skill;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.SkillMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.TargetSkillMetadata;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Particle;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.attribute.Attribute;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
|
||||||
|
public class Deep_Wound extends Skill {
|
||||||
|
public Deep_Wound() {
|
||||||
|
super();
|
||||||
|
setMaterial(Material.REDSTONE);
|
||||||
|
setLore("You puncture your target, dealing &c{damage} &7damage.", "Damage is increased up to &c+{extra}% &7based",
|
||||||
|
"on your target's missing health.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}");
|
||||||
|
|
||||||
|
addModifier("cooldown", new LinearValue(20, -.1, 5, 20));
|
||||||
|
addModifier("mana", new LinearValue(8, 3));
|
||||||
|
addModifier("damage", new LinearValue(5, 1.5));
|
||||||
|
addModifier("extra", new LinearValue(50, 20));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) {
|
||||||
|
TargetSkillMetadata cast = new TargetSkillMetadata(caster, skill, 3);
|
||||||
|
if (!cast.isSuccessful())
|
||||||
|
return cast;
|
||||||
|
|
||||||
|
LivingEntity target = cast.getTarget();
|
||||||
|
target.getWorld().playSound(target.getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 2, 2);
|
||||||
|
target.getWorld().spawnParticle(Particle.CRIT, target.getLocation().add(0, target.getHeight() / 2, 0), 32, 0, 0, 0, .7);
|
||||||
|
target.getWorld().spawnParticle(Particle.BLOCK_CRACK, target.getLocation().add(0, target.getHeight() / 2, 0), 32, 0, 0, 0, 2,
|
||||||
|
Material.REDSTONE_BLOCK.createBlockData());
|
||||||
|
|
||||||
|
double max = target.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
|
||||||
|
double ratio = (max - target.getHealth()) / max;
|
||||||
|
|
||||||
|
double damage = cast.getModifier("damage") * (1 + cast.getModifier("extra") * ratio / 100);
|
||||||
|
caster.attack(target, damage, DamageType.SKILL, DamageType.PHYSICAL);
|
||||||
|
return cast;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,119 @@
|
|||||||
|
package net.Indyuce.mmocore.skill.list;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.api.event.PlayerAttackEvent;
|
||||||
|
import io.lumine.mythic.lib.damage.DamageType;
|
||||||
|
import io.lumine.mythic.lib.version.VersionMaterial;
|
||||||
|
import io.lumine.mythic.lib.version.VersionSound;
|
||||||
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
|
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect;
|
||||||
|
import net.Indyuce.mmocore.skill.CasterMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.Skill;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.SkillMetadata;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Particle;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
public class Empowered_Attack extends Skill {
|
||||||
|
private static final double perb = 5;
|
||||||
|
|
||||||
|
public Empowered_Attack() {
|
||||||
|
super();
|
||||||
|
setMaterial(VersionMaterial.BONE_MEAL.toMaterial());
|
||||||
|
setLore("You charge your weapon with lightning.", "Your next attack deals &f{extra}% &7extra damage", "and spreads to enemies within &f{radius} &7blocks", "for &f{ratio}% &7of the initial damage.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}");
|
||||||
|
|
||||||
|
addModifier("cooldown", new LinearValue(10, -.2, 5, 10));
|
||||||
|
addModifier("mana", new LinearValue(4, 1));
|
||||||
|
addModifier("radius", new LinearValue(4, 0));
|
||||||
|
addModifier("ratio", new LinearValue(30, 10, 30, 100));
|
||||||
|
addModifier("extra", new LinearValue(30, 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) {
|
||||||
|
SkillMetadata cast = new SkillMetadata(caster, skill);
|
||||||
|
if (!cast.isSuccessful())
|
||||||
|
return cast;
|
||||||
|
|
||||||
|
caster.getPlayer().playSound(caster.getPlayer().getLocation(), Sound.BLOCK_END_PORTAL_FRAME_FILL, 1, 1);
|
||||||
|
new EmpoweredAttack(caster, cast.getModifier("extra"), cast.getModifier("ratio"), cast.getModifier("radius"));
|
||||||
|
return cast;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawVector(Location loc, Vector vec) {
|
||||||
|
|
||||||
|
double steps = vec.length() * perb;
|
||||||
|
Vector v = vec.clone().normalize().multiply((double) 1 / perb);
|
||||||
|
|
||||||
|
for (int j = 0; j < Math.min(steps, 124); j++)
|
||||||
|
loc.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, loc.add(v), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class EmpoweredAttack implements Listener {
|
||||||
|
private final CasterMetadata caster;
|
||||||
|
private final double c, r, rad;
|
||||||
|
|
||||||
|
public EmpoweredAttack(CasterMetadata caster, double extra, double ratio, double radius) {
|
||||||
|
this.caster = caster;
|
||||||
|
this.c = 1 + extra / 100;
|
||||||
|
this.r = ratio / 100;
|
||||||
|
this.rad = radius;
|
||||||
|
|
||||||
|
if (caster.getPlayerData().isOnline())
|
||||||
|
new SmallParticleEffect(caster.getPlayer(), Particle.FIREWORKS_SPARK);
|
||||||
|
|
||||||
|
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
||||||
|
Bukkit.getScheduler().scheduleSyncDelayedTask(MMOCore.plugin, this::close, 80);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void close() {
|
||||||
|
PlayerAttackEvent.getHandlerList().unregister(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void a(PlayerAttackEvent event) {
|
||||||
|
if (!caster.getPlayerData().isOnline()) return;
|
||||||
|
if (event.getPlayer().equals(caster.getPlayer()) && event.getAttack().getDamage().hasType(DamageType.WEAPON)) {
|
||||||
|
close();
|
||||||
|
|
||||||
|
Entity target = event.getEntity();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* play lightning effect
|
||||||
|
*/
|
||||||
|
final Location loc = target.getLocation().add(0, target.getHeight() / 2, 0);
|
||||||
|
for (int j = 0; j < 3; j++) {
|
||||||
|
Location clone = loc.clone();
|
||||||
|
double a = random.nextDouble() * Math.PI * 2;
|
||||||
|
loc.add(Math.cos(a), 5, Math.sin(a));
|
||||||
|
drawVector(clone, loc.clone().subtract(clone).toVector());
|
||||||
|
}
|
||||||
|
|
||||||
|
target.getWorld().playSound(target.getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 2, .5f);
|
||||||
|
target.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, target.getLocation().add(0, target.getHeight() / 2, 0), 32, 0, 0, 0, .2);
|
||||||
|
|
||||||
|
double sweep = event.getAttack().getDamage().getDamage() * r;
|
||||||
|
Location src = target.getLocation().add(0, target.getHeight() / 2, 0);
|
||||||
|
|
||||||
|
for (Entity entity : target.getNearbyEntities(rad, rad, rad))
|
||||||
|
if (MMOCoreUtils.canTarget(caster.getPlayerData(), entity)) {
|
||||||
|
drawVector(src, entity.getLocation().add(0, entity.getHeight() / 2, 0).subtract(src).toVector());
|
||||||
|
caster.attack((LivingEntity) entity, sweep, DamageType.PHYSICAL, DamageType.SKILL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Apply damage afterwards otherwise the damage dealt to nearby
|
||||||
|
* entities scale with the extra ability damage.
|
||||||
|
*/
|
||||||
|
event.getAttack().getDamage().multiply(1 + c, DamageType.WEAPON);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
83
src/main/java/net/Indyuce/mmocore/skill/list/Evade.java
Normal file
83
src/main/java/net/Indyuce/mmocore/skill/list/Evade.java
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
package net.Indyuce.mmocore.skill.list;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.api.event.PlayerAttackEvent;
|
||||||
|
import io.lumine.mythic.lib.damage.DamageType;
|
||||||
|
import io.lumine.mythic.lib.version.VersionSound;
|
||||||
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect;
|
||||||
|
import net.Indyuce.mmocore.skill.CasterMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.Skill;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.SkillMetadata;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Particle;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.entity.EntityDamageEvent;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
|
||||||
|
public class Evade extends Skill {
|
||||||
|
public Evade() {
|
||||||
|
super();
|
||||||
|
setMaterial(Material.LEATHER_BOOTS);
|
||||||
|
setLore("You become imune to damage for &8{duration} &7seconds.", "Cancels when dealing weapon damage.", "", "&e{cooldown}s Cooldown",
|
||||||
|
"&9Costs {mana} {mana_name}");
|
||||||
|
|
||||||
|
addModifier("cooldown", new LinearValue(20, 0));
|
||||||
|
addModifier("mana", new LinearValue(8, 3));
|
||||||
|
addModifier("duration", new LinearValue(2, .3, 2, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) {
|
||||||
|
SkillMetadata cast = new SkillMetadata(caster, skill);
|
||||||
|
if (!cast.isSuccessful())
|
||||||
|
return cast;
|
||||||
|
|
||||||
|
caster.getPlayer().getWorld().playSound(caster.getPlayer().getLocation(), VersionSound.ENTITY_ENDERMAN_TELEPORT.toSound(), 1, 2);
|
||||||
|
new SmallParticleEffect(caster.getPlayer(), Particle.CLOUD);
|
||||||
|
new EvadeSkill(caster.getPlayerData(), cast.getModifier("duration"));
|
||||||
|
return cast;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class EvadeSkill extends BukkitRunnable implements Listener {
|
||||||
|
private final PlayerData data;
|
||||||
|
|
||||||
|
public EvadeSkill(PlayerData data, double duration) {
|
||||||
|
this.data = data;
|
||||||
|
|
||||||
|
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
||||||
|
runTaskTimer(MMOCore.plugin, 0, 1);
|
||||||
|
Bukkit.getScheduler().runTaskLater(MMOCore.plugin, this::close, (long) (duration * 20));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void close() {
|
||||||
|
cancel();
|
||||||
|
EntityDamageEvent.getHandlerList().unregister(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOW)
|
||||||
|
public void a(EntityDamageEvent event) {
|
||||||
|
if (!data.isOnline()) return;
|
||||||
|
if (event.getEntity().equals(data.getPlayer()))
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
|
public void b(PlayerAttackEvent event) {
|
||||||
|
if (event.getAttack().getDamage().hasType(DamageType.WEAPON) && !event.isCancelled() && PlayerData.get(event.getData().getUniqueId()).equals(data))
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (!data.isOnline() || data.getPlayer().isDead())
|
||||||
|
close();
|
||||||
|
else
|
||||||
|
data.getPlayer().getWorld().spawnParticle(Particle.CLOUD, data.getPlayer().getLocation().add(0, 1, 0), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package net.Indyuce.mmocore.skill.list;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.api.event.PlayerAttackEvent;
|
||||||
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
|
import net.Indyuce.mmocore.skill.PassiveSkill;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class Fire_Berserker extends PassiveSkill {
|
||||||
|
public Fire_Berserker() {
|
||||||
|
super();
|
||||||
|
setMaterial(Material.FLINT_AND_STEEL);
|
||||||
|
setLore("You deal &c{extra}% &7more damage when on fire.");
|
||||||
|
setPassive();
|
||||||
|
|
||||||
|
addModifier("extra", new LinearValue(10, 5));
|
||||||
|
// addModifier("duration", new LinearValue(10, .1));
|
||||||
|
// addModifier("cooldown", new LinearValue(30, 0));
|
||||||
|
|
||||||
|
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||||
|
public void a(PlayerAttackEvent event) {
|
||||||
|
PlayerData data = PlayerData.get(event.getData().getUniqueId());
|
||||||
|
if (event.getPlayer().getFireTicks() > 0) {
|
||||||
|
Optional<SkillInfo> skill = data.getProfess().findSkill(this);
|
||||||
|
skill.ifPresent(skillInfo -> event.getAttack().getDamage().multiply(1 + skillInfo.getModifier("extra", data.getSkillLevel(this)) / 100));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
158
src/main/java/net/Indyuce/mmocore/skill/list/Fire_Rage.java
Normal file
158
src/main/java/net/Indyuce/mmocore/skill/list/Fire_Rage.java
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
package net.Indyuce.mmocore.skill.list;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.MythicLib;
|
||||||
|
import io.lumine.mythic.lib.api.player.EquipmentSlot;
|
||||||
|
import io.lumine.mythic.lib.api.stat.StatMap;
|
||||||
|
import io.lumine.mythic.lib.damage.DamageType;
|
||||||
|
import io.lumine.mythic.lib.version.VersionMaterial;
|
||||||
|
import io.lumine.mythic.lib.version.VersionSound;
|
||||||
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
|
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.VectorRotation;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
|
import net.Indyuce.mmocore.skill.CasterMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.Skill;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.SkillMetadata;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Particle;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
import org.bukkit.potion.PotionEffectType;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
public class Fire_Rage extends Skill {
|
||||||
|
public Fire_Rage() {
|
||||||
|
super();
|
||||||
|
setMaterial(VersionMaterial.FIRE_CHARGE.toMaterial());
|
||||||
|
setLore("For {duration} seconds, you slow down and are able", "to cast up to {count} fireballs by left clicking.", "", "Fireballs deal &c{damage} &7damage upon contact", "and ignite your target for &c{ignite} &7seconds.", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}");
|
||||||
|
|
||||||
|
addModifier("duration", new LinearValue(8, 0));
|
||||||
|
addModifier("count", new LinearValue(4, 0));
|
||||||
|
addModifier("mana", new LinearValue(15, 1));
|
||||||
|
addModifier("damage", new LinearValue(5, 3));
|
||||||
|
addModifier("ignite", new LinearValue(2, .1));
|
||||||
|
addModifier("cooldown", new LinearValue(9, -.1, 1, 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) {
|
||||||
|
SkillMetadata cast = new SkillMetadata(caster, skill);
|
||||||
|
if (!cast.isSuccessful())
|
||||||
|
return cast;
|
||||||
|
|
||||||
|
new Rage(caster, cast);
|
||||||
|
return cast;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Rage extends BukkitRunnable implements Listener {
|
||||||
|
private final CasterMetadata caster;
|
||||||
|
private final StatMap.CachedStatMap cachedStats;
|
||||||
|
private final int count, ignite;
|
||||||
|
private final double damage;
|
||||||
|
|
||||||
|
private int c;
|
||||||
|
private double b;
|
||||||
|
private long last = System.currentTimeMillis();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* time the player needs to wait before firing two fireballs.
|
||||||
|
*/
|
||||||
|
private static final long timeOut = 700;
|
||||||
|
|
||||||
|
public Rage(CasterMetadata caster, SkillMetadata cast) {
|
||||||
|
this.caster = caster;
|
||||||
|
this.cachedStats = caster.getPlayerData().getMMOPlayerData().getStatMap().cache(EquipmentSlot.MAIN_HAND);
|
||||||
|
this.ignite = (int) (20 * cast.getModifier("ignite"));
|
||||||
|
this.damage = cast.getModifier("damage");
|
||||||
|
c = count = (int) cast.getModifier("count");
|
||||||
|
|
||||||
|
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
||||||
|
Bukkit.getScheduler().runTaskLater(MMOCore.plugin, this::close, (long) (cast.getModifier("duration") * 20));
|
||||||
|
runTaskTimer(MMOCore.plugin, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void a(PlayerInteractEvent event) {
|
||||||
|
if (event.getPlayer().equals(caster.getPlayer()) && event.getAction().name().contains("LEFT_CLICK") && (System.currentTimeMillis() - last) > timeOut) {
|
||||||
|
last = System.currentTimeMillis();
|
||||||
|
castEffect();
|
||||||
|
fireball(c < 2);
|
||||||
|
if (c-- < 2)
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void castEffect() {
|
||||||
|
VectorRotation rotation = new VectorRotation(caster.getPlayer().getEyeLocation());
|
||||||
|
for (double a = 0; a < Math.PI * 2; a += Math.PI / 13) {
|
||||||
|
Vector vec = rotation.rotate(new Vector(Math.cos(a), Math.sin(a), 0)).add(caster.getPlayer().getEyeLocation().getDirection().multiply(.5)).multiply(.3);
|
||||||
|
caster.getPlayer().getWorld().spawnParticle(Particle.FLAME, caster.getPlayer().getLocation().add(0, 1.3, 0).add(caster.getPlayer().getEyeLocation().getDirection().multiply(.5)), 0, vec.getX(), vec.getY(), vec.getZ(), .3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void close() {
|
||||||
|
if (isCancelled())
|
||||||
|
return;
|
||||||
|
|
||||||
|
cancel();
|
||||||
|
HandlerList.unregisterAll(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fireball(boolean last) {
|
||||||
|
if (last) {
|
||||||
|
caster.getPlayer().removePotionEffect(PotionEffectType.SLOW);
|
||||||
|
caster.getPlayer().removePotionEffect(PotionEffectType.SLOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
caster.getPlayer().getWorld().playSound(caster.getPlayer().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 1, last ? 0 : 1);
|
||||||
|
new BukkitRunnable() {
|
||||||
|
int j = 0;
|
||||||
|
final Vector vec = caster.getPlayer().getEyeLocation().getDirection();
|
||||||
|
final Location loc = caster.getPlayer().getLocation().add(0, 1.3, 0);
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
if (j++ > 40)
|
||||||
|
cancel();
|
||||||
|
|
||||||
|
loc.add(vec);
|
||||||
|
|
||||||
|
if (j % 2 == 0)
|
||||||
|
loc.getWorld().playSound(loc, Sound.BLOCK_FIRE_AMBIENT, 2, 1);
|
||||||
|
loc.getWorld().spawnParticle(Particle.FLAME, loc, 4, .1, .1, .1, 0);
|
||||||
|
loc.getWorld().spawnParticle(Particle.LAVA, loc, 0);
|
||||||
|
|
||||||
|
for (Entity target : MMOCoreUtils.getNearbyChunkEntities(loc))
|
||||||
|
if (MythicLib.plugin.getVersion().getWrapper().isInBoundingBox(target, loc) && MMOCoreUtils.canTarget(caster.getPlayerData(), target)) {
|
||||||
|
loc.getWorld().spawnParticle(Particle.LAVA, loc, 8);
|
||||||
|
loc.getWorld().spawnParticle(Particle.FLAME, loc, 32, 0, 0, 0, .1);
|
||||||
|
loc.getWorld().playSound(loc, Sound.ENTITY_BLAZE_HURT, 2, 1);
|
||||||
|
target.setFireTicks(target.getFireTicks() + ignite);
|
||||||
|
caster.attack((LivingEntity) target, damage, DamageType.SKILL, DamageType.PROJECTILE, DamageType.MAGIC);
|
||||||
|
cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.runTaskTimer(MMOCore.plugin, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (caster.getPlayer().isDead() || !caster.getPlayer().isOnline()) {
|
||||||
|
close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
b += Math.PI / 30;
|
||||||
|
for (int j = 0; j < c; j++) {
|
||||||
|
double a = Math.PI * 2 * j / count + b;
|
||||||
|
caster.getPlayer().spawnParticle(Particle.FLAME, caster.getPlayer().getLocation().add(Math.cos(a) * 1.5, 1 + Math.sin(a * 1.5) * .7, Math.sin(a) * 1.5), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package net.Indyuce.mmocore.skill;
|
package net.Indyuce.mmocore.skill.list;
|
||||||
|
|
||||||
|
import net.Indyuce.mmocore.skill.CasterMetadata;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Particle;
|
import org.bukkit.Particle;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
@ -10,14 +11,14 @@ import org.bukkit.util.Vector;
|
|||||||
|
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.skill.Skill;
|
import net.Indyuce.mmocore.skill.Skill;
|
||||||
import net.Indyuce.mmocore.api.skill.SkillResult;
|
import net.Indyuce.mmocore.skill.metadata.SkillMetadata;
|
||||||
import net.Indyuce.mmocore.api.skill.result.TargetSkillResult;
|
import net.Indyuce.mmocore.skill.metadata.TargetSkillMetadata;
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
import net.Indyuce.mmocore.api.util.math.particle.ParabolicProjectile;
|
import net.Indyuce.mmocore.api.util.math.particle.ParabolicProjectile;
|
||||||
import io.lumine.mythic.lib.MythicLib;
|
import io.lumine.mythic.lib.MythicLib;
|
||||||
import io.lumine.mythic.lib.api.AttackResult;
|
import io.lumine.mythic.lib.api.AttackResult;
|
||||||
import io.lumine.mythic.lib.api.DamageType;
|
import io.lumine.mythic.lib.damage.DamageType;;
|
||||||
import io.lumine.mythic.lib.version.VersionSound;
|
import io.lumine.mythic.lib.version.VersionSound;
|
||||||
|
|
||||||
public class Fire_Storm extends Skill {
|
public class Fire_Storm extends Skill {
|
||||||
@ -33,34 +34,34 @@ public class Fire_Storm extends Skill {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SkillResult whenCast(PlayerData data, SkillInfo skill) {
|
public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) {
|
||||||
TargetSkillResult cast = new TargetSkillResult(data, skill, 20);
|
TargetSkillMetadata cast = new TargetSkillMetadata(caster, skill, 20);
|
||||||
if (!cast.isSuccessful() || !data.isOnline())
|
if (!cast.isSuccessful() )
|
||||||
return cast;
|
return cast;
|
||||||
|
|
||||||
LivingEntity target = cast.getTarget();
|
LivingEntity target = cast.getTarget();
|
||||||
|
|
||||||
double damage = cast.getModifier("damage");
|
final double damage = cast.getModifier("damage");
|
||||||
int ignite = (int) (20 * cast.getModifier("ignite"));
|
final int ignite = (int) (20 * cast.getModifier("ignite"));
|
||||||
|
|
||||||
data.getPlayer().getWorld().playSound(data.getPlayer().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 1, 1);
|
caster.getPlayer().getWorld().playSound(caster.getPlayer().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 1, 1);
|
||||||
new BukkitRunnable() {
|
new BukkitRunnable() {
|
||||||
int j = 0;
|
int j = 0;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (j++ > 5 || data.getPlayer().isDead() || !data.getPlayer().isOnline() || target.isDead() || !data.getPlayer().getWorld().equals(target.getWorld())) {
|
if (j++ > 5 || caster.getPlayer().isDead() || !caster.getPlayer().isOnline() || target.isDead() || !caster.getPlayer().getWorld().equals(target.getWorld())) {
|
||||||
cancel();
|
cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO dynamic target location
|
// TODO dynamic target location
|
||||||
|
|
||||||
data.getPlayer().getWorld().playSound(data.getPlayer().getLocation(), Sound.BLOCK_FIRE_AMBIENT, 1, 1);
|
caster.getPlayer().getWorld().playSound(caster.getPlayer().getLocation(), Sound.BLOCK_FIRE_AMBIENT, 1, 1);
|
||||||
new ParabolicProjectile(data.getPlayer().getLocation().add(0, 1, 0), target.getLocation().add(0, target.getHeight() / 2, 0), randomVector(data.getPlayer()), () -> {
|
new ParabolicProjectile(caster.getPlayer().getLocation().add(0, 1, 0), target.getLocation().add(0, target.getHeight() / 2, 0), randomVector(caster.getPlayer()), () -> {
|
||||||
target.getWorld().playSound(target.getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_TWINKLE.toSound(), 1, 2);
|
target.getWorld().playSound(target.getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_TWINKLE.toSound(), 1, 2);
|
||||||
target.getWorld().spawnParticle(Particle.SMOKE_NORMAL, target.getLocation().add(0, target.getHeight() / 2, 0), 8, 0, 0, 0, .15);
|
target.getWorld().spawnParticle(Particle.SMOKE_NORMAL, target.getLocation().add(0, target.getHeight() / 2, 0), 8, 0, 0, 0, .15);
|
||||||
MythicLib.plugin.getDamage().damage(data.getPlayer(), target, new AttackResult(damage, DamageType.SKILL, DamageType.PROJECTILE, DamageType.MAGIC));
|
caster.attack(target, damage, DamageType.SKILL, DamageType.PROJECTILE, DamageType.MAGIC);
|
||||||
target.setFireTicks(ignite);
|
target.setFireTicks(ignite);
|
||||||
|
|
||||||
}, 2, Particle.FLAME);
|
}, 2, Particle.FLAME);
|
104
src/main/java/net/Indyuce/mmocore/skill/list/Fireball.java
Normal file
104
src/main/java/net/Indyuce/mmocore/skill/list/Fireball.java
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
package net.Indyuce.mmocore.skill.list;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.MythicLib;
|
||||||
|
import io.lumine.mythic.lib.api.MMORayTraceResult;
|
||||||
|
import io.lumine.mythic.lib.damage.DamageType;
|
||||||
|
import io.lumine.mythic.lib.version.VersionMaterial;
|
||||||
|
import io.lumine.mythic.lib.version.VersionSound;
|
||||||
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
|
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
|
import net.Indyuce.mmocore.skill.CasterMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.Skill;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.SkillMetadata;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Particle;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
public class Fireball extends Skill {
|
||||||
|
public Fireball() {
|
||||||
|
super();
|
||||||
|
setMaterial(VersionMaterial.FIRE_CHARGE.toMaterial());
|
||||||
|
setLore("Casts a deadly fireball onto your", "target, dealing &c{damage} &7damage upon contact", "and igniting it for &c{ignite} &7seconds.", "", "Shatters into 3 blazing hot shards which stick", "to walls and explode 3 seconds later, dealing", "&c{ratio}% &7of the initial spell damage.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}");
|
||||||
|
|
||||||
|
addModifier("mana", new LinearValue(15, 1));
|
||||||
|
addModifier("damage", new LinearValue(5, 3));
|
||||||
|
addModifier("ignite", new LinearValue(2, .1));
|
||||||
|
addModifier("ratio", new LinearValue(50, 3));
|
||||||
|
addModifier("cooldown", new LinearValue(9, -.1, 1, 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) {
|
||||||
|
SkillMetadata cast = new SkillMetadata(caster, skill);
|
||||||
|
if (!cast.isSuccessful())
|
||||||
|
return cast;
|
||||||
|
|
||||||
|
caster.getPlayer().getWorld().playSound(caster.getPlayer().getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 1, 1);
|
||||||
|
new BukkitRunnable() {
|
||||||
|
int j = 0;
|
||||||
|
final Vector vec = caster.getPlayer().getEyeLocation().getDirection();
|
||||||
|
final Location loc = caster.getPlayer().getLocation().add(0, 1.3, 0);
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
if (j++ > 40) {
|
||||||
|
cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
loc.add(vec);
|
||||||
|
|
||||||
|
if (j % 3 == 0)
|
||||||
|
loc.getWorld().playSound(loc, Sound.BLOCK_FIRE_AMBIENT, 2, 1);
|
||||||
|
loc.getWorld().spawnParticle(Particle.FLAME, loc, 4, .02, .02, .02, 0);
|
||||||
|
loc.getWorld().spawnParticle(Particle.LAVA, loc, 0);
|
||||||
|
|
||||||
|
for (Entity target : MMOCoreUtils.getNearbyChunkEntities(loc))
|
||||||
|
if (MythicLib.plugin.getVersion().getWrapper().isInBoundingBox(target, loc) && MMOCoreUtils.canTarget(caster.getPlayerData(), target)) {
|
||||||
|
loc.getWorld().spawnParticle(Particle.LAVA, loc, 8);
|
||||||
|
loc.getWorld().spawnParticle(Particle.FLAME, loc, 32, 0, 0, 0, .1);
|
||||||
|
loc.getWorld().playSound(loc, Sound.ENTITY_BLAZE_HURT, 2, 1);
|
||||||
|
target.setFireTicks((int) (target.getFireTicks() + cast.getModifier("ignite") * 20));
|
||||||
|
double damage = cast.getModifier("damage");
|
||||||
|
caster.attack((LivingEntity) target, damage, DamageType.SKILL, DamageType.PROJECTILE, DamageType.MAGIC);
|
||||||
|
|
||||||
|
new BukkitRunnable() {
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (i++ > 2) {
|
||||||
|
cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
double range = 2.5 * (1 + random.nextDouble());
|
||||||
|
Vector dir = randomDirection();
|
||||||
|
loc.getWorld().playSound(loc, Sound.ENTITY_BLAZE_HURT, 2, 1.5f);
|
||||||
|
|
||||||
|
MMORayTraceResult result = MythicLib.plugin.getVersion().getWrapper().rayTrace(loc, dir, range, entity -> MMOCoreUtils.canTarget(caster.getPlayerData(), entity));
|
||||||
|
if (result.hasHit())
|
||||||
|
caster.attack(result.getHit(), damage, DamageType.SKILL, DamageType.PROJECTILE, DamageType.MAGIC);
|
||||||
|
result.draw(loc.clone(), dir, 8, tick -> tick.getWorld().spawnParticle(Particle.FLAME, tick, 0));
|
||||||
|
|
||||||
|
}
|
||||||
|
}.runTaskTimer(MMOCore.plugin, 3, 3);
|
||||||
|
|
||||||
|
cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.runTaskTimer(MMOCore.plugin, 0, 1);
|
||||||
|
return cast;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Vector randomDirection() {
|
||||||
|
double x = random.nextDouble() - .5, y = (random.nextDouble() - .2) / 2, z = random.nextDouble() - .5;
|
||||||
|
Vector dir = new Vector(x, y, z);
|
||||||
|
return dir.lengthSquared() == 0 ? new Vector(1, 0, 0) : dir.normalize();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
package net.Indyuce.mmocore.skill.list;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.damage.DamageType;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect;
|
||||||
|
import net.Indyuce.mmocore.skill.CasterMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.Skill;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.SkillMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.TargetSkillMetadata;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Particle;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
|
||||||
|
public class Furtive_Strike extends Skill {
|
||||||
|
public Furtive_Strike() {
|
||||||
|
super();
|
||||||
|
setMaterial(Material.COAL);
|
||||||
|
setLore("Deals &c{damage} &7damage, increased by &c{extra}% &7if", "there are not any enemies within &c{radius} &7blocks.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}");
|
||||||
|
|
||||||
|
addModifier("cooldown", new LinearValue(20, -.1, 5, 20));
|
||||||
|
addModifier("mana", new LinearValue(8, 3));
|
||||||
|
addModifier("damage", new LinearValue(5, 1.5));
|
||||||
|
addModifier("extra", new LinearValue(50, 20));
|
||||||
|
addModifier("radius", new LinearValue(7, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) {
|
||||||
|
TargetSkillMetadata cast = new TargetSkillMetadata(caster, skill, 3);
|
||||||
|
if (!cast.isSuccessful())
|
||||||
|
return cast;
|
||||||
|
|
||||||
|
LivingEntity target = cast.getTarget();
|
||||||
|
target.getWorld().playSound(target.getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 2, 1.5f);
|
||||||
|
target.getWorld().spawnParticle(Particle.CRIT, target.getLocation().add(0, target.getHeight() / 2, 0), 32, 0, 0, 0, .5);
|
||||||
|
target.getWorld().spawnParticle(Particle.SMOKE_NORMAL, target.getLocation().add(0, target.getHeight() / 2, 0), 64, 0, 0, 0, .08);
|
||||||
|
|
||||||
|
double damage = cast.getModifier("damage");
|
||||||
|
|
||||||
|
double radius = cast.getModifier("radius");
|
||||||
|
if (target.getNearbyEntities(radius, radius, radius).stream().allMatch(entity -> entity.equals(caster.getPlayer()))) {
|
||||||
|
new SmallParticleEffect(target, Particle.SPELL_WITCH);
|
||||||
|
damage *= 1 + cast.getModifier("extra") / 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
caster.attack(target, damage, DamageType.SKILL, DamageType.PHYSICAL);
|
||||||
|
return cast;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package net.Indyuce.mmocore.skill.list;
|
||||||
|
|
||||||
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect;
|
||||||
|
import net.Indyuce.mmocore.skill.CasterMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.Skill;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.SkillMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.TargetSkillMetadata;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Particle;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.attribute.Attribute;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
|
||||||
|
public class Greater_Healings extends Skill {
|
||||||
|
public Greater_Healings() {
|
||||||
|
super();
|
||||||
|
setMaterial(Material.GOLDEN_APPLE);
|
||||||
|
setLore("Instantly grants &a{heal} &7HP to the", "target. Sneak to cast it on yourself.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}");
|
||||||
|
|
||||||
|
addModifier("mana", new LinearValue(4, 2));
|
||||||
|
addModifier("heal", new LinearValue(10, 4));
|
||||||
|
addModifier("cooldown", new LinearValue(9, -.1, 1, 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) {
|
||||||
|
SkillMetadata cast = caster.getPlayer().isSneaking() ? new SkillMetadata(caster, skill) : new TargetSkillMetadata(caster, skill, 50, true);
|
||||||
|
if (!cast.isSuccessful())
|
||||||
|
return cast;
|
||||||
|
|
||||||
|
LivingEntity target = cast instanceof TargetSkillMetadata ? ((TargetSkillMetadata) cast).getTarget() : caster.getPlayer();
|
||||||
|
|
||||||
|
double max = target.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
|
||||||
|
target.setHealth(Math.min(max, target.getHealth() + cast.getModifier("heal")));
|
||||||
|
|
||||||
|
new SmallParticleEffect(target, Particle.HEART, 1);
|
||||||
|
target.getWorld().playSound(target.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 2, 2);
|
||||||
|
return cast;
|
||||||
|
}
|
||||||
|
}
|
105
src/main/java/net/Indyuce/mmocore/skill/list/Human_Shield.java
Normal file
105
src/main/java/net/Indyuce/mmocore/skill/list/Human_Shield.java
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
package net.Indyuce.mmocore.skill.list;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.version.VersionMaterial;
|
||||||
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
|
import net.Indyuce.mmocore.skill.CasterMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.Skill;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.SkillMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.TargetSkillMetadata;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Particle;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.attribute.Attribute;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.entity.EntityDamageEvent;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
|
||||||
|
public class Human_Shield extends Skill {
|
||||||
|
public Human_Shield() {
|
||||||
|
super();
|
||||||
|
setMaterial(VersionMaterial.TOTEM_OF_UNDYING.toMaterial());
|
||||||
|
setLore("Casts a protection charm onto target ally,", "reducing damage taken by &a{reduction}%&7.", "&a{redirect}% &7of this damage is redirected to you.", "Charm is cancelled when reaching &c{low}%&7 health.", "Lasts &a{duration} &7seconds.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}");
|
||||||
|
|
||||||
|
addModifier("cooldown", new LinearValue(18, -.3, 14, 18));
|
||||||
|
addModifier("mana", new LinearValue(15, 1.5));
|
||||||
|
addModifier("reduction", new LinearValue(30, 3, 30, 70));
|
||||||
|
addModifier("redirect", new LinearValue(30, -2, 20, 30));
|
||||||
|
addModifier("duration", new LinearValue(7, 0));
|
||||||
|
addModifier("low", new LinearValue(10, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) {
|
||||||
|
TargetSkillMetadata cast = new TargetSkillMetadata(caster, skill, 7, true);
|
||||||
|
if (!cast.isSuccessful())
|
||||||
|
return cast;
|
||||||
|
|
||||||
|
if (!(cast.getTarget() instanceof Player)) {
|
||||||
|
cast.abort();
|
||||||
|
return cast;
|
||||||
|
}
|
||||||
|
|
||||||
|
caster.getPlayer().getWorld().playSound(caster.getPlayer().getLocation(), Sound.ENTITY_BLAZE_AMBIENT, 1, 1);
|
||||||
|
new HumanShield(caster.getPlayerData(), (Player) cast.getTarget(), cast.getModifier("reduction"), cast.getModifier("redirect"), cast.getModifier("duration"), cast.getModifier("low"));
|
||||||
|
return cast;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class HumanShield extends BukkitRunnable implements Listener {
|
||||||
|
private final PlayerData data;
|
||||||
|
private final Player target;
|
||||||
|
private final double r, rd, d, l;
|
||||||
|
|
||||||
|
private int j;
|
||||||
|
|
||||||
|
public HumanShield(PlayerData data, Player target, double reduction, double redirect, double duration, double low) {
|
||||||
|
this.target = target;
|
||||||
|
this.data = data;
|
||||||
|
|
||||||
|
r = 1 - Math.min(1, reduction / 100);
|
||||||
|
rd = redirect / 100;
|
||||||
|
d = duration * 20;
|
||||||
|
l = low / 100;
|
||||||
|
|
||||||
|
runTaskTimer(MMOCore.plugin, 0, 1);
|
||||||
|
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void a(EntityDamageEvent event) {
|
||||||
|
if (event.getEntity().equals(target)) {
|
||||||
|
|
||||||
|
double damage = event.getDamage() * r;
|
||||||
|
event.setDamage(damage);
|
||||||
|
|
||||||
|
double health = data.getPlayer().getHealth() - damage * rd;
|
||||||
|
if (health > data.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue() * l)
|
||||||
|
data.getPlayer().setHealth(health);
|
||||||
|
else {
|
||||||
|
data.getPlayer().setHealth(1);
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (!data.isOnline() || data.getPlayer().isDead() || !target.isOnline() || target.isDead() || j++ >= d) {
|
||||||
|
close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
double a = (double) j / 5;
|
||||||
|
target.getWorld().spawnParticle(Particle.VILLAGER_HAPPY, target.getLocation().add(Math.cos(a), 1 + Math.sin(a / 3) / 1.3, Math.sin(a)), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void close() {
|
||||||
|
cancel();
|
||||||
|
HandlerList.unregisterAll(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
79
src/main/java/net/Indyuce/mmocore/skill/list/Ice_Spikes.java
Normal file
79
src/main/java/net/Indyuce/mmocore/skill/list/Ice_Spikes.java
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
package net.Indyuce.mmocore.skill.list;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.damage.DamageType;
|
||||||
|
import io.lumine.mythic.lib.version.VersionMaterial;
|
||||||
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
|
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.Line3D;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
|
import net.Indyuce.mmocore.skill.CasterMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.Skill;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.LocationSkillMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.SkillMetadata;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Particle;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
import org.bukkit.potion.PotionEffect;
|
||||||
|
import org.bukkit.potion.PotionEffectType;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
public class Ice_Spikes extends Skill {
|
||||||
|
private static final double radius = 3;
|
||||||
|
|
||||||
|
public Ice_Spikes() {
|
||||||
|
super();
|
||||||
|
setMaterial(VersionMaterial.SNOWBALL.toMaterial());
|
||||||
|
setLore("Ice spikes summon from the ground", "and shatter, each dealing &9{damage} &7damage", "to hit enemies and slowing them down", "for &9{slow} &7seconds.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}");
|
||||||
|
|
||||||
|
addModifier("cooldown", new LinearValue(6, -.1, 2, 6));
|
||||||
|
addModifier("mana", new LinearValue(20, 2));
|
||||||
|
addModifier("damage", new LinearValue(3, 1));
|
||||||
|
addModifier("slow", new LinearValue(4, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) {
|
||||||
|
LocationSkillMetadata cast = new LocationSkillMetadata(caster, skill, 20);
|
||||||
|
if (!cast.isSuccessful())
|
||||||
|
return cast;
|
||||||
|
|
||||||
|
Location loc = cast.getHit();
|
||||||
|
double damage = cast.getModifier("damage");
|
||||||
|
int slow = (int) (20 * cast.getModifier("slow"));
|
||||||
|
|
||||||
|
new BukkitRunnable() {
|
||||||
|
int j = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
|
||||||
|
if (j++ > 8) {
|
||||||
|
cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Location loc1 = loc.clone().add(offset() * radius, 0, offset() * radius).add(0, 2, 0);
|
||||||
|
loc.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, loc1, 32, 0, 2, 0, 0);
|
||||||
|
loc.getWorld().spawnParticle(Particle.SNOWBALL, loc1, 32, 0, 2, 0, 0);
|
||||||
|
loc.getWorld().playSound(loc1, Sound.BLOCK_GLASS_BREAK, 2, 0);
|
||||||
|
|
||||||
|
Line3D line = new Line3D(loc.toVector(), loc.toVector().add(new Vector(0, 1, 0)));
|
||||||
|
for (Entity entity : MMOCoreUtils.getNearbyChunkEntities(loc1))
|
||||||
|
if (line.distanceSquared(entity.getLocation().toVector()) < radius && Math.abs(entity.getLocation().getY() - loc1.getY()) < 10 && MMOCoreUtils.canTarget(caster.getPlayerData(), entity)) {
|
||||||
|
caster.attack((LivingEntity) entity, damage, DamageType.SKILL, DamageType.MAGIC);
|
||||||
|
((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, slow, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.runTaskTimer(MMOCore.plugin, 0, 5);
|
||||||
|
return cast;
|
||||||
|
}
|
||||||
|
|
||||||
|
private double offset() {
|
||||||
|
return random.nextDouble() * (random.nextBoolean() ? 1 : -1);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package net.Indyuce.mmocore.skill.list;
|
||||||
|
|
||||||
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect;
|
||||||
|
import net.Indyuce.mmocore.skill.CasterMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.Skill;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.SkillMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.TargetSkillMetadata;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Particle;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.attribute.Attribute;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
|
||||||
|
public class Minor_Healings extends Skill {
|
||||||
|
public Minor_Healings() {
|
||||||
|
super();
|
||||||
|
setMaterial(Material.GOLDEN_APPLE);
|
||||||
|
setLore("Instantly grants &a{heal} &7HP to the", "target. Sneak to cast it on yourself.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}");
|
||||||
|
|
||||||
|
addModifier("mana", new LinearValue(4, 2));
|
||||||
|
addModifier("heal", new LinearValue(4, 2));
|
||||||
|
addModifier("cooldown", new LinearValue(9, -.1, 1, 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) {
|
||||||
|
SkillMetadata cast = caster.getPlayer().isSneaking() ? new SkillMetadata(caster, skill) : new TargetSkillMetadata(caster, skill, 50, true);
|
||||||
|
if (!cast.isSuccessful())
|
||||||
|
return cast;
|
||||||
|
|
||||||
|
LivingEntity target = cast instanceof TargetSkillMetadata ? ((TargetSkillMetadata) cast).getTarget() : caster.getPlayer();
|
||||||
|
|
||||||
|
double max = target.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
|
||||||
|
target.setHealth(Math.min(max, target.getHealth() + cast.getModifier("heal")));
|
||||||
|
|
||||||
|
new SmallParticleEffect(target, Particle.HEART, 1);
|
||||||
|
target.getWorld().playSound(target.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 2, 2);
|
||||||
|
return cast;
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,8 @@
|
|||||||
package net.Indyuce.mmocore.skill;
|
package net.Indyuce.mmocore.skill.list;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import net.Indyuce.mmocore.skill.PassiveSkill;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
@ -10,11 +11,11 @@ import org.bukkit.event.Listener;
|
|||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent;
|
import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.skill.Skill;
|
import net.Indyuce.mmocore.skill.Skill;
|
||||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
import io.lumine.mythic.lib.version.VersionMaterial;
|
import io.lumine.mythic.lib.version.VersionMaterial;
|
||||||
|
|
||||||
public class Neptune_Gift extends Skill implements Listener {
|
public class Neptune_Gift extends PassiveSkill {
|
||||||
public Neptune_Gift() {
|
public Neptune_Gift() {
|
||||||
super("NEPTUNE_GIFT");
|
super("NEPTUNE_GIFT");
|
||||||
setName("Neptune's Gift");
|
setName("Neptune's Gift");
|
134
src/main/java/net/Indyuce/mmocore/skill/list/Power_Mark.java
Normal file
134
src/main/java/net/Indyuce/mmocore/skill/list/Power_Mark.java
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
package net.Indyuce.mmocore.skill.list;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.api.event.PlayerAttackEvent;
|
||||||
|
import io.lumine.mythic.lib.damage.DamageType;
|
||||||
|
import io.lumine.mythic.lib.version.VersionMaterial;
|
||||||
|
import io.lumine.mythic.lib.version.VersionSound;
|
||||||
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.particle.ParabolicProjectile;
|
||||||
|
import net.Indyuce.mmocore.skill.CasterMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.PassiveSkill;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.SkillMetadata;
|
||||||
|
import org.bukkit.*;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.potion.PotionEffect;
|
||||||
|
import org.bukkit.potion.PotionEffectType;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
public class Power_Mark extends PassiveSkill {
|
||||||
|
public Power_Mark() {
|
||||||
|
super();
|
||||||
|
setMaterial(VersionMaterial.WITHER_SKELETON_SKULL.toMaterial());
|
||||||
|
setLore("Attacking an enemy applies a deadly", "magical mark which spreads accross the", "ground. This mark accumulates &6{ratio}%", "of the damage dealt to the initial", "target over &6{duration} &7seconds.", "", "After this duration, the mark bursts, dealing", "accumulated damage to nearby enemies and", "stunning them for &6{stun}+ &7seconds.", "", "The more damage, the longer the stun.", "", "&e{cooldown}s Cooldown");
|
||||||
|
setPassive();
|
||||||
|
|
||||||
|
addModifier("stun", new LinearValue(.4, .03));
|
||||||
|
addModifier("ratio", new LinearValue(10, 5));
|
||||||
|
addModifier("duration", new LinearValue(10, .1));
|
||||||
|
addModifier("cooldown", new LinearValue(30, 0));
|
||||||
|
|
||||||
|
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void a(PlayerAttackEvent event) {
|
||||||
|
PlayerData data = PlayerData.get(event.getData().getUniqueId());
|
||||||
|
if (!event.getAttack().getDamage().hasType(DamageType.WEAPON) || !data.getProfess().hasSkill(this))
|
||||||
|
return;
|
||||||
|
|
||||||
|
SkillMetadata cast = data.cast(this);
|
||||||
|
if (!cast.isSuccessful())
|
||||||
|
return;
|
||||||
|
|
||||||
|
new PowerMark(new CasterMetadata(data), cast, event.getEntity().getLocation());
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PowerMark extends BukkitRunnable implements Listener {
|
||||||
|
private final CasterMetadata caster;
|
||||||
|
private final Location loc;
|
||||||
|
|
||||||
|
private final double duration;
|
||||||
|
private final double ratio;
|
||||||
|
private double stun;
|
||||||
|
|
||||||
|
private double accumulate;
|
||||||
|
private int j;
|
||||||
|
|
||||||
|
public PowerMark(CasterMetadata caster, SkillMetadata cast, Location loc) {
|
||||||
|
this.caster = caster;
|
||||||
|
this.loc = loc;
|
||||||
|
|
||||||
|
loc.getWorld().playSound(loc, Sound.BLOCK_END_PORTAL_FRAME_FILL, 2, 1);
|
||||||
|
|
||||||
|
duration = cast.getModifier("duration");
|
||||||
|
ratio = cast.getModifier("ratio") / 100;
|
||||||
|
stun = cast.getModifier("stun");
|
||||||
|
|
||||||
|
runTaskTimer(MMOCore.plugin, 0, 1);
|
||||||
|
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void unregister() {
|
||||||
|
PlayerAttackEvent.getHandlerList().unregister(this);
|
||||||
|
cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
|
public void stackDamage(PlayerAttackEvent event) {
|
||||||
|
if (!event.isCancelled() && j < 20 * (duration - 2) && radiusCheck(event.getEntity().getLocation()) && event.getPlayer().equals(caster.getPlayer())) {
|
||||||
|
accumulate += event.getAttack().getDamage().getDamage() * ratio;
|
||||||
|
new ParabolicProjectile(event.getEntity().getLocation().add(0, event.getEntity().getHeight() / 2, 0), loc, () -> loc.getWorld().playSound(loc, Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1), Color.PURPLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean radiusCheck(Location loc) {
|
||||||
|
return loc.getWorld().equals(this.loc.getWorld()) && loc.distanceSquared(this.loc) < 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (j++ > duration * 20) {
|
||||||
|
unregister();
|
||||||
|
|
||||||
|
for (double a = 0; a < Math.PI * 2; a += Math.PI * 2 / 17)
|
||||||
|
new ParabolicProjectile(loc, loc.clone().add(6 * Math.cos(a), 0, 6 * Math.sin(a)), Particle.SPELL_WITCH);
|
||||||
|
|
||||||
|
loc.getWorld().playSound(loc, Sound.ENTITY_GENERIC_EXPLODE, 2, 0);
|
||||||
|
loc.getWorld().spawnParticle(Particle.EXPLOSION_LARGE, loc.clone().add(0, 1, 0), 16, 2, 2, 2, 0);
|
||||||
|
loc.getWorld().spawnParticle(Particle.EXPLOSION_NORMAL, loc.clone().add(0, 1, 0), 24, 0, 0, 0, .3f);
|
||||||
|
|
||||||
|
stun += Math.log(Math.max(1, accumulate - 10)) / 8;
|
||||||
|
|
||||||
|
for (Entity entity : MMOCoreUtils.getNearbyChunkEntities(loc))
|
||||||
|
if (entity.getLocation().distanceSquared(loc) < 25 && MMOCoreUtils.canTarget(caster.getPlayerData(), entity)) {
|
||||||
|
((LivingEntity) entity).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, (int) (stun * 20), 10, false, false));
|
||||||
|
caster.attack((LivingEntity) entity, accumulate, DamageType.SKILL, DamageType.MAGIC);
|
||||||
|
entity.setVelocity(format(entity.getLocation().subtract(loc).toVector().setY(0)).setY(.3));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j % 2 == 0 && j > 20 * (duration - 2))
|
||||||
|
loc.getWorld().playSound(loc, VersionSound.BLOCK_NOTE_BLOCK_PLING.toSound(), 1, (float) (1 + (j - 20 * (duration - 2)) / 40));
|
||||||
|
|
||||||
|
double a = (double) j / 16;
|
||||||
|
double r = Math.sqrt(Math.min(duration * 2 - (double) j / 10, 4)) * 2;
|
||||||
|
for (double k = 0; k < Math.PI * 2; k += Math.PI * 2 / 5)
|
||||||
|
loc.getWorld().spawnParticle(Particle.SPELL_WITCH, loc.clone().add(r * Math.cos(k + a), 0, r * Math.sin(k + a)), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Vector format(Vector vec) {
|
||||||
|
return vec.length() < .01 ? new Vector(0, 0, 0) : vec.normalize();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package net.Indyuce.mmocore.skill.list;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.api.event.PlayerAttackEvent;
|
||||||
|
import io.lumine.mythic.lib.damage.DamageType;
|
||||||
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
|
import net.Indyuce.mmocore.skill.PassiveSkill;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.SkillMetadata;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Particle;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
|
||||||
|
public class Sneaky_Picky extends PassiveSkill {
|
||||||
|
public Sneaky_Picky() {
|
||||||
|
super();
|
||||||
|
setMaterial(Material.DIAMOND_SWORD);
|
||||||
|
setLore("Your attack is empowered by &f{extra}% &7when", "delivering the first blow during a fight.", "", "&9Costs {mana} {mana_name}");
|
||||||
|
setPassive();
|
||||||
|
|
||||||
|
addModifier("cooldown", new LinearValue(0, 0));
|
||||||
|
addModifier("mana", new LinearValue(8, 1));
|
||||||
|
addModifier("extra", new LinearValue(50, 20));
|
||||||
|
|
||||||
|
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void a(PlayerAttackEvent event) {
|
||||||
|
PlayerData data = PlayerData.get(event.getData().getUniqueId());
|
||||||
|
if (!event.getAttack().getDamage().hasType(DamageType.WEAPON) || data.isInCombat() || !data.getProfess().hasSkill(this))
|
||||||
|
return;
|
||||||
|
|
||||||
|
SkillMetadata cast = data.cast(this);
|
||||||
|
if (!cast.isSuccessful())
|
||||||
|
return;
|
||||||
|
|
||||||
|
data.cast(cast.getInfo());
|
||||||
|
|
||||||
|
event.getAttack().getDamage().multiply(1 + cast.getModifier("extra") / 100, DamageType.WEAPON);
|
||||||
|
LivingEntity target = event.getEntity();
|
||||||
|
target.getWorld().spawnParticle(Particle.SMOKE_NORMAL, target.getLocation().add(0, target.getHeight() / 2, 0), 64, 0, 0, 0, .05);
|
||||||
|
target.getWorld().playSound(target.getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 1, 2);
|
||||||
|
}
|
||||||
|
}
|
98
src/main/java/net/Indyuce/mmocore/skill/list/Telekinesy.java
Normal file
98
src/main/java/net/Indyuce/mmocore/skill/list/Telekinesy.java
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
package net.Indyuce.mmocore.skill.list;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.version.VersionMaterial;
|
||||||
|
import io.lumine.mythic.lib.version.VersionSound;
|
||||||
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.particle.ParabolicProjectile;
|
||||||
|
import net.Indyuce.mmocore.skill.CasterMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.Skill;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.SkillMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.TargetSkillMetadata;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Particle;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
|
||||||
|
public class Telekinesy extends Skill {
|
||||||
|
public Telekinesy() {
|
||||||
|
super();
|
||||||
|
setMaterial(VersionMaterial.MAGENTA_DYE.toMaterial());
|
||||||
|
setLore("You take the control over your target", "for &9{duration} &7seconds. Left click to throw him.", "Knockback force: &f{knockback}%", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}");
|
||||||
|
|
||||||
|
addModifier("cooldown", new LinearValue(20, -.3, 10, 20));
|
||||||
|
addModifier("mana", new LinearValue(20, 2));
|
||||||
|
addModifier("knockback", new LinearValue(50, 10));
|
||||||
|
addModifier("duration", new LinearValue(3, .1, 3, 6));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) {
|
||||||
|
TargetSkillMetadata cast = new TargetSkillMetadata(caster, skill, 7);
|
||||||
|
if (!cast.isSuccessful())
|
||||||
|
return cast;
|
||||||
|
|
||||||
|
caster.getPlayer().getWorld().playSound(caster.getPlayer().getLocation(), Sound.BLOCK_END_PORTAL_FRAME_FILL, 1, 1);
|
||||||
|
new TelekinesyRunnable(caster.getPlayerData(), cast.getTarget(), cast.getModifier("duration"), cast.getModifier("knockback") / 100);
|
||||||
|
return cast;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TelekinesyRunnable extends BukkitRunnable implements Listener {
|
||||||
|
private final Entity entity;
|
||||||
|
private final PlayerData data;
|
||||||
|
|
||||||
|
private final long duration;
|
||||||
|
private final double d, f;
|
||||||
|
|
||||||
|
private int j;
|
||||||
|
|
||||||
|
public TelekinesyRunnable(PlayerData data, Entity entity, double duration, double force) {
|
||||||
|
this.entity = entity;
|
||||||
|
this.data = data;
|
||||||
|
|
||||||
|
d = data.getPlayer().getLocation().distance(entity.getLocation());
|
||||||
|
f = force;
|
||||||
|
this.duration = (long) (20 * duration);
|
||||||
|
|
||||||
|
runTaskTimer(MMOCore.plugin, 0, 1);
|
||||||
|
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void a(PlayerInteractEvent event) {
|
||||||
|
if (event.getPlayer().equals(data.getPlayer()) && event.getAction().name().contains("LEFT_CLICK")) {
|
||||||
|
entity.setVelocity(data.getPlayer().getEyeLocation().getDirection().multiply(1.5 * f));
|
||||||
|
entity.getWorld().playSound(entity.getLocation(), VersionSound.ENTITY_FIREWORK_ROCKET_BLAST.toSound(), 2, 1);
|
||||||
|
entity.getWorld().spawnParticle(Particle.SPELL_WITCH, entity.getLocation().add(0, entity.getHeight() / 2, 0), 16);
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (!data.isOnline() || entity.isDead() || j++ >= duration) {
|
||||||
|
close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j % 8 == 0)
|
||||||
|
new ParabolicProjectile(data.getPlayer().getEyeLocation(), entity.getLocation().add(0, entity.getHeight() / 2, 0), Particle.SPELL_WITCH);
|
||||||
|
|
||||||
|
Location loc = data.getPlayer().getEyeLocation().add(data.getPlayer().getEyeLocation().getDirection().multiply(d));
|
||||||
|
entity.setVelocity(loc.subtract(entity.getLocation().add(0, entity.getHeight() / 2, 0)).toVector().multiply(2));
|
||||||
|
entity.setFallDistance(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void close() {
|
||||||
|
cancel();
|
||||||
|
HandlerList.unregisterAll(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
59
src/main/java/net/Indyuce/mmocore/skill/list/Warp.java
Normal file
59
src/main/java/net/Indyuce/mmocore/skill/list/Warp.java
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
package net.Indyuce.mmocore.skill.list;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.version.VersionSound;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.particle.ParabolicProjectile;
|
||||||
|
import net.Indyuce.mmocore.skill.CasterMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.Skill;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.SkillMetadata;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Particle;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
|
||||||
|
public class Warp extends Skill {
|
||||||
|
public Warp() {
|
||||||
|
super();
|
||||||
|
setMaterial(Material.ENDER_PEARL);
|
||||||
|
setLore("Teleports you to target location.", "Max. Range: &5{range}", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}");
|
||||||
|
|
||||||
|
addModifier("cooldown", new LinearValue(15, -.3, 2, 15));
|
||||||
|
addModifier("mana", new LinearValue(8, 3));
|
||||||
|
addModifier("range", new LinearValue(16, 1, 0, 100));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) {
|
||||||
|
WarpSkillMetadata cast = new WarpSkillMetadata(caster, skill);
|
||||||
|
if (!cast.isSuccessful())
|
||||||
|
return cast;
|
||||||
|
|
||||||
|
caster.getPlayer().getWorld().playSound(caster.getPlayer().getLocation(), Sound.BLOCK_END_PORTAL_FRAME_FILL, 1, 2);
|
||||||
|
|
||||||
|
Location loc = cast.block.getLocation().add(0, 1, 0);
|
||||||
|
loc.setYaw(caster.getPlayer().getLocation().getYaw());
|
||||||
|
loc.setPitch(caster.getPlayer().getLocation().getPitch());
|
||||||
|
|
||||||
|
new ParabolicProjectile(caster.getPlayer().getLocation().add(0, 1, 0), loc.clone().add(0, 1, 0), () -> {
|
||||||
|
if (caster.getPlayer().isOnline() && !caster.getPlayer().isDead()) {
|
||||||
|
caster.getPlayer().teleport(loc);
|
||||||
|
caster.getPlayer().getWorld().spawnParticle(Particle.EXPLOSION_LARGE, caster.getPlayer().getLocation().add(0, 1, 0), 0);
|
||||||
|
caster.getPlayer().getWorld().spawnParticle(Particle.SPELL_INSTANT, caster.getPlayer().getLocation().add(0, 1, 0), 32, 0, 0, 0, .1);
|
||||||
|
caster.getPlayer().getWorld().playSound(caster.getPlayer().getLocation(), VersionSound.ENTITY_ENDERMAN_TELEPORT.toSound(), 1, 1);
|
||||||
|
}
|
||||||
|
}, 2, Particle.SPELL_INSTANT);
|
||||||
|
return cast;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class WarpSkillMetadata extends SkillMetadata {
|
||||||
|
private Block block;
|
||||||
|
|
||||||
|
public WarpSkillMetadata(CasterMetadata caster, SkillInfo skill) {
|
||||||
|
super(caster, skill);
|
||||||
|
|
||||||
|
if (isSuccessful() && (block = caster.getPlayer().getTargetBlock(null, (int) getModifier("range"))) == null)
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
76
src/main/java/net/Indyuce/mmocore/skill/list/Weaken.java
Normal file
76
src/main/java/net/Indyuce/mmocore/skill/list/Weaken.java
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
package net.Indyuce.mmocore.skill.list;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.version.VersionMaterial;
|
||||||
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.particle.ParabolicProjectile;
|
||||||
|
import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect;
|
||||||
|
import net.Indyuce.mmocore.skill.CasterMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.Skill;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.SkillMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.metadata.TargetSkillMetadata;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Particle;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
public class Weaken extends Skill {
|
||||||
|
public Weaken() {
|
||||||
|
super();
|
||||||
|
setMaterial(VersionMaterial.MAGENTA_DYE.toMaterial());
|
||||||
|
setLore("The target is weakened for", "&8{duration} &7seconds and is dealt", "&7extra &8{ratio}% &7damage.", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}");
|
||||||
|
|
||||||
|
addModifier("cooldown", new LinearValue(20, -.1, 5, 20));
|
||||||
|
addModifier("mana", new LinearValue(4, 1));
|
||||||
|
addModifier("ratio", new LinearValue(30, 3));
|
||||||
|
addModifier("duration", new LinearValue(10, -.1, 5, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SkillMetadata whenCast(CasterMetadata caster, SkillInfo skill) {
|
||||||
|
TargetSkillMetadata cast = new TargetSkillMetadata(caster, skill, 7);
|
||||||
|
if (!cast.isSuccessful())
|
||||||
|
return cast;
|
||||||
|
|
||||||
|
LivingEntity target = cast.getTarget();
|
||||||
|
new ParabolicProjectile(caster.getPlayer().getLocation().add(0, 1, 0), target.getLocation().add(0, target.getHeight() / 2, 0), randomVector(caster.getPlayer()), () -> {
|
||||||
|
if (!target.isDead())
|
||||||
|
new Weakened(target, cast.getModifier("ratio"), cast.getModifier("duration"));
|
||||||
|
}, 2, Particle.SPELL_WITCH);
|
||||||
|
return cast;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Vector randomVector(Player player) {
|
||||||
|
double a = Math.toRadians(player.getEyeLocation().getYaw() + 90);
|
||||||
|
a += (random.nextBoolean() ? 1 : -1) * (random.nextDouble() + .5) * Math.PI / 6;
|
||||||
|
return new Vector(Math.cos(a), .8, Math.sin(a)).normalize().multiply(.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Weakened implements Listener {
|
||||||
|
private final Entity entity;
|
||||||
|
private final double c;
|
||||||
|
|
||||||
|
public Weakened(Entity entity, double ratio, double duration) {
|
||||||
|
this.entity = entity;
|
||||||
|
this.c = 1 + ratio / 100;
|
||||||
|
|
||||||
|
new SmallParticleEffect(entity, Particle.SPELL_WITCH);
|
||||||
|
|
||||||
|
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
||||||
|
Bukkit.getScheduler().scheduleSyncDelayedTask(MMOCore.plugin, () -> EntityDamageByEntityEvent.getHandlerList().unregister(this), (int) duration * 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void a(EntityDamageByEntityEvent event) {
|
||||||
|
if (event.getEntity().equals(entity)) {
|
||||||
|
event.getEntity().getWorld().spawnParticle(Particle.SPELL_WITCH, entity.getLocation().add(0, entity.getHeight() / 2, 0), 16, .5, .5, .5, 0);
|
||||||
|
event.setDamage(event.getDamage() * c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package net.Indyuce.mmocore.skill.metadata;
|
||||||
|
|
||||||
|
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||||
|
import net.Indyuce.mmocore.skill.CasterMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.Skill.SkillInfo;
|
||||||
|
import org.bukkit.FluidCollisionMode;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.util.RayTraceResult;
|
||||||
|
|
||||||
|
public class LocationSkillMetadata extends SkillMetadata {
|
||||||
|
private Location loc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param caster Player casting the skill
|
||||||
|
* @param skill Skill being cast
|
||||||
|
* @param range Skill raycast range
|
||||||
|
*/
|
||||||
|
public LocationSkillMetadata(CasterMetadata caster, SkillInfo skill, double range) {
|
||||||
|
this(caster, skill, range, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param caster Player casting the skill
|
||||||
|
* @param skill Skill being cast
|
||||||
|
* @param range Skill raycast range
|
||||||
|
* @param buff If the skill is a buff ie if it can be cast on party members
|
||||||
|
*/
|
||||||
|
public LocationSkillMetadata(CasterMetadata caster, SkillInfo skill, double range, boolean buff) {
|
||||||
|
super(caster, skill);
|
||||||
|
|
||||||
|
if (isSuccessful()) {
|
||||||
|
|
||||||
|
RayTraceResult result = caster.getPlayer().getWorld().rayTrace(caster.getPlayer().getEyeLocation(),
|
||||||
|
caster.getPlayer().getEyeLocation().getDirection(), range, FluidCollisionMode.ALWAYS, true, 1.0D,
|
||||||
|
entity -> MMOCoreUtils.canTarget(caster.getPlayerData(), entity, buff));
|
||||||
|
if (result == null)
|
||||||
|
abort(CancelReason.OTHER);
|
||||||
|
else
|
||||||
|
loc = result.getHitBlock() != null ? result.getHitBlock().getLocation()
|
||||||
|
: result.getHitEntity() != null ? result.getHitEntity().getLocation() : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasHit() {
|
||||||
|
return loc != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Location getHit() {
|
||||||
|
return loc;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,123 @@
|
|||||||
|
package net.Indyuce.mmocore.skill.metadata;
|
||||||
|
|
||||||
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
import net.Indyuce.mmocore.comp.flags.FlagPlugin.CustomFlag;
|
||||||
|
import net.Indyuce.mmocore.skill.CasterMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.Skill;
|
||||||
|
import net.Indyuce.mmocore.skill.Skill.SkillInfo;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class SkillMetadata {
|
||||||
|
private final SkillInfo skill;
|
||||||
|
private final int level;
|
||||||
|
private final double mana, cooldown, stamina;
|
||||||
|
|
||||||
|
private CancelReason cancelReason;
|
||||||
|
|
||||||
|
public SkillMetadata(CasterMetadata caster, SkillInfo skill) {
|
||||||
|
this.skill = skill;
|
||||||
|
|
||||||
|
PlayerData data = caster.getPlayerData();
|
||||||
|
|
||||||
|
level = data.getSkillLevel(skill.getSkill());
|
||||||
|
cooldown = (skill.getSkill().hasModifier("cooldown") ? data.getSkillData().getCooldown(skill) : 0);
|
||||||
|
mana = (skill.getSkill().hasModifier("mana") ? skill.getModifier("mana", level) : 0);
|
||||||
|
stamina = (skill.getSkill().hasModifier("stamina") ? skill.getModifier("stamina", level) : 0);
|
||||||
|
cancelReason = !data.hasSkillUnlocked(skill) ? CancelReason.LOCKED
|
||||||
|
: cooldown > 0 ? CancelReason.COOLDOWN
|
||||||
|
: mana > data.getMana() ? CancelReason.MANA
|
||||||
|
: stamina > data.getStamina() ? CancelReason.STAMINA
|
||||||
|
: !data.isOnline() ? CancelReason.OTHER
|
||||||
|
: !MMOCore.plugin.flagPlugin.isFlagAllowed(data.getPlayer(), CustomFlag.SKILLS) ? CancelReason.FLAG
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SkillMetadata(PlayerData data, SkillInfo skill, CancelReason reason) {
|
||||||
|
this.skill = skill;
|
||||||
|
this.cancelReason = reason;
|
||||||
|
|
||||||
|
level = data.getSkillLevel(skill.getSkill());
|
||||||
|
cooldown = skill.getSkill().hasModifier("cooldown") ? data.getSkillData().getCooldown(skill) : 0;
|
||||||
|
mana = skill.getSkill().hasModifier("mana") ? skill.getModifier("mana", level) : 0;
|
||||||
|
stamina = (skill.getSkill().hasModifier("stamina") ? skill.getModifier("stamina", level) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Skill getSkill() {
|
||||||
|
return skill.getSkill();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SkillInfo getInfo() {
|
||||||
|
return skill;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLevel() {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getStaminaCost() {
|
||||||
|
return stamina;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getManaCost() {
|
||||||
|
return mana;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getCooldown() {
|
||||||
|
return cooldown;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSuccessful() {
|
||||||
|
return cancelReason == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CancelReason getCancelReason() {
|
||||||
|
return cancelReason;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void abort() {
|
||||||
|
abort(CancelReason.OTHER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void abort(CancelReason reason) {
|
||||||
|
cancelReason = Objects.requireNonNull(reason, "Reason cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getModifier(String modifier) {
|
||||||
|
return skill.getModifier(modifier, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum CancelReason {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag plugin like WorldGuard or any other
|
||||||
|
*/
|
||||||
|
FLAG,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Not enough stamina
|
||||||
|
*/
|
||||||
|
MANA,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Not enough mana
|
||||||
|
*/
|
||||||
|
STAMINA,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skill still on cooldown
|
||||||
|
*/
|
||||||
|
COOLDOWN,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skill is locked
|
||||||
|
*/
|
||||||
|
LOCKED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Anything else
|
||||||
|
*/
|
||||||
|
OTHER;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package net.Indyuce.mmocore.skill.metadata;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.MythicLib;
|
||||||
|
import io.lumine.mythic.lib.api.MMORayTraceResult;
|
||||||
|
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||||
|
import net.Indyuce.mmocore.skill.CasterMetadata;
|
||||||
|
import net.Indyuce.mmocore.skill.Skill.SkillInfo;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
|
||||||
|
public class TargetSkillMetadata extends SkillMetadata {
|
||||||
|
private LivingEntity target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param caster Player casting the skill
|
||||||
|
* @param skill Skill being cast
|
||||||
|
* @param range Skill raycast range
|
||||||
|
*/
|
||||||
|
public TargetSkillMetadata(CasterMetadata caster, SkillInfo skill, double range) {
|
||||||
|
this(caster, skill, range, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param caster Player casting the skill
|
||||||
|
* @param skill Skill being cast
|
||||||
|
* @param range Skill raycast range
|
||||||
|
* @param buff If the skill is a buff ie if it can be cast on party members
|
||||||
|
*/
|
||||||
|
public TargetSkillMetadata(CasterMetadata caster, SkillInfo skill, double range, boolean buff) {
|
||||||
|
super(caster, skill);
|
||||||
|
|
||||||
|
if (isSuccessful()) {
|
||||||
|
MMORayTraceResult result = MythicLib.plugin.getVersion().getWrapper().rayTrace(caster.getPlayer(), range, entity -> MMOCoreUtils.canTarget(caster.getPlayerData(), entity, buff));
|
||||||
|
if (!result.hasHit())
|
||||||
|
abort();
|
||||||
|
else
|
||||||
|
target = result.getHit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public LivingEntity getTarget() {
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
}
|
@ -45,14 +45,14 @@ default-playerdata:
|
|||||||
# The list of all conditions which must be met for the
|
# The list of all conditions which must be met for the
|
||||||
# BLOCK REGEN and BLOCK RESTRICTIONS to apply. Set to
|
# BLOCK REGEN and BLOCK RESTRICTIONS to apply. Set to
|
||||||
# 'custom-mine-conditions: []' to disable custom mining entirely.
|
# 'custom-mine-conditions: []' to disable custom mining entirely.
|
||||||
custom-mine-conditions:
|
|
||||||
- 'world{name="world,world_nether,world_the_end"}'
|
|
||||||
- 'region{name="example_region,example_region2,__global__"}'
|
|
||||||
#
|
#
|
||||||
# custom-mine-conditions:
|
# custom-mine-conditions:
|
||||||
# - 'world{name="__global__"}'
|
# - 'world{name="__global__"}'
|
||||||
#
|
#
|
||||||
# ^ will enable custom mining server wide
|
# ^ will enable custom mining server wide
|
||||||
|
custom-mine-conditions:
|
||||||
|
- 'world{name="world,world_nether,world_the_end"}'
|
||||||
|
- 'region{name="example_region,example_region2,__global__"}'
|
||||||
|
|
||||||
# Set to true to prevent vanilla blocks from being
|
# Set to true to prevent vanilla blocks from being
|
||||||
# broken when custom mining conditions are met
|
# broken when custom mining conditions are met
|
||||||
@ -121,6 +121,9 @@ vanilla-exp-redirection:
|
|||||||
# Requires a SERVER reload when changed.
|
# Requires a SERVER reload when changed.
|
||||||
override-vanilla-exp: true
|
override-vanilla-exp: true
|
||||||
|
|
||||||
|
# Check the target player's RPG profile when shift when shift right clicking.
|
||||||
|
shift-click-player-profile-check: true
|
||||||
|
|
||||||
# If main class experience holograms should be displayed
|
# If main class experience holograms should be displayed
|
||||||
# whenever a player earns main class exp
|
# whenever a player earns main class exp
|
||||||
display-main-class-exp-holograms: true
|
display-main-class-exp-holograms: true
|
||||||
|
Loading…
Reference in New Issue
Block a user