diff --git a/pom.xml b/pom.xml
index 36dae57e..112be0c7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -32,7 +32,7 @@
strife
- 3.4.1
+ 3.4.2
jar
strife
diff --git a/src/main/java/land/face/strife/commands/InspectCommand.java b/src/main/java/land/face/strife/commands/InspectCommand.java
index 19eee3ae..a714e736 100644
--- a/src/main/java/land/face/strife/commands/InspectCommand.java
+++ b/src/main/java/land/face/strife/commands/InspectCommand.java
@@ -38,7 +38,7 @@ public InspectCommand(StrifePlugin plugin) {
@Default
public void baseCommand(Player sender) {
- plugin.getChampionManager().updateEquipmentStats(sender);
+ plugin.getStrifeMobManager().updateEquipmentStats(plugin.getStrifeMobManager().getStatMob(sender));
plugin.getChampionManager().update(sender);
plugin.getStatUpdateManager().updateVanillaAttributes(sender);
plugin.getStatsMenu().getInspectionTargetMap().put(sender, sender);
diff --git a/src/main/java/land/face/strife/commands/StrifeCommand.java b/src/main/java/land/face/strife/commands/StrifeCommand.java
index d7725cdb..f5db430a 100644
--- a/src/main/java/land/face/strife/commands/StrifeCommand.java
+++ b/src/main/java/land/face/strife/commands/StrifeCommand.java
@@ -321,8 +321,8 @@ public void bindCommand(CommandSender sender, OnlinePlayer target, String loreAb
sendMessage(sender, "Invalid loreAbility ID: " + loreAbilityId);
return;
}
- Champion champion = plugin.getChampionManager().getChampion(target.getPlayer());
- boolean success = plugin.getChampionManager().addBoundLoreAbility(champion, ability);
+ StrifeMob mob = plugin.getStrifeMobManager().getStatMob(target.getPlayer());
+ boolean success = plugin.getChampionManager().addBoundLoreAbility(mob, ability);
if (success) {
sendMessage(sender,
"&aBound loreAbility " + loreAbilityId + " to player " + target.getPlayer().getName());
@@ -341,8 +341,8 @@ public void unbindCommand(CommandSender sender, OnlinePlayer target, String lore
sendMessage(sender, "Invalid loreAbility ID: " + loreAbilityId);
return;
}
- Champion champion = plugin.getChampionManager().getChampion(target.getPlayer());
- boolean success = plugin.getChampionManager().removeBoundLoreAbility(champion, ability);
+ StrifeMob mob = plugin.getStrifeMobManager().getStatMob(target.getPlayer());
+ boolean success = plugin.getChampionManager().removeBoundLoreAbility(mob, ability);
if (success) {
sendMessage(sender,
"&aUnbound loreAbility " + loreAbilityId + " to player " + target.getPlayer().getName());
diff --git a/src/main/java/land/face/strife/data/DamageModifiers.java b/src/main/java/land/face/strife/data/DamageModifiers.java
index a3d65ebe..0a2c2691 100644
--- a/src/main/java/land/face/strife/data/DamageModifiers.java
+++ b/src/main/java/land/face/strife/data/DamageModifiers.java
@@ -166,6 +166,7 @@ public enum ElementalStatus {
FREEZE,
SHOCK,
CORRUPT,
+ CRUNCH
}
}
diff --git a/src/main/java/land/face/strife/data/Spawner.java b/src/main/java/land/face/strife/data/Spawner.java
index e9598932..1f6184a2 100644
--- a/src/main/java/land/face/strife/data/Spawner.java
+++ b/src/main/java/land/face/strife/data/Spawner.java
@@ -57,7 +57,7 @@ public Spawner(String id, UniqueEntity uniqueEntity, String uniqueId, int amount
this.leashRange = leashRange;
chunkKey = location.getChunk().getChunkKey();
- runTaskTimer(StrifePlugin.getInstance(), SPAWNER_OFFSET, 40L);
+ runTaskTimer(StrifePlugin.getInstance(), SPAWNER_OFFSET % 20, 40L);
SPAWNER_OFFSET++;
LogUtil.printDebug("Created Spawner with taskId " + getTaskId());
}
diff --git a/src/main/java/land/face/strife/data/StrifeMob.java b/src/main/java/land/face/strife/data/StrifeMob.java
index dadf6e54..9ea02641 100644
--- a/src/main/java/land/face/strife/data/StrifeMob.java
+++ b/src/main/java/land/face/strife/data/StrifeMob.java
@@ -14,7 +14,9 @@
import land.face.strife.data.ability.EntityAbilitySet;
import land.face.strife.data.buff.Buff;
import land.face.strife.data.champion.Champion;
+import land.face.strife.data.champion.EquipmentCache;
import land.face.strife.data.effects.FiniteUsesEffect;
+import land.face.strife.managers.LoreAbilityManager.TriggerType;
import land.face.strife.managers.StatUpdateManager;
import land.face.strife.stats.StrifeStat;
import land.face.strife.stats.StrifeTrait;
@@ -33,6 +35,7 @@ public class StrifeMob {
private final static int CACHE_DELAY = 100;
+ private final EquipmentCache equipmentCache = new EquipmentCache();
private final Map baseStats = new HashMap<>();
private final Map statCache = new HashMap<>();
@@ -56,11 +59,13 @@ public class StrifeMob {
private float maxBarrier = 0;
private boolean shielded;
+ private boolean useEquipment;
+
private CombatCountdownTask combatCountdownTask = null;
- private final BarrierTask barrierTask = new BarrierTask(this);
- private final LifeTask lifeTask = new LifeTask(this);
- private final EnergyTask energyTask = new EnergyTask(this);
+ private BarrierTask barrierTask = new BarrierTask(this);
+ private LifeTask lifeTask = new LifeTask(this);
+ private EnergyTask energyTask = new EnergyTask(this);
private MinionTask minionTask = null;
private final Set minions = new HashSet<>();
@@ -70,11 +75,13 @@ public class StrifeMob {
public StrifeMob(Champion champion) {
this.livingEntity = new WeakReference<>(champion.getPlayer());
this.champion = new WeakReference<>(champion);
+ useEquipment = true;
}
public StrifeMob(LivingEntity livingEntity) {
this.livingEntity = new WeakReference<>(livingEntity);
this.champion = new WeakReference<>(null);
+ useEquipment = livingEntity instanceof Player;
}
public float getBarrier() {
@@ -218,6 +225,14 @@ public EntityAbilitySet getAbilitySet() {
return abilitySet;
}
+ public boolean isUseEquipment() {
+ return useEquipment;
+ }
+
+ public void setUseEquipment(boolean useEquipment) {
+ this.useEquipment = useEquipment;
+ }
+
public void setAbilitySet(EntityAbilitySet abilitySet) {
this.abilitySet = abilitySet;
}
@@ -258,7 +273,7 @@ public Map getFinalStats() {
if (getChampion() != null) {
return StatUpdateManager.combineMaps(getChampion().getCombinedCache(), getBuffStats());
}
- return StatUpdateManager.combineMaps(baseStats, getBuffStats());
+ return StatUpdateManager.combineMaps(baseStats, getBuffStats(), equipmentCache.getCombinedStats());
}
public Map getBaseStats() {
@@ -347,11 +362,28 @@ public boolean isMasterOf(LivingEntity entity) {
return false;
}
- public boolean hasTrait(StrifeTrait trait) {
- if (getChampion() == null) {
- return false;
+ public EquipmentCache getEquipmentCache() {
+ return equipmentCache;
+ }
+
+ public Map> getLoreAbilities() {
+ return equipmentCache.getCombinedAbilities();
+ }
+
+ public Set getTraits() {
+ Set traits = new HashSet<>(equipmentCache.getCombinedTraits());
+ if (champion.get() == null) {
+ traits.addAll(Objects.requireNonNull(champion.get()).getPathTraits());
+ }
+ return traits;
+ }
+
+ public boolean hasTrait (StrifeTrait trait) {
+ if (champion.get() == null) {
+ return equipmentCache.getCombinedTraits().contains(trait);
}
- return Objects.requireNonNull(champion.get()).hasTrait(trait);
+ return equipmentCache.getCombinedTraits().contains(trait) ||
+ Objects.requireNonNull(champion.get()).getPathTraits().contains(trait);
}
public void removeMinion(StrifeMob minion) {
@@ -400,6 +432,39 @@ public void setCharmImmune(boolean charmImmune) {
this.charmImmune = charmImmune;
}
+ public void minionDeath() {
+ if (minionTask == null) {
+ return;
+ }
+ minionTask.forceStartDeath();
+ }
+
+ public double getMinionRating() {
+ if (minionTask == null) {
+ // Arbitrary High Number
+ return 10000000;
+ }
+ if (minionTask.getLifespan() < 1) {
+ return 0;
+ }
+ return livingEntity.get().getHealth() * (1 + (double) minionTask.getLifespan() / 10D);
+ }
+
+ public void restartTimers() {
+ if (lifeTask != null && !lifeTask.isCancelled()) {
+ lifeTask.cancel();
+ }
+ lifeTask = new LifeTask(this);
+ if (barrierTask != null && !barrierTask.isCancelled()) {
+ barrierTask.cancel();
+ }
+ barrierTask = new BarrierTask(this);
+ if (energyTask != null && !energyTask.isCancelled()) {
+ energyTask.cancel();
+ }
+ energyTask = new EnergyTask(this);
+ }
+
public void bumpCombat() {
if (isInCombat()) {
combatCountdownTask.bump();
diff --git a/src/main/java/land/face/strife/data/UniqueEntity.java b/src/main/java/land/face/strife/data/UniqueEntity.java
index 32c123e7..42ebcb07 100644
--- a/src/main/java/land/face/strife/data/UniqueEntity.java
+++ b/src/main/java/land/face/strife/data/UniqueEntity.java
@@ -28,6 +28,7 @@ public class UniqueEntity {
private boolean angry;
private boolean zombificationImmune;
private boolean armsRaised;
+ private boolean hasAI;
private boolean gravity;
private Profession profession;
private int size;
@@ -154,6 +155,15 @@ public void setArmsRaised(boolean armsRaised) {
this.armsRaised = armsRaised;
}
+ public boolean isHasAI() {
+ return hasAI;
+ }
+
+ public void setHasAI(boolean hasAI) {
+ this.hasAI = hasAI;
+ }
+
+
public boolean isGravity() {
return gravity;
}
diff --git a/src/main/java/land/face/strife/data/buff/Buff.java b/src/main/java/land/face/strife/data/buff/Buff.java
index ae057009..da61aad1 100644
--- a/src/main/java/land/face/strife/data/buff/Buff.java
+++ b/src/main/java/land/face/strife/data/buff/Buff.java
@@ -4,7 +4,6 @@
import java.util.Map;
import java.util.UUID;
import land.face.strife.stats.StrifeStat;
-import org.bukkit.Bukkit;
public class Buff {
@@ -52,7 +51,7 @@ public long getEndingTimestamp() {
public void bumpBuff(double duration) {
setExpireTimeFromDuration(duration);
stacks = Math.min(stacks + 1, maxStacks);
- Bukkit.getLogger().warning(" Stacks: " + stacks + "/" + maxStacks);
+ //Bukkit.getLogger().warning(" Stacks: " + stacks + "/" + maxStacks);
}
public int getStacks() {
diff --git a/src/main/java/land/face/strife/data/champion/Champion.java b/src/main/java/land/face/strife/data/champion/Champion.java
index 14304c49..4d1eec7b 100644
--- a/src/main/java/land/face/strife/data/champion/Champion.java
+++ b/src/main/java/land/face/strife/data/champion/Champion.java
@@ -26,8 +26,6 @@
import java.util.UUID;
import land.face.strife.StrifePlugin;
import land.face.strife.data.CombatDetailsContainer;
-import land.face.strife.data.LoreAbility;
-import land.face.strife.managers.LoreAbilityManager.TriggerType;
import land.face.strife.managers.StatUpdateManager;
import land.face.strife.stats.StrifeStat;
import land.face.strife.stats.StrifeTrait;
@@ -35,7 +33,6 @@
public class Champion {
- private final PlayerEquipmentCache equipmentCache;
private final ChampionSaveData saveData;
private final CombatDetailsContainer detailsContainer = new CombatDetailsContainer();
@@ -62,7 +59,6 @@ public Champion(Player player, ChampionSaveData saveData) {
levelPointStats = new HashMap<>();
combinedStatMap = new HashMap<>();
pathStats = new HashMap<>();
- equipmentCache = new PlayerEquipmentCache();
pathTraits = new HashSet<>();
}
@@ -80,7 +76,6 @@ public void recombineCache() {
baseStats,
levelPointStats,
pathStats,
- equipmentCache.getCombinedStats(),
StrifePlugin.getInstance().getBoostManager().getStats()
));
}
@@ -197,10 +192,6 @@ public CombatDetailsContainer getDetailsContainer() {
return detailsContainer;
}
- public PlayerEquipmentCache getEquipmentCache() {
- return equipmentCache;
- }
-
public Map getPathStats() {
return pathStats;
}
@@ -209,21 +200,6 @@ public Set getPathTraits() {
return pathTraits;
}
- public Map> getLoreAbilities() {
- return equipmentCache.getCombinedAbilities();
- }
-
- public Set getTraits() {
- Set traits = new HashSet<>();
- traits.addAll(equipmentCache.getCombinedTraits());
- traits.addAll(pathTraits);
- return traits;
- }
-
- public boolean hasTrait (StrifeTrait trait) {
- return equipmentCache.getCombinedTraits().contains(trait) || pathTraits.contains(trait);
- }
-
public int getUnchosenPaths() {
return getHighestReachedLevel() / 10 - saveData.getPathMap().size();
}
diff --git a/src/main/java/land/face/strife/data/champion/PlayerEquipmentCache.java b/src/main/java/land/face/strife/data/champion/EquipmentCache.java
similarity index 91%
rename from src/main/java/land/face/strife/data/champion/PlayerEquipmentCache.java
rename to src/main/java/land/face/strife/data/champion/EquipmentCache.java
index fc8c57c1..aca3d4db 100644
--- a/src/main/java/land/face/strife/data/champion/PlayerEquipmentCache.java
+++ b/src/main/java/land/face/strife/data/champion/EquipmentCache.java
@@ -7,6 +7,7 @@
import java.util.Map;
import java.util.Set;
import land.face.strife.data.LoreAbility;
+import land.face.strife.data.StrifeMob;
import land.face.strife.managers.LoreAbilityManager;
import land.face.strife.managers.LoreAbilityManager.TriggerType;
import land.face.strife.managers.StatUpdateManager;
@@ -14,7 +15,7 @@
import land.face.strife.stats.StrifeTrait;
import org.bukkit.inventory.EquipmentSlot;
-public class PlayerEquipmentCache {
+public class EquipmentCache {
private final Map slotHashCodeMap = new HashMap<>();
@@ -28,7 +29,7 @@ public class PlayerEquipmentCache {
public final static EquipmentSlot[] ITEM_SLOTS = EquipmentSlot.values();
- PlayerEquipmentCache() {
+ public EquipmentCache() {
for (EquipmentSlot slot : ITEM_SLOTS) {
slotHashCodeMap.put(slot, -1);
slotStatMap.put(slot, new HashMap<>());
@@ -105,11 +106,14 @@ public void recombineStats() {
));
}
- public void recombineAbilities(Champion champion) {
+ public void recombineAbilities(StrifeMob mob) {
for (TriggerType triggerType : LoreAbilityManager.triggerTypes) {
loreAbilities.get(triggerType).clear();
}
- Set newAbilities = new HashSet<>(champion.getSaveData().getBoundAbilities());
+ Set newAbilities = new HashSet<>();
+ if (mob.getChampion() != null) {
+ newAbilities.addAll(mob.getChampion().getSaveData().getBoundAbilities());
+ }
for (EquipmentSlot slot : ITEM_SLOTS) {
newAbilities.addAll(slotAbilityMap.get(slot));
}
@@ -125,9 +129,9 @@ public void recombineTraits() {
}
}
- public void recombine(Champion champion) {
+ public void recombine(StrifeMob mob) {
recombineStats();
- recombineAbilities(champion);
+ recombineAbilities(mob);
recombineTraits();
}
}
diff --git a/src/main/java/land/face/strife/data/conditions/Condition.java b/src/main/java/land/face/strife/data/conditions/Condition.java
index 3fa16b28..d3017aa9 100644
--- a/src/main/java/land/face/strife/data/conditions/Condition.java
+++ b/src/main/java/land/face/strife/data/conditions/Condition.java
@@ -103,6 +103,7 @@ public enum ConditionType {
ENDLESS_EFFECT,
BLOCKING,
MOVING,
+ MINION,
NEARBY_ENTITIES,
IN_COMBAT,
CHANCE,
diff --git a/src/main/java/land/face/strife/data/conditions/LoreCondition.java b/src/main/java/land/face/strife/data/conditions/LoreCondition.java
index f9989aae..2a0ed45f 100644
--- a/src/main/java/land/face/strife/data/conditions/LoreCondition.java
+++ b/src/main/java/land/face/strife/data/conditions/LoreCondition.java
@@ -15,7 +15,7 @@ public LoreCondition(String loreId) {
public boolean isMet(StrifeMob attacker, StrifeMob target) {
StrifeMob actualTarget = getCompareTarget() == CompareTarget.SELF ? attacker : target;
if (actualTarget.getChampion() != null) {
- for (Set las : actualTarget.getChampion().getLoreAbilities().values()) {
+ for (Set las : actualTarget.getLoreAbilities().values()) {
for (LoreAbility la : las) {
if (loreId.equals(la.getId())) {
return true;
diff --git a/src/main/java/land/face/strife/data/conditions/MinionCondition.java b/src/main/java/land/face/strife/data/conditions/MinionCondition.java
new file mode 100644
index 00000000..2f1180c8
--- /dev/null
+++ b/src/main/java/land/face/strife/data/conditions/MinionCondition.java
@@ -0,0 +1,26 @@
+package land.face.strife.data.conditions;
+
+import land.face.strife.data.StrifeMob;
+
+public class MinionCondition extends Condition {
+
+ private final boolean isOwner;
+
+ public MinionCondition(boolean isOwner) {
+ this.isOwner = isOwner;
+ }
+
+ public boolean isMet(StrifeMob attacker, StrifeMob target) {
+ if (getCompareTarget() == CompareTarget.SELF) {
+ if (isOwner) {
+ return target.getMinions().contains(attacker);
+ }
+ return attacker.getMaster() != null;
+ } else {
+ if (isOwner) {
+ return attacker.getMinions().contains(target);
+ }
+ return target.getMaster() != null;
+ }
+ }
+}
diff --git a/src/main/java/land/face/strife/data/effects/Bleed.java b/src/main/java/land/face/strife/data/effects/Bleed.java
index 1987dba5..4ba22566 100644
--- a/src/main/java/land/face/strife/data/effects/Bleed.java
+++ b/src/main/java/land/face/strife/data/effects/Bleed.java
@@ -18,9 +18,6 @@ public class Bleed extends Effect {
@Override
public void apply(StrifeMob caster, StrifeMob target) {
float bleedAmount = amount;
- for (StrifeStat attr : getStatMults().keySet()) {
- bleedAmount += getStatMults().get(attr) * caster.getStat(attr);
- }
BonusDamage container = new BonusDamage(damageScale, null, null, bleedAmount);
bleedAmount = DamageUtil.applyDamageScale(caster, target, container);
if (applyBleedMods) {
@@ -30,7 +27,7 @@ public void apply(StrifeMob caster, StrifeMob target) {
if (!ignoreArmor) {
bleedAmount *= StatUtil.getArmorMult(caster, target);
}
- DamageUtil.applyBleed(target, bleedAmount, bypassBarrier);
+ DamageUtil.applyBleed(target, applyMultipliers(caster, bleedAmount), bypassBarrier);
}
public void setDamageScale(DamageScale damageScale) {
diff --git a/src/main/java/land/face/strife/data/effects/ChangeEnergy.java b/src/main/java/land/face/strife/data/effects/ChangeEnergy.java
index 237f033e..9fe5d721 100644
--- a/src/main/java/land/face/strife/data/effects/ChangeEnergy.java
+++ b/src/main/java/land/face/strife/data/effects/ChangeEnergy.java
@@ -18,12 +18,9 @@ public void apply(StrifeMob caster, StrifeMob target) {
return;
}
float restoreAmount = amount;
- for (StrifeStat attr : getStatMults().keySet()) {
- restoreAmount += getStatMults().get(attr) * caster.getStat(attr);
- }
BonusDamage bonusDamage = new BonusDamage(damageScale, null, null, restoreAmount);
restoreAmount = DamageUtil.applyDamageScale(caster, target, bonusDamage);
- StatUtil.changeEnergy(target, restoreAmount);
+ StatUtil.changeEnergy(target, applyMultipliers(caster, restoreAmount));
}
public void setAmount(float amount) {
diff --git a/src/main/java/land/face/strife/data/effects/ChangeRage.java b/src/main/java/land/face/strife/data/effects/ChangeRage.java
index fc067cdd..7dd80d17 100644
--- a/src/main/java/land/face/strife/data/effects/ChangeRage.java
+++ b/src/main/java/land/face/strife/data/effects/ChangeRage.java
@@ -17,12 +17,9 @@ public void apply(StrifeMob caster, StrifeMob target) {
return;
}
float restoreAmount = amount;
- for (StrifeStat attr : getStatMults().keySet()) {
- restoreAmount += getStatMults().get(attr) * caster.getStat(attr);
- }
BonusDamage bonusDamage = new BonusDamage(damageScale, null, null, restoreAmount);
restoreAmount = DamageUtil.applyDamageScale(caster, target, bonusDamage);
- getPlugin().getRageManager().changeRage(target, restoreAmount);
+ getPlugin().getRageManager().changeRage(target, applyMultipliers(caster, restoreAmount));
}
public void setAmount(float amount) {
diff --git a/src/main/java/land/face/strife/data/effects/Charm.java b/src/main/java/land/face/strife/data/effects/Charm.java
index 66759114..fbceaa3d 100644
--- a/src/main/java/land/face/strife/data/effects/Charm.java
+++ b/src/main/java/land/face/strife/data/effects/Charm.java
@@ -1,9 +1,13 @@
package land.face.strife.data.effects;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
import java.util.Random;
import land.face.strife.data.StrifeMob;
import land.face.strife.stats.StrifeStat;
import land.face.strife.util.StatUtil;
+import org.bukkit.attribute.Attribute;
import org.bukkit.entity.Mob;
import org.bukkit.entity.Player;
import org.bukkit.entity.Wolf;
@@ -25,27 +29,40 @@ public void apply(StrifeMob caster, StrifeMob target) {
if (!overrideMaster && target.getMaster() != null) {
return;
}
- if (caster.getMinions().size() >= caster.getStat(StrifeStat.MAX_MINIONS)) {
+
+ if (!rollCharmChance(caster, target)) {
return;
}
+
if (target.getEntity() instanceof Wolf) {
if (((Wolf) target.getEntity()).getOwner() != null) {
return;
}
((Wolf) target.getEntity()).setAngry(true);
}
- if (!rollCharmChance(caster, target)) {
- return;
- }
((Mob) target.getEntity()).setTarget(null);
+ target.getFactions().clear();
float lifespan = lifespanSeconds * (1 + (caster.getStat(StrifeStat.EFFECT_DURATION) / 100));
-
caster.addMinion(target, (int) lifespan);
- target.getFactions().clear();
+
+ double maxHealth = target.getEntity().getMaxHealth() * (1 + (caster.getStat(StrifeStat.MINION_LIFE) / 100));
+ target.getEntity().getAttribute(Attribute.GENERIC_MAX_HEALTH).setBaseValue(maxHealth);
+ target.getEntity().setHealth(maxHealth);
getPlugin().getSpawnerManager().addRespawnTime(target.getEntity());
+
+ List minionList = new ArrayList<>(caster.getMinions());
+
+ int excessMinions = minionList.size() - (int) caster.getStat(StrifeStat.MAX_MINIONS);
+ if (excessMinions > 0) {
+ minionList.sort(Comparator.comparingDouble(StrifeMob::getMinionRating));
+ while (excessMinions > 0) {
+ minionList.get(excessMinions - 1).minionDeath();
+ excessMinions--;
+ }
+ }
}
private boolean rollCharmChance(StrifeMob caster, StrifeMob target) {
diff --git a/src/main/java/land/face/strife/data/effects/Corrupt.java b/src/main/java/land/face/strife/data/effects/Corrupt.java
index 29190c00..c18af6ad 100644
--- a/src/main/java/land/face/strife/data/effects/Corrupt.java
+++ b/src/main/java/land/face/strife/data/effects/Corrupt.java
@@ -1,7 +1,6 @@
package land.face.strife.data.effects;
import land.face.strife.data.StrifeMob;
-import land.face.strife.stats.StrifeStat;
import land.face.strife.util.DamageUtil;
public class Corrupt extends Effect {
@@ -10,11 +9,7 @@ public class Corrupt extends Effect {
@Override
public void apply(StrifeMob caster, StrifeMob target) {
- float corruptionStacks = amount;
- for (StrifeStat attr : getStatMults().keySet()) {
- corruptionStacks += getStatMults().get(attr) * caster.getStat(attr);
- }
- DamageUtil.applyCorrupt(target.getEntity(), corruptionStacks);
+ DamageUtil.applyCorrupt(target.getEntity(), applyMultipliers(caster, amount));
}
public void setAmount(float amount) {
diff --git a/src/main/java/land/face/strife/data/effects/Damage.java b/src/main/java/land/face/strife/data/effects/Damage.java
index 73079f87..3d51d8dd 100644
--- a/src/main/java/land/face/strife/data/effects/Damage.java
+++ b/src/main/java/land/face/strife/data/effects/Damage.java
@@ -12,7 +12,6 @@
import land.face.strife.data.StrifeMob;
import land.face.strife.data.TargetResponse;
import land.face.strife.events.StrifeDamageEvent;
-import land.face.strife.stats.StrifeStat;
import land.face.strife.util.DamageUtil;
import land.face.strife.util.DamageUtil.AbilityMod;
import land.face.strife.util.DamageUtil.AttackType;
@@ -38,6 +37,7 @@ public class Damage extends Effect {
private boolean applyOnHitEffects;
private boolean showPopoffs;
private boolean bypassBarrier;
+ private boolean selfInflict;
private final List hitEffects = new ArrayList<>();
private final List killEffects = new ArrayList<>();
@@ -58,6 +58,7 @@ public void apply(StrifeMob caster, StrifeMob target) {
mods.setApplyOnHitEffects(applyOnHitEffects);
mods.setShowPopoffs(showPopoffs);
mods.setBypassBarrier(bypassBarrier);
+ mods.setScaleChancesWithAttack(true);
if (canSneakAttack && caster.getEntity() instanceof Player && getPlugin().getStealthManager()
.canSneakAttack((Player) caster.getEntity())) {
mods.setSneakAttack(true);
@@ -67,19 +68,19 @@ public void apply(StrifeMob caster, StrifeMob target) {
mods.getDamageMultipliers().putAll(damageMultipliers);
mods.getAbilityMods().putAll(abilityMods);
+
boolean attackSuccess = DamageUtil.preDamage(caster, target, mods);
if (!attackSuccess) {
return;
}
-
- float statMultiplier = 1;
- for (StrifeStat s : getStatMults().keySet()) {
- statMultiplier += caster.getStat(s) * getStatMults().get(s);
- }
- mods.setAttackMultiplier(mods.getAttackMultiplier() * statMultiplier);
+ mods.setAttackMultiplier(applyMultipliers(caster, mods.getAttackMultiplier()));
Map damage = DamageUtil.buildDamage(caster, target, mods);
+ if (selfInflict) {
+ target = caster;
+ }
+ DamageUtil.applyElementalEffects(caster, target, damage, mods);
DamageUtil.reduceDamage(caster, target, damage, mods);
float finalDamage = DamageUtil.calculateFinalDamage(caster, target, damage, mods);
@@ -112,8 +113,9 @@ public void apply(StrifeMob caster, StrifeMob target) {
DamageUtil.attemptBleed(caster, target, damage.get(DamageType.PHYSICAL), mods, false);
}
+ StrifeMob finalTarget = target;
Bukkit.getScheduler().runTaskLater(StrifePlugin.getInstance(),
- () -> DamageUtil.postDamage(caster, target, mods), 0L);
+ () -> DamageUtil.postDamage(caster, finalTarget, mods), 0L);
}
public float getDamageReductionRatio() {
@@ -204,6 +206,10 @@ public void setBypassBarrier(boolean bypassBarrier) {
this.bypassBarrier = bypassBarrier;
}
+ public void setSelfInflict(boolean selfInflict) {
+ this.selfInflict = selfInflict;
+ }
+
public List getHitEffects() {
return hitEffects;
}
diff --git a/src/main/java/land/face/strife/data/effects/Effect.java b/src/main/java/land/face/strife/data/effects/Effect.java
index dd202d73..a5d79d71 100644
--- a/src/main/java/land/face/strife/data/effects/Effect.java
+++ b/src/main/java/land/face/strife/data/effects/Effect.java
@@ -6,6 +6,9 @@
import java.util.Set;
import land.face.strife.StrifePlugin;
import land.face.strife.data.StrifeMob;
+import land.face.strife.data.champion.Champion;
+import land.face.strife.data.champion.LifeSkillType;
+import land.face.strife.data.champion.StrifeAttribute;
import land.face.strife.data.conditions.Condition;
import land.face.strife.stats.StrifeStat;
@@ -18,6 +21,8 @@ public abstract class Effect {
private boolean friendly;
private final Map statMults = new HashMap<>();
+ private final Map skillMults = new HashMap<>();
+ private final Map attributeMults = new HashMap<>();
private final Set conditions = new HashSet<>();
public void apply(StrifeMob caster, StrifeMob target) {
@@ -48,15 +53,38 @@ public void setFriendly(boolean friendly) {
this.friendly = friendly;
}
- public Map getStatMults() {
- return statMults;
- }
-
public void setStatMults(Map statMults) {
this.statMults.clear();
this.statMults.putAll(statMults);
}
+ public void setSkillMults(Map skillMults) {
+ this.skillMults.clear();
+ this.skillMults.putAll(skillMults);
+ }
+
+ public void setAttributeMults(Map attributeMults) {
+ this.attributeMults.clear();
+ this.attributeMults.putAll(attributeMults);
+ }
+
+ public float applyMultipliers(StrifeMob caster, float amount) {
+ float multiplier = 1f;
+ for (StrifeStat attr : statMults.keySet()) {
+ multiplier += statMults.get(attr) * caster.getStat(attr);
+ }
+ if (caster.getChampion() != null) {
+ Champion champion = caster.getChampion();
+ for (LifeSkillType attr : skillMults.keySet()) {
+ multiplier += skillMults.get(attr) * champion.getLifeSkillLevel(attr);
+ }
+ for (StrifeAttribute attr : attributeMults.keySet()) {
+ multiplier += attributeMults.get(attr) * (float) champion.getAttributeLevel(attr);
+ }
+ }
+ return amount * multiplier;
+ }
+
public void addCondition(Condition condition) {
conditions.add(condition);
}
diff --git a/src/main/java/land/face/strife/data/effects/Food.java b/src/main/java/land/face/strife/data/effects/Food.java
index b23b3b59..0983cb16 100644
--- a/src/main/java/land/face/strife/data/effects/Food.java
+++ b/src/main/java/land/face/strife/data/effects/Food.java
@@ -1,7 +1,6 @@
package land.face.strife.data.effects;
import land.face.strife.data.StrifeMob;
-import land.face.strife.stats.StrifeStat;
import org.bukkit.entity.Player;
public class Food extends Effect {
@@ -10,13 +9,10 @@ public class Food extends Effect {
@Override
public void apply(StrifeMob caster, StrifeMob target) {
- double food = amount;
if (!(target.getEntity() instanceof Player)) {
return;
}
- for (StrifeStat attr : getStatMults().keySet()) {
- food += getStatMults().get(attr) * caster.getStat(attr);
- }
+ float food = applyMultipliers(caster, (float) amount);
((Player) target.getEntity())
.setFoodLevel((int) Math.min(20, ((Player) target.getEntity()).getFoodLevel() + food));
}
diff --git a/src/main/java/land/face/strife/data/effects/Heal.java b/src/main/java/land/face/strife/data/effects/Heal.java
index fcc5181e..3e207e2b 100644
--- a/src/main/java/land/face/strife/data/effects/Heal.java
+++ b/src/main/java/land/face/strife/data/effects/Heal.java
@@ -28,9 +28,6 @@ public void apply(StrifeMob caster, StrifeMob target) {
}
float heal = amount;
- for (StrifeStat attr : getStatMults().keySet()) {
- heal += getStatMults().get(attr) * caster.getStat(attr);
- }
BonusDamage container = new BonusDamage(damageScale, null, null, heal);
heal = DamageUtil.applyDamageScale(caster, target, container);
@@ -40,17 +37,13 @@ public void apply(StrifeMob caster, StrifeMob target) {
heal *= 1 + caster.getStat(StrifeStat.HEALING_POWER) / 100;
}
- for (StrifeStat attr : getStatMults().keySet()) {
- heal *= 1 + getStatMults().get(attr) * caster.getStat(attr);
- }
-
if (!healCaster && caster != target && caster.getEntity() instanceof Player) {
String healText = "&a&l+" + INT_FORMAT.format(heal);
StrifePlugin.getInstance().getIndicatorManager().addIndicator(caster.getEntity(),
target.getEntity(), IndicatorStyle.FLOAT_UP_SLOW, 8, healText);
}
- DamageUtil.restoreHealth(healCaster ? caster.getEntity() : target.getEntity(), heal);
+ DamageUtil.restoreHealth(healCaster ? caster.getEntity() : target.getEntity(), applyMultipliers(caster, heal));
}
public void setAmount(float amount) {
diff --git a/src/main/java/land/face/strife/data/effects/RestoreBarrier.java b/src/main/java/land/face/strife/data/effects/RestoreBarrier.java
index 2bf80d32..6f60d8e7 100644
--- a/src/main/java/land/face/strife/data/effects/RestoreBarrier.java
+++ b/src/main/java/land/face/strife/data/effects/RestoreBarrier.java
@@ -19,12 +19,9 @@ public void apply(StrifeMob caster, StrifeMob target) {
return;
}
float restoreAmount = amount;
- for (StrifeStat attr : getStatMults().keySet()) {
- restoreAmount += getStatMults().get(attr) * caster.getStat(attr);
- }
BonusDamage bonusDamage = new BonusDamage(damageScale, DamageType.TRUE_DAMAGE, null, restoreAmount);
restoreAmount = DamageUtil.applyDamageScale(caster, target, bonusDamage);
- target.restoreBarrier(restoreAmount);
+ target.restoreBarrier(applyMultipliers(caster, restoreAmount));
}
public void setAmount(float amount) {
diff --git a/src/main/java/land/face/strife/data/effects/ShootBlock.java b/src/main/java/land/face/strife/data/effects/ShootBlock.java
index ecaf4618..0252ec5f 100644
--- a/src/main/java/land/face/strife/data/effects/ShootBlock.java
+++ b/src/main/java/land/face/strife/data/effects/ShootBlock.java
@@ -42,6 +42,7 @@ public void applyAtLocation(StrifeMob caster, Location location) {
for (int i = 0; i < quantity; i++) {
FallingBlock block = location.getWorld().spawnFallingBlock(location, blockData);
+ SpecialStatusUtil.setDespawnOnUnload(block);
Vector newDirection = castDirection.clone();
applySpread(newDirection, spread);
block.setVelocity(newDirection);
diff --git a/src/main/java/land/face/strife/data/effects/ShootProjectile.java b/src/main/java/land/face/strife/data/effects/ShootProjectile.java
index d6668b50..e7e63845 100644
--- a/src/main/java/land/face/strife/data/effects/ShootProjectile.java
+++ b/src/main/java/land/face/strife/data/effects/ShootProjectile.java
@@ -135,12 +135,12 @@ public void apply(StrifeMob caster, StrifeMob target) {
if (maxDuration != -1) {
Bukkit.getScheduler().runTaskLater(getPlugin(), () -> {
- for (Effect effect : hitEffects) {
- if (effect instanceof LocationEffect) {
- ((LocationEffect) effect).applyAtLocation(caster, projectile.getLocation());
- }
- }
if (projectile.isValid()) {
+ for (Effect effect : hitEffects) {
+ if (effect instanceof LocationEffect) {
+ ((LocationEffect) effect).applyAtLocation(caster, projectile.getLocation());
+ }
+ }
projectile.remove();
}
}, maxDuration);
diff --git a/src/main/java/land/face/strife/data/effects/StrifeParticle.java b/src/main/java/land/face/strife/data/effects/StrifeParticle.java
index f02dfdbe..be5f3a5d 100644
--- a/src/main/java/land/face/strife/data/effects/StrifeParticle.java
+++ b/src/main/java/land/face/strife/data/effects/StrifeParticle.java
@@ -89,6 +89,9 @@ private void playAtLocation(StrifeMob attacker, Location location, Vector direct
case ARC:
spawnParticleArc(particleInUse, direction, location, size, arcAngle, arcOffset);
return;
+ case CLAW:
+ spawnParticleClaw(particleInUse, direction, location, size, arcAngle, arcOffset);
+ return;
case NORMAL:
default:
spawnParticle(particleInUse, location);
@@ -219,6 +222,33 @@ private void spawnParticleArc(Particle particle, Vector direction, Location cent
}
}
+ private void spawnParticleClaw(Particle particle, Vector direction, Location center,
+ double radius, double angle, double offset) {
+ int segments = (int) (6 * (angle / 90) * (1 + radius / 3));
+ double startAngle = -angle * 0.5;
+ double segmentAngle = angle / segments;
+ double verticalDirection = random.nextDouble() < 0.5 ? 1 : -1;
+ double startVerticalOffset = verticalDirection * offset * random.nextDouble() * 0.5;
+ double segmentOffset = (2 * startVerticalOffset) / segments;
+ double segmentChunk = ((double) segments) * 0.25D;
+ for (int i = 0; i <= segments; i++) {
+ Vector newDirection = direction.clone();
+ newDirection.setX(newDirection.getX() + 0.001);
+ newDirection.setY(0.001);
+ newDirection.setZ(newDirection.getZ() + 0.001);
+ newDirection.normalize().multiply(size);
+ double radialAngle = Math.toRadians(startAngle + i * segmentAngle);
+ applyRadialAngles(newDirection, radialAngle);
+ newDirection.setY(startVerticalOffset - segmentOffset * i);
+ Location newLoc = center.clone().add(newDirection);
+ spawnParticle(particle, newLoc);
+ if (i > segmentChunk && i < segments - segmentChunk) {
+ spawnParticle(particle, newLoc.add(0, 0.4, 0));
+ spawnParticle(particle, newLoc.add(0, -0.8, 0));
+ }
+ }
+ }
+
private void applyRadialAngles(Vector direction, double angle) {
double x = direction.getX();
double z = direction.getZ();
@@ -299,6 +329,7 @@ public enum ParticleStyle {
CIRCLE,
ORBIT,
LINE,
- ARC
+ ARC,
+ CLAW
}
}
diff --git a/src/main/java/land/face/strife/data/effects/Summon.java b/src/main/java/land/face/strife/data/effects/Summon.java
index 1808186e..3fbc12fd 100644
--- a/src/main/java/land/face/strife/data/effects/Summon.java
+++ b/src/main/java/land/face/strife/data/effects/Summon.java
@@ -1,7 +1,10 @@
package land.face.strife.data.effects;
-import static land.face.strife.data.champion.PlayerEquipmentCache.ITEM_SLOTS;
+import static land.face.strife.data.champion.EquipmentCache.ITEM_SLOTS;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
import land.face.strife.StrifePlugin;
import land.face.strife.data.StrifeMob;
import land.face.strife.listeners.SpawnListener;
@@ -32,78 +35,90 @@ public class Summon extends LocationEffect {
private boolean mount;
private boolean clone;
+
@Override
public void apply(StrifeMob caster, StrifeMob target) {
- for (int i = 0; i < amount; i++) {
- Location loc = target.getEntity().getLocation();
- applyAtLocation(caster, loc);
- }
+ Location loc = target.getEntity().getLocation();
+ applyAtLocation(caster, loc);
}
@Override
public void applyAtLocation(StrifeMob caster, Location location) {
- if (caster.getMinions().size() >= caster.getStat(StrifeStat.MAX_MINIONS)) {
- return;
- }
- StrifeMob summonedEntity = StrifePlugin.getInstance().getUniqueEntityManager()
- .spawnUnique(uniqueEntity, location);
+ double lifespan = lifespanSeconds * (1 + (caster.getStat(StrifeStat.EFFECT_DURATION) / 100));
- if (summonedEntity == null || summonedEntity.getEntity() == null) {
- return;
- }
+ for (int i = 0; i < amount; i++) {
+ StrifeMob summonedEntity = StrifePlugin.getInstance().getUniqueEntityManager()
+ .spawnUnique(uniqueEntity, location);
- LivingEntity summon = summonedEntity.getEntity();
- double lifespan = lifespanSeconds * (1 + (caster.getStat(StrifeStat.EFFECT_DURATION) / 100));
- caster.addMinion(summonedEntity, (int) lifespan);
-
- if (clone) {
- Disguise disguise;
- if (caster.getEntity().getType() == EntityType.PLAYER) {
- disguise = new PlayerDisguise((Player) caster.getEntity());
- ((PlayerDisguise) disguise).setName("");
- } else {
- disguise = new MobDisguise(DisguiseType.getType(caster.getEntity().getType()));
+ if (summonedEntity == null || summonedEntity.getEntity() == null) {
+ return;
}
- disguise.setReplaceSounds(true);
- disguise.setDynamicName(true);
-
- DisguiseAPI.disguiseToAll(summonedEntity.getEntity(), disguise);
-
- Bukkit.getScheduler().runTaskLater(StrifePlugin.getInstance(), () -> {
- for (EquipmentSlot slot : ITEM_SLOTS) {
- if (slot == EquipmentSlot.HAND && ItemUtil
- .isWandOrStaff(caster.getEntity().getEquipment().getItem(EquipmentSlot.HAND))) {
- summonedEntity.getEntity().getEquipment().setItem(slot, SpawnListener.SKELETON_WAND);
- } else {
- summonedEntity.getEntity().getEquipment()
- .setItem(slot, caster.getEntity().getEquipment().getItem(slot));
- }
+
+ LivingEntity summon = summonedEntity.getEntity();
+ caster.addMinion(summonedEntity, (int) lifespan);
+
+ if (clone) {
+ Disguise disguise;
+ if (caster.getEntity().getType() == EntityType.PLAYER) {
+ disguise = new PlayerDisguise((Player) caster.getEntity());
+ ((PlayerDisguise) disguise).setName("");
+ } else {
+ disguise = new MobDisguise(DisguiseType.getType(caster.getEntity().getType()));
}
- }, 2L);
- summonedEntity.setStats(caster.getBaseStats());
- }
+ disguise.setReplaceSounds(true);
+ disguise.setDynamicName(true);
+
+ DisguiseAPI.disguiseToAll(summonedEntity.getEntity(), disguise);
+
+ Bukkit.getScheduler().runTaskLater(StrifePlugin.getInstance(), () -> {
+ for (EquipmentSlot slot : ITEM_SLOTS) {
+ if (slot == EquipmentSlot.HAND && ItemUtil
+ .isWandOrStaff(caster.getEntity().getEquipment().getItem(EquipmentSlot.HAND))) {
+ summonedEntity.getEntity().getEquipment().setItem(slot, SpawnListener.SKELETON_WAND);
+ } else {
+ summonedEntity.getEntity().getEquipment()
+ .setItem(slot, caster.getEntity().getEquipment().getItem(slot));
+ }
+ }
+ }, 2L);
+ summonedEntity.setStats(caster.getBaseStats());
+ }
- if (caster.getEntity() instanceof Mob && summon instanceof Mob) {
- ((Mob) summon).setTarget(((Mob) caster.getEntity()).getTarget());
- }
+ if (caster.getEntity() instanceof Mob && summon instanceof Mob) {
+ ((Mob) summon).setTarget(((Mob) caster.getEntity()).getTarget());
+ }
- if (summon instanceof Tameable && caster.getEntity() instanceof Player) {
- ((Tameable) summon).setOwner((Player) caster.getEntity());
- }
+ if (summon instanceof Tameable && caster.getEntity() instanceof Player) {
+ ((Tameable) summon).setOwner((Player) caster.getEntity());
+ }
- if (soundEffect != null) {
- PlaySound sound = (PlaySound) StrifePlugin.getInstance().getEffectManager()
- .getEffect(soundEffect);
- sound.applyAtLocation(caster, summon.getLocation());
+ if (soundEffect != null) {
+ PlaySound sound = (PlaySound) StrifePlugin.getInstance().getEffectManager()
+ .getEffect(soundEffect);
+ sound.applyAtLocation(caster, summon.getLocation());
+ }
+
+ if (mount) {
+ summon.addPassenger(caster.getEntity());
+ }
+ double maxHealth = summon.getMaxHealth() *
+ (1 + (caster.getStat(StrifeStat.MINION_LIFE) / 100));
+ summon.getAttribute(Attribute.GENERIC_MAX_HEALTH).setBaseValue(maxHealth);
+ summon.setHealth(maxHealth);
}
- if (mount) {
- summon.addPassenger(caster.getEntity());
+ List minionList = new ArrayList<>(caster.getMinions());
+
+ int excessMinions = minionList.size() - (int) caster.getStat(StrifeStat.MAX_MINIONS);
+ if (excessMinions > 0) {
+ minionList.sort(Comparator.comparingDouble(StrifeMob::getMinionRating));
+ while (excessMinions > 0) {
+ minionList.get(excessMinions - 1).minionDeath();
+ //Bukkit.getLogger().info("commit die: " + minionList.get(excessMinions - 1).getEntity().getName());
+ excessMinions--;
+ }
}
- double maxHealth = summon.getMaxHealth() * (1 + (caster.getStat(StrifeStat.MINION_LIFE) / 100));
- summon.getAttribute(Attribute.GENERIC_MAX_HEALTH).setBaseValue(maxHealth);
- summon.setHealth(maxHealth);
}
public void setUniqueEntity(String uniqueEntity) {
diff --git a/src/main/java/land/face/strife/data/effects/TriggerLoreAbility.java b/src/main/java/land/face/strife/data/effects/TriggerLoreAbility.java
index f4d9d21f..91ce6c7f 100644
--- a/src/main/java/land/face/strife/data/effects/TriggerLoreAbility.java
+++ b/src/main/java/land/face/strife/data/effects/TriggerLoreAbility.java
@@ -1,7 +1,6 @@
package land.face.strife.data.effects;
import land.face.strife.data.StrifeMob;
-import land.face.strife.data.champion.Champion;
import land.face.strife.listeners.LoreAbilityListener;
import land.face.strife.managers.LoreAbilityManager.TriggerType;
@@ -15,12 +14,8 @@ public TriggerLoreAbility(TriggerType triggerType) {
@Override
public void apply(StrifeMob caster, StrifeMob target) {
- Champion champion = caster.getChampion();
- if (champion != null) {
- LoreAbilityListener.executeBoundEffects(caster, target.getEntity(), champion.getLoreAbilities().get(triggerType));
- }
+ LoreAbilityListener.executeBoundEffects(caster, target.getEntity(), caster.getLoreAbilities().get(triggerType));
LoreAbilityListener.executeFiniteEffects(caster, target, triggerType);
}
-
}
\ No newline at end of file
diff --git a/src/main/java/land/face/strife/listeners/CombatListener.java b/src/main/java/land/face/strife/listeners/CombatListener.java
index 5f523baa..383de6b8 100644
--- a/src/main/java/land/face/strife/listeners/CombatListener.java
+++ b/src/main/java/land/face/strife/listeners/CombatListener.java
@@ -258,6 +258,7 @@ public void strifeDamageHandler(EntityDamageByEntityEvent event) {
}
Map damage = DamageUtil.buildDamage(attacker, defender, damageModifiers);
+ DamageUtil.applyElementalEffects(attacker, defender, damage, damageModifiers);
DamageUtil.reduceDamage(attacker, defender, damage, damageModifiers);
float finalDamage = DamageUtil.calculateFinalDamage(attacker, defender, damage, damageModifiers);
diff --git a/src/main/java/land/face/strife/listeners/DataListener.java b/src/main/java/land/face/strife/listeners/DataListener.java
index a6500652..afe15201 100644
--- a/src/main/java/land/face/strife/listeners/DataListener.java
+++ b/src/main/java/land/face/strife/listeners/DataListener.java
@@ -278,6 +278,12 @@ public void onInvyClose(InventoryCloseEvent event) {
plugin.getConfirmationMenu().open((Player) event.getPlayer()), 1L);
}
+ @EventHandler(priority = EventPriority.NORMAL)
+ public void onRespawn(PlayerRespawnEvent event) {
+ StrifeMob mob = plugin.getStrifeMobManager().getStatMob(event.getPlayer());
+ mob.restartTimers();
+ }
+
private void ensureAbilitiesDontInstantCast(Player player) {
plugin.getAbilityManager().setGlobalCooldown(player, 30);
if (player.getInventory().getHeldItemSlot() < 3) {
diff --git a/src/main/java/land/face/strife/listeners/InventoryListener.java b/src/main/java/land/face/strife/listeners/InventoryListener.java
index 6eb02e65..4cda61a8 100644
--- a/src/main/java/land/face/strife/listeners/InventoryListener.java
+++ b/src/main/java/land/face/strife/listeners/InventoryListener.java
@@ -40,7 +40,7 @@ public void onChangeHeldItem(PlayerItemHeldEvent event) {
return;
}
Bukkit.getScheduler().runTaskLater(StrifePlugin.getInstance(), () -> {
- plugin.getChampionManager().updateEquipmentStats(event.getPlayer());
+ plugin.getStrifeMobManager().updateEquipmentStats(event.getPlayer());
plugin.getStatUpdateManager().updateVanillaAttributes(event.getPlayer());
}, 1L);
}
@@ -73,7 +73,7 @@ public void onChangeHeldItem(PlayerSwapHandItemsEvent event) {
return;
}
Bukkit.getScheduler().runTaskLater(StrifePlugin.getInstance(), () -> {
- plugin.getChampionManager().updateEquipmentStats(plugin.getChampionManager().getChampion(event.getPlayer()));
+ plugin.getStrifeMobManager().updateEquipmentStats(event.getPlayer());
plugin.getStatUpdateManager().updateVanillaAttributes(event.getPlayer());
}, 1L);
}
diff --git a/src/main/java/land/face/strife/listeners/LoreAbilityListener.java b/src/main/java/land/face/strife/listeners/LoreAbilityListener.java
index c4755b13..5c85a61b 100644
--- a/src/main/java/land/face/strife/listeners/LoreAbilityListener.java
+++ b/src/main/java/land/face/strife/listeners/LoreAbilityListener.java
@@ -55,33 +55,20 @@ public LoreAbilityListener(StrifeMobManager strifeMobManager,
@EventHandler(priority = EventPriority.MONITOR)
public void onAbilityCast(AbilityCastEvent event) {
- Champion champion = event.getCaster().getChampion();
- if (champion != null) {
- executeBoundEffects(event.getCaster(), event.getCaster().getEntity(),
- champion.getLoreAbilities().get(ON_CAST));
- }
+ executeBoundEffects(event.getCaster(), event.getCaster().getEntity(), event.getCaster().getLoreAbilities().get(ON_CAST));
executeFiniteEffects(event.getCaster(), event.getCaster(), ON_CAST);
}
@EventHandler(priority = EventPriority.MONITOR)
public void onAirJump(AirJumpEvent event) {
- Champion champion = event.getJumper().getChampion();
- if (champion != null) {
- executeBoundEffects(event.getJumper(), event.getJumper().getEntity(),
- champion.getLoreAbilities().get(ON_AIR_JUMP));
- }
+ executeBoundEffects(event.getJumper(), event.getJumper().getEntity(), event.getJumper().getLoreAbilities().get(ON_AIR_JUMP));
executeFiniteEffects(event.getJumper(), event.getJumper(), ON_AIR_JUMP);
}
@EventHandler(priority = EventPriority.MONITOR)
public void onCombatChange(CombatChangeEvent event) {
- Champion champion = event.getTarget().getChampion();
- TriggerType type =
- event.getNewState() == NewCombatState.ENTER ? ON_COMBAT_START : ON_COMBAT_END;
- if (champion != null) {
- executeBoundEffects(event.getTarget(), event.getTarget().getEntity(),
- champion.getLoreAbilities().get(type));
- }
+ TriggerType type = event.getNewState() == NewCombatState.ENTER ? ON_COMBAT_START : ON_COMBAT_END;
+ executeBoundEffects(event.getTarget(), event.getTarget().getEntity(), event.getTarget().getLoreAbilities().get(type));
executeFiniteEffects(event.getTarget(), event.getTarget(), type);
}
@@ -89,8 +76,7 @@ public void onCombatChange(CombatChangeEvent event) {
public void onCriticalHit(CriticalEvent event) {
Champion champion = event.getAttacker().getChampion();
if (champion != null) {
- executeBoundEffects(event.getAttacker(), event.getVictim().getEntity(),
- event.getAttacker().getChampion().getLoreAbilities().get(ON_CRIT));
+ executeBoundEffects(event.getAttacker(), event.getVictim().getEntity(), event.getAttacker().getLoreAbilities().get(ON_CRIT));
}
executeFiniteEffects(event.getAttacker(), event.getVictim(), ON_CRIT);
}
@@ -104,8 +90,7 @@ public void onFall(EntityDamageEvent event) {
return;
}
StrifeMob mob = getAttrEntity((Player) event.getEntity());
- executeBoundEffects(mob, (LivingEntity) event.getEntity(),
- mob.getChampion().getLoreAbilities().get(ON_FALL));
+ executeBoundEffects(mob, (LivingEntity) event.getEntity(), mob.getLoreAbilities().get(ON_FALL));
executeFiniteEffects(mob, mob, ON_FALL);
}
@@ -113,8 +98,7 @@ public void onFall(EntityDamageEvent event) {
public void onEvade(EvadeEvent event) {
Champion champion = event.getEvader().getChampion();
if (champion != null) {
- executeBoundEffects(event.getEvader(), event.getAttacker().getEntity(),
- event.getEvader().getChampion().getLoreAbilities().get(ON_EVADE));
+ executeBoundEffects(event.getEvader(), event.getAttacker().getEntity(), event.getEvader().getLoreAbilities().get(ON_EVADE));
}
executeFiniteEffects(event.getEvader(), event.getAttacker(), ON_EVADE);
}
@@ -123,8 +107,7 @@ public void onEvade(EvadeEvent event) {
public void onBlock(BlockEvent event) {
Champion champion = event.getBlocker().getChampion();
if (champion != null) {
- executeBoundEffects(event.getBlocker(), event.getAttacker().getEntity(),
- event.getBlocker().getChampion().getLoreAbilities().get(ON_BLOCK));
+ executeBoundEffects(event.getBlocker(), event.getAttacker().getEntity(), event.getBlocker().getLoreAbilities().get(ON_BLOCK));
}
executeFiniteEffects(event.getBlocker(), event.getAttacker(), ON_BLOCK);
}
@@ -133,8 +116,7 @@ public void onBlock(BlockEvent event) {
public void onSneakAttack(SneakAttackEvent event) {
Champion champion = event.getAttacker().getChampion();
if (champion != null) {
- executeBoundEffects(event.getAttacker(), event.getVictim().getEntity(),
- event.getAttacker().getChampion().getLoreAbilities().get(ON_SNEAK_ATTACK));
+ executeBoundEffects(event.getAttacker(), event.getVictim().getEntity(), event.getAttacker().getLoreAbilities().get(ON_SNEAK_ATTACK));
}
executeFiniteEffects(event.getAttacker(), event.getVictim(), ON_SNEAK_ATTACK);
}
@@ -150,8 +132,7 @@ public void onEntityDeath(EntityDeathEvent event) {
}
}
StrifeMob killerMob = strifeMobManager.getStatMob(killer);
- executeBoundEffects(killerMob, event.getEntity(),
- killerMob.getChampion().getLoreAbilities().get(ON_KILL));
+ executeBoundEffects(killerMob, event.getEntity(), killerMob.getLoreAbilities().get(ON_KILL));
executeFiniteEffects(killerMob, victim, ON_KILL);
}
@@ -170,21 +151,19 @@ public void onStrifeDamage(StrifeDamageEvent event) {
return;
}
- if (attacker.getEntity() instanceof Player) {
- boolean trigger = event.getDamageModifiers().isApplyOnHitEffects() || (Math.random() < Math
- .max(event.getDamageModifiers().getAttackMultiplier(),
- event.getDamageModifiers().getDamageReductionRatio()));
- if (trigger) {
- HashSet abilitySet = new HashSet<>(
- attacker.getChampion().getLoreAbilities().get(ON_HIT));
- executeBoundEffects(attacker, defender.getEntity(), abilitySet);
- }
+ boolean trigger = event.getDamageModifiers().isApplyOnHitEffects() || (Math.random() < Math
+ .max(event.getDamageModifiers().getAttackMultiplier(),
+ event.getDamageModifiers().getDamageReductionRatio()));
+ if (trigger) {
+ HashSet abilitySet = new HashSet<>(attacker.getLoreAbilities().get(ON_HIT));
+ executeBoundEffects(attacker, defender.getEntity(), abilitySet);
}
+
executeFiniteEffects(attacker, defender, ON_HIT);
if (defender.getEntity() instanceof Player) {
executeBoundEffects(defender, attacker.getEntity(),
- event.getDefender().getChampion().getLoreAbilities().get(WHEN_HIT));
+ event.getDefender().getLoreAbilities().get(WHEN_HIT));
}
executeFiniteEffects(defender, attacker, WHEN_HIT);
}
diff --git a/src/main/java/land/face/strife/listeners/ShootListener.java b/src/main/java/land/face/strife/listeners/ShootListener.java
index 8127f277..b3a95a3b 100644
--- a/src/main/java/land/face/strife/listeners/ShootListener.java
+++ b/src/main/java/land/face/strife/listeners/ShootListener.java
@@ -250,6 +250,7 @@ public void onEffectProjectileHit(final ProjectileHitEvent event) {
}
plugin.getEffectManager().processEffectList(caster, response, hitEffects);
+ event.getEntity().remove();
}
private void doPistolShot(StrifeMob mob, float attackMultiplier) {
diff --git a/src/main/java/land/face/strife/listeners/StatUpdateListener.java b/src/main/java/land/face/strife/listeners/StatUpdateListener.java
index c2917fcc..d3ffeead 100644
--- a/src/main/java/land/face/strife/listeners/StatUpdateListener.java
+++ b/src/main/java/land/face/strife/listeners/StatUpdateListener.java
@@ -73,7 +73,7 @@ public void onInventoryClose(InventoryCloseEvent event) {
if (player.isDead() || player.getHealth() <= 0D) {
return;
}
- plugin.getChampionManager().updateEquipmentStats(plugin.getChampionManager().getChampion((Player) event.getPlayer()));
+ plugin.getStrifeMobManager().updateEquipmentStats(plugin.getStrifeMobManager().getStatMob(event.getPlayer()));
plugin.getStatUpdateManager().updateVanillaAttributes(player);
}
diff --git a/src/main/java/land/face/strife/managers/ChampionManager.java b/src/main/java/land/face/strife/managers/ChampionManager.java
index 8e8cd136..3700d3f2 100644
--- a/src/main/java/land/face/strife/managers/ChampionManager.java
+++ b/src/main/java/land/face/strife/managers/ChampionManager.java
@@ -17,8 +17,6 @@
package land.face.strife.managers;
import static com.tealcube.minecraft.bukkit.facecore.utilities.MessageUtils.sendMessage;
-import static org.bukkit.inventory.EquipmentSlot.HAND;
-import static org.bukkit.inventory.EquipmentSlot.OFF_HAND;
import com.tealcube.minecraft.bukkit.facecore.utilities.MessageUtils;
import java.util.Collection;
@@ -33,36 +31,21 @@
import land.face.strife.data.StrifeMob;
import land.face.strife.data.champion.Champion;
import land.face.strife.data.champion.ChampionSaveData;
-import land.face.strife.data.champion.PlayerEquipmentCache;
import land.face.strife.data.champion.StrifeAttribute;
import land.face.strife.managers.LoreAbilityManager.TriggerType;
import land.face.strife.stats.StrifeStat;
-import land.face.strife.stats.StrifeTrait;
-import land.face.strife.util.ItemUtil;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
-import org.bukkit.inventory.EntityEquipment;
-import org.bukkit.inventory.EquipmentSlot;
-import org.bukkit.inventory.ItemStack;
public class ChampionManager {
private final StrifePlugin plugin;
- private final String levelReqGeneric;
- private final float dualWieldAttackSpeed;
- private final Map levelReqMap = new HashMap<>();
private final Map championMap = new HashMap<>();
-
private final static String RESET_MESSAGE =
"&a&lYour Levelpoints have been automatically reset due to an update!";
public ChampionManager(StrifePlugin plugin) {
this.plugin = plugin;
- dualWieldAttackSpeed = (float) plugin.getSettings().getDouble("config.mechanics.dual-wield-attack-speed", 0) / 2;
- levelReqGeneric = plugin.getSettings().getString("language.level-req.generic", "");
- for (EquipmentSlot slot : EquipmentSlot.values()) {
- levelReqMap.put(slot, plugin.getSettings().getString("language.level-req." + slot, ""));
- }
}
public Champion getChampion(Player player) {
@@ -80,7 +63,6 @@ public Champion getChampion(Player player) {
buildBaseStats(champion);
rebuildAttributes(champion);
- buildEquipmentAttributes(champion);
plugin.getPathManager().buildPathBonus(champion);
champion.recombineCache();
@@ -116,13 +98,12 @@ public void tickPassiveLoreAbilities() {
if (!p.isValid()) {
continue;
}
- Champion champion = getChampion(p);
- Set abilities = champion.getEquipmentCache().getCombinedAbilities().get(
- TriggerType.TIMER);
+ StrifeMob mob = plugin.getStrifeMobManager().getStatMob(p);
+ Set abilities = mob.getEquipmentCache().getCombinedAbilities()
+ .get(TriggerType.TIMER);
if (abilities == null || abilities.isEmpty()) {
continue;
}
- StrifeMob mob = plugin.getStrifeMobManager().getStatMob(p);
for (LoreAbility ability : abilities) {
plugin.getLoreAbilityManager().applyLoreAbility(ability, mob, mob.getEntity());
}
@@ -198,171 +179,32 @@ public void rebuildAttributes(Champion champion) {
champion.setLevelPointStats(attributeMap);
}
- private void buildEquipmentAttributes(Champion champion) {
- EntityEquipment equipment = champion.getPlayer().getEquipment();
- PlayerEquipmentCache equipmentCache = champion.getEquipmentCache();
-
- Set updatedSlots = new HashSet<>();
- for (EquipmentSlot slot : PlayerEquipmentCache.ITEM_SLOTS) {
- ItemStack item = ItemUtil.getItem(equipment, slot);
- if (!ItemUtil.doesHashMatch(item, equipmentCache.getSlotHash(slot))) {
- updatedSlots.add(slot);
- }
- }
-
- if (updatedSlots.contains(HAND)) {
- updatedSlots.add(OFF_HAND);
- } else if (updatedSlots.contains(OFF_HAND)) {
- updatedSlots.add(HAND);
- }
-
- for (EquipmentSlot slot : updatedSlots) {
- ItemStack item = ItemUtil.getItem(equipment, slot);
- equipmentCache.setSlotHash(slot, ItemUtil.hashItem(item));
-
- equipmentCache.setSlotStats(slot, getItemStats(slot, equipment));
- if (clearStatsIfReqNotMet(champion.getPlayer(), slot, equipmentCache)) {
- continue;
- }
- equipmentCache.setSlotAbilities(slot, getItemAbilities(slot, equipment));
- equipmentCache.setSlotTraits(slot, getItemTraits(slot, equipment));
- }
-
- if (updatedSlots.contains(HAND) && ItemUtil.isDualWield(equipment)) {
- applyDualWieldStatChanges(equipmentCache, HAND);
- applyDualWieldStatChanges(equipmentCache, OFF_HAND);
- }
-
- equipmentCache.recombine(champion);
- }
-
- private void applyDualWieldStatChanges(PlayerEquipmentCache cache, EquipmentSlot slot) {
- for (StrifeStat attribute : cache.getSlotStats(slot).keySet()) {
- cache.getSlotStats(slot).put(attribute, cache.getSlotStats(slot).get(attribute) * 0.7f);
- }
- cache.getSlotStats(slot).put(StrifeStat.ATTACK_SPEED,
- cache.getSlotStats(slot).getOrDefault(StrifeStat.ATTACK_SPEED, 0f) + dualWieldAttackSpeed);
- }
-
- private boolean clearStatsIfReqNotMet(Player p, EquipmentSlot slot, PlayerEquipmentCache cache) {
- if (!meetsLevelRequirement(p, cache.getSlotStats(slot))) {
- sendMessage(p, levelReqMap.get(slot));
- sendMessage(p, levelReqGeneric);
- cache.clearSlot(slot);
- return true;
+ public boolean addBoundLoreAbility(StrifeMob mob, LoreAbility loreAbility) {
+ Champion champion = mob.getChampion();
+ if (champion == null) {
+ return false;
}
- return false;
- }
-
- public boolean addBoundLoreAbility(Champion champion, LoreAbility loreAbility) {
if (champion.getSaveData().getBoundAbilities().contains(loreAbility)) {
return false;
}
champion.getSaveData().getBoundAbilities().add(loreAbility);
- champion.getEquipmentCache().recombineAbilities(champion);
+ mob.getEquipmentCache().recombineAbilities(mob);
return true;
}
- public boolean removeBoundLoreAbility(Champion champion, LoreAbility loreAbility) {
+ public boolean removeBoundLoreAbility(StrifeMob mob, LoreAbility loreAbility) {
+ Champion champion = mob.getChampion();
+ if (champion == null) {
+ return false;
+ }
if (!champion.getSaveData().getBoundAbilities().contains(loreAbility)) {
return false;
}
champion.getSaveData().getBoundAbilities().remove(loreAbility);
- champion.getEquipmentCache().recombineAbilities(champion);
+ mob.getEquipmentCache().recombineAbilities(mob);
return true;
}
- public void updateEquipmentStats(Player player) {
- updateEquipmentStats(getChampion(player));
- }
-
- public void updateEquipmentStats(Champion champion) {
- buildEquipmentAttributes(champion);
- champion.recombineCache();
- }
-
- private Set getItemAbilities(EquipmentSlot slot, EntityEquipment equipment) {
- switch (slot) {
- case HAND:
- if (ItemUtil.isArmor(equipment.getItemInMainHand().getType())) {
- return new HashSet<>();
- }
- return plugin.getLoreAbilityManager().getAbilities(equipment.getItemInMainHand());
- case OFF_HAND:
- if (ItemUtil.isArmor(equipment.getItemInMainHand().getType())) {
- return new HashSet<>();
- }
- if (!ItemUtil.isValidOffhand(equipment)) {
- return new HashSet<>();
- }
- return plugin.getLoreAbilityManager().getAbilities(equipment.getItemInOffHand());
- case HEAD:
- return plugin.getLoreAbilityManager().getAbilities(equipment.getHelmet());
- case CHEST:
- return plugin.getLoreAbilityManager().getAbilities(equipment.getChestplate());
- case LEGS:
- return plugin.getLoreAbilityManager().getAbilities(equipment.getLeggings());
- case FEET:
- return plugin.getLoreAbilityManager().getAbilities(equipment.getBoots());
- default:
- return new HashSet<>();
- }
- }
-
- private Map getItemStats(EquipmentSlot slot, EntityEquipment equipment) {
- switch (slot) {
- case HAND:
- if (ItemUtil.isArmor(equipment.getItemInMainHand().getType())) {
- return new HashMap<>();
- }
- return plugin.getStatUpdateManager().getItemStats(equipment.getItemInMainHand());
- case OFF_HAND:
- if (ItemUtil.isArmor(equipment.getItemInMainHand().getType())) {
- return new HashMap<>();
- }
- if (!ItemUtil.isValidOffhand(equipment)) {
- return new HashMap<>();
- }
- return plugin.getStatUpdateManager().getItemStats(equipment.getItemInOffHand());
- case HEAD:
- return plugin.getStatUpdateManager().getItemStats(equipment.getHelmet());
- case CHEST:
- return plugin.getStatUpdateManager().getItemStats(equipment.getChestplate());
- case LEGS:
- return plugin.getStatUpdateManager().getItemStats(equipment.getLeggings());
- case FEET:
- return plugin.getStatUpdateManager().getItemStats(equipment.getBoots());
- default:
- return new HashMap<>();
- }
- }
-
- private Set getItemTraits(EquipmentSlot slot, EntityEquipment equipment) {
- switch (slot) {
- case HAND:
- return ItemUtil.getTraits(equipment.getItemInMainHand());
- case OFF_HAND:
- if (!ItemUtil.isValidOffhand(equipment)) {
- return new HashSet<>();
- }
- return ItemUtil.getTraits(equipment.getItemInOffHand());
- case HEAD:
- return ItemUtil.getTraits(equipment.getHelmet());
- case CHEST:
- return ItemUtil.getTraits(equipment.getChestplate());
- case LEGS:
- return ItemUtil.getTraits(equipment.getLeggings());
- case FEET:
- return ItemUtil.getTraits(equipment.getBoots());
- default:
- return new HashSet<>();
- }
- }
-
- private boolean meetsLevelRequirement(Player player, Map statMap) {
- return Math.round(statMap.getOrDefault(StrifeStat.LEVEL_REQUIREMENT, 0f)) <= player.getLevel();
- }
-
private int getTotalChampionStats(Champion champion) {
ChampionSaveData championSaveData = champion.getSaveData();
int total = championSaveData.getUnusedStatPoints();
diff --git a/src/main/java/land/face/strife/managers/EffectManager.java b/src/main/java/land/face/strife/managers/EffectManager.java
index b34757e4..5fec9ac0 100644
--- a/src/main/java/land/face/strife/managers/EffectManager.java
+++ b/src/main/java/land/face/strife/managers/EffectManager.java
@@ -18,6 +18,7 @@
import land.face.strife.data.StrifeMob;
import land.face.strife.data.TargetResponse;
import land.face.strife.data.ability.Ability;
+import land.face.strife.data.champion.LifeSkillType;
import land.face.strife.data.champion.StrifeAttribute;
import land.face.strife.data.conditions.AliveCondition;
import land.face.strife.data.conditions.AttributeCondition;
@@ -46,6 +47,7 @@
import land.face.strife.data.conditions.LevelCondition;
import land.face.strife.data.conditions.LightCondition;
import land.face.strife.data.conditions.LoreCondition;
+import land.face.strife.data.conditions.MinionCondition;
import land.face.strife.data.conditions.MovingCondition;
import land.face.strife.data.conditions.NearbyEntitiesCondition;
import land.face.strife.data.conditions.PotionCondition;
@@ -303,6 +305,7 @@ public void loadEffect(String key, ConfigurationSection cs) {
((Damage) effect).setApplyOnHitEffects(cs.getBoolean("apply-on-hit-effects", attackMult >= 0.6 || damageReductionRatio >= 0.6));
((Damage) effect).setShowPopoffs(cs.getBoolean("show-popoffs", true));
((Damage) effect).setBypassBarrier(cs.getBoolean("bypass-barrier", false));
+ ((Damage) effect).setSelfInflict(cs.getBoolean("self-inflict", false));
List hitEffects = cs.getStringList("hit-effects");
delayedSetEffects(((Damage) effect).getHitEffects(), hitEffects, key, false);
List killEffects = cs.getStringList("kill-effects");
@@ -733,7 +736,7 @@ public void loadEffect(String key, ConfigurationSection cs) {
((StrifeParticle) effect).setBlue(cs.getDouble("blue", 0) / 255D);
((StrifeParticle) effect).setGreen(cs.getDouble("green", 0) / 255D);
}
- if (style == ParticleStyle.ARC) {
+ if (style == ParticleStyle.ARC || style == ParticleStyle.CLAW) {
((StrifeParticle) effect).setArcAngle(cs.getDouble("arc-angle", 30));
((StrifeParticle) effect).setArcOffset(cs.getDouble("arc-offset", 0));
}
@@ -769,8 +772,15 @@ public void loadEffect(String key, ConfigurationSection cs) {
if (effectType != Effect.EffectType.WAIT) {
effect.setForceTargetCaster(cs.getBoolean("force-target-caster", false));
effect.setFriendly(cs.getBoolean("friendly", false));
- Map statMults = StatUtil.getStatMapFromSection(cs.getConfigurationSection("stat-mults"));
+ Map statMults = StatUtil
+ .getStatMapFromSection(cs.getConfigurationSection("stat-mults"));
effect.setStatMults(statMults);
+ Map skillMults = StatUtil
+ .getSkillMapFromSection(cs.getConfigurationSection("skill-multipliers"));
+ effect.setSkillMults(skillMults);
+ Map attributeMults = StatUtil
+ .getAttributeMapFromSection(cs.getConfigurationSection("attribute-multipliers"));
+ effect.setAttributeMults(attributeMults);
}
effect.setId(key);
List conditionStrings = cs.getStringList("conditions");
@@ -921,6 +931,9 @@ public void loadCondition(String key, ConfigurationSection cs) {
case MOVING:
condition = new MovingCondition(cs.getBoolean("state", true));
break;
+ case MINION:
+ condition = new MinionCondition(cs.getBoolean("is-owner", false));
+ break;
case NEARBY_ENTITIES:
int range = cs.getInt("range", 1);
condition = new NearbyEntitiesCondition(cs.getBoolean("friendly", true), range);
diff --git a/src/main/java/land/face/strife/managers/StrifeMobManager.java b/src/main/java/land/face/strife/managers/StrifeMobManager.java
index bcc1f0ab..3810db0f 100644
--- a/src/main/java/land/face/strife/managers/StrifeMobManager.java
+++ b/src/main/java/land/face/strife/managers/StrifeMobManager.java
@@ -1,25 +1,48 @@
package land.face.strife.managers;
+import static com.tealcube.minecraft.bukkit.facecore.utilities.MessageUtils.sendMessage;
+import static org.bukkit.inventory.EquipmentSlot.HAND;
+import static org.bukkit.inventory.EquipmentSlot.OFF_HAND;
+
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
import java.util.WeakHashMap;
import land.face.strife.StrifePlugin;
import land.face.strife.data.LoreAbility;
import land.face.strife.data.StrifeMob;
+import land.face.strife.data.champion.EquipmentCache;
import land.face.strife.data.effects.FiniteUsesEffect;
+import land.face.strife.stats.StrifeStat;
+import land.face.strife.stats.StrifeTrait;
+import land.face.strife.util.ItemUtil;
import land.face.strife.util.SpecialStatusUtil;
import land.face.strife.util.StatUtil;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
+import org.bukkit.inventory.EntityEquipment;
+import org.bukkit.inventory.EquipmentSlot;
+import org.bukkit.inventory.ItemStack;
public class StrifeMobManager {
private final StrifePlugin plugin;
private final Map trackedEntities = new WeakHashMap<>();
+ private final String levelReqGeneric;
+ private final float dualWieldAttackSpeed;
+ private final Map levelReqMap = new HashMap<>();
+
public StrifeMobManager(StrifePlugin plugin) {
this.plugin = plugin;
+ dualWieldAttackSpeed = (float) plugin.getSettings().getDouble("config.mechanics.dual-wield-attack-speed", 0) / 2;
+ levelReqGeneric = plugin.getSettings().getString("language.level-req.generic", "");
+ for (EquipmentSlot slot : EquipmentSlot.values()) {
+ levelReqMap.put(slot, plugin.getSettings().getString("language.level-req." + slot, ""));
+ }
}
public Map getMobs() {
@@ -92,4 +115,157 @@ public void doChunkDespawn(Entity entity) {
public boolean isTrackedEntity(LivingEntity entity) {
return trackedEntities.containsKey(entity);
}
+
+ private void buildEquipmentAttributes(StrifeMob mob) {
+ EntityEquipment equipment = mob.getEntity().getEquipment();
+ EquipmentCache equipmentCache = mob.getEquipmentCache();
+
+ Set updatedSlots = new HashSet<>();
+ for (EquipmentSlot slot : EquipmentCache.ITEM_SLOTS) {
+ ItemStack item = ItemUtil.getItem(equipment, slot);
+ if (!ItemUtil.doesHashMatch(item, equipmentCache.getSlotHash(slot))) {
+ updatedSlots.add(slot);
+ }
+ }
+
+ if (updatedSlots.contains(HAND)) {
+ updatedSlots.add(OFF_HAND);
+ } else if (updatedSlots.contains(OFF_HAND)) {
+ updatedSlots.add(HAND);
+ }
+
+ for (EquipmentSlot slot : updatedSlots) {
+ ItemStack item = ItemUtil.getItem(equipment, slot);
+ equipmentCache.setSlotHash(slot, ItemUtil.hashItem(item));
+
+ equipmentCache.setSlotStats(slot, getItemStats(slot, equipment));
+ if (clearStatsIfReqNotMet(mob, slot, equipmentCache)) {
+ continue;
+ }
+ equipmentCache.setSlotAbilities(slot, getItemAbilities(slot, equipment));
+ equipmentCache.setSlotTraits(slot, getItemTraits(slot, equipment));
+ }
+
+ if (updatedSlots.contains(HAND) && ItemUtil.isDualWield(equipment)) {
+ applyDualWieldStatChanges(equipmentCache, HAND);
+ applyDualWieldStatChanges(equipmentCache, OFF_HAND);
+ }
+
+ equipmentCache.recombine(mob);
+ }
+
+ private Set getItemAbilities(EquipmentSlot slot, EntityEquipment equipment) {
+ switch (slot) {
+ case HAND:
+ if (ItemUtil.isArmor(equipment.getItemInMainHand().getType())) {
+ return new HashSet<>();
+ }
+ return plugin.getLoreAbilityManager().getAbilities(equipment.getItemInMainHand());
+ case OFF_HAND:
+ if (ItemUtil.isArmor(equipment.getItemInMainHand().getType())) {
+ return new HashSet<>();
+ }
+ if (!ItemUtil.isValidOffhand(equipment)) {
+ return new HashSet<>();
+ }
+ return plugin.getLoreAbilityManager().getAbilities(equipment.getItemInOffHand());
+ case HEAD:
+ return plugin.getLoreAbilityManager().getAbilities(equipment.getHelmet());
+ case CHEST:
+ return plugin.getLoreAbilityManager().getAbilities(equipment.getChestplate());
+ case LEGS:
+ return plugin.getLoreAbilityManager().getAbilities(equipment.getLeggings());
+ case FEET:
+ return plugin.getLoreAbilityManager().getAbilities(equipment.getBoots());
+ default:
+ return new HashSet<>();
+ }
+ }
+
+ private Map getItemStats(EquipmentSlot slot, EntityEquipment equipment) {
+ switch (slot) {
+ case HAND:
+ if (ItemUtil.isArmor(equipment.getItemInMainHand().getType())) {
+ return new HashMap<>();
+ }
+ return plugin.getStatUpdateManager().getItemStats(equipment.getItemInMainHand());
+ case OFF_HAND:
+ if (ItemUtil.isArmor(equipment.getItemInMainHand().getType())) {
+ return new HashMap<>();
+ }
+ if (!ItemUtil.isValidOffhand(equipment)) {
+ return new HashMap<>();
+ }
+ return plugin.getStatUpdateManager().getItemStats(equipment.getItemInOffHand());
+ case HEAD:
+ return plugin.getStatUpdateManager().getItemStats(equipment.getHelmet());
+ case CHEST:
+ return plugin.getStatUpdateManager().getItemStats(equipment.getChestplate());
+ case LEGS:
+ return plugin.getStatUpdateManager().getItemStats(equipment.getLeggings());
+ case FEET:
+ return plugin.getStatUpdateManager().getItemStats(equipment.getBoots());
+ default:
+ return new HashMap<>();
+ }
+ }
+
+ private Set getItemTraits(EquipmentSlot slot, EntityEquipment equipment) {
+ switch (slot) {
+ case HAND:
+ return ItemUtil.getTraits(equipment.getItemInMainHand());
+ case OFF_HAND:
+ if (!ItemUtil.isValidOffhand(equipment)) {
+ return new HashSet<>();
+ }
+ return ItemUtil.getTraits(equipment.getItemInOffHand());
+ case HEAD:
+ return ItemUtil.getTraits(equipment.getHelmet());
+ case CHEST:
+ return ItemUtil.getTraits(equipment.getChestplate());
+ case LEGS:
+ return ItemUtil.getTraits(equipment.getLeggings());
+ case FEET:
+ return ItemUtil.getTraits(equipment.getBoots());
+ default:
+ return new HashSet<>();
+ }
+ }
+
+ private boolean meetsLevelRequirement(Player player, Map statMap) {
+ return Math.round(statMap.getOrDefault(StrifeStat.LEVEL_REQUIREMENT, 0f)) <= player.getLevel();
+ }
+
+ public void updateEquipmentStats(LivingEntity le) {
+ updateEquipmentStats(getStatMob(le));
+ }
+
+ public void updateEquipmentStats(StrifeMob mob) {
+ buildEquipmentAttributes(mob);
+ if (mob.getChampion() != null) {
+ mob.getChampion().recombineCache();
+ }
+ }
+
+ private void applyDualWieldStatChanges(EquipmentCache cache, EquipmentSlot slot) {
+ for (StrifeStat attribute : cache.getSlotStats(slot).keySet()) {
+ cache.getSlotStats(slot).put(attribute, cache.getSlotStats(slot).get(attribute) * 0.7f);
+ }
+ cache.getSlotStats(slot).put(StrifeStat.ATTACK_SPEED,
+ cache.getSlotStats(slot).getOrDefault(StrifeStat.ATTACK_SPEED, 0f) + dualWieldAttackSpeed);
+ }
+
+ private boolean clearStatsIfReqNotMet(StrifeMob mob, EquipmentSlot slot, EquipmentCache cache) {
+ if (mob.getChampion() == null) {
+ return false;
+ }
+ Player p = mob.getChampion().getPlayer();
+ if (!meetsLevelRequirement(p, cache.getSlotStats(slot))) {
+ sendMessage(p, levelReqMap.get(slot));
+ sendMessage(p, levelReqGeneric);
+ cache.clearSlot(slot);
+ return true;
+ }
+ return false;
+ }
}
diff --git a/src/main/java/land/face/strife/managers/UniqueEntityManager.java b/src/main/java/land/face/strife/managers/UniqueEntityManager.java
index aa9593d3..dabd9355 100644
--- a/src/main/java/land/face/strife/managers/UniqueEntityManager.java
+++ b/src/main/java/land/face/strife/managers/UniqueEntityManager.java
@@ -121,6 +121,9 @@ public StrifeMob spawnUnique(UniqueEntity uniqueEntity, Location location) {
if (!uniqueEntity.isGravity()) {
le.setGravity(false);
}
+ if (!uniqueEntity.isHasAI()) {
+ le.setAI(false);
+ }
if (le instanceof Zombie) {
((Zombie) le).setBaby(uniqueEntity.isBaby());
@@ -333,6 +336,7 @@ public void loadUniques(VersionedSmartYamlConfiguration uniqueEnemiesYAML) {
uniqueEntity.setZombificationImmune(cs.getBoolean("zombification-immune", true));
uniqueEntity.setArmsRaised(cs.getBoolean("arms-raised", true));
uniqueEntity.setGravity(cs.getBoolean("gravity", true));
+ uniqueEntity.setHasAI(cs.getBoolean("has-ai", true));
if (uniqueEntity.getType() == EntityType.VILLAGER || uniqueEntity.getType() == EntityType.ZOMBIE_VILLAGER) {
String prof = cs.getString("profession");
if (prof != null) {
diff --git a/src/main/java/land/face/strife/menus/stats/StatsEffectMenuItem.java b/src/main/java/land/face/strife/menus/stats/StatsEffectMenuItem.java
index 52b826ed..595b4d82 100644
--- a/src/main/java/land/face/strife/menus/stats/StatsEffectMenuItem.java
+++ b/src/main/java/land/face/strife/menus/stats/StatsEffectMenuItem.java
@@ -59,7 +59,7 @@ public ItemStack getFinalIcon(Player commandSender) {
lore.add(StatsMenu.breakLine);
List traitLores = new ArrayList<>();
- for (StrifeTrait trait : pStats.getChampion().getTraits()) {
+ for (StrifeTrait trait : pStats.getTraits()) {
traitLores.add(ChatColor.YELLOW + "❂ " + trait.getName());
}
@@ -69,8 +69,8 @@ public ItemStack getFinalIcon(Player commandSender) {
}
List abilityLores = new ArrayList<>();
- for (TriggerType triggerType : pStats.getChampion().getLoreAbilities().keySet()) {
- for (LoreAbility la : pStats.getChampion().getLoreAbilities().get(triggerType)) {
+ for (TriggerType triggerType : pStats.getLoreAbilities().keySet()) {
+ for (LoreAbility la : pStats.getLoreAbilities().get(triggerType)) {
abilityLores.add(la.getTriggerText());
abilityLores.addAll(la.getDescription());
}
diff --git a/src/main/java/land/face/strife/menus/stats/StatsOffenseMenuItem.java b/src/main/java/land/face/strife/menus/stats/StatsOffenseMenuItem.java
index bb50900c..ae3cd81c 100644
--- a/src/main/java/land/face/strife/menus/stats/StatsOffenseMenuItem.java
+++ b/src/main/java/land/face/strife/menus/stats/StatsOffenseMenuItem.java
@@ -116,9 +116,9 @@ public ItemStack getFinalIcon(Player commandSender) {
addIfApplicable(damageDisplay, trueDmg, ChatColor.GRAY, "Ω");
lore.add(damageDisplay.toString());
double criticalMult = 1;
- if (!mob.getChampion().getTraits().contains(StrifeTrait.NO_CRIT_MULT)) {
+ if (!mob.getTraits().contains(StrifeTrait.NO_CRIT_MULT)) {
float critDamage;
- if (mob.getChampion().getTraits().contains(StrifeTrait.ELEMENTAL_CRITS)) {
+ if (mob.getTraits().contains(StrifeTrait.ELEMENTAL_CRITS)) {
critDamage = physical + magical;
} else {
critDamage = total - trueDmg;
diff --git a/src/main/java/land/face/strife/tasks/BarrierTask.java b/src/main/java/land/face/strife/tasks/BarrierTask.java
index 48ad9108..7bb9d533 100644
--- a/src/main/java/land/face/strife/tasks/BarrierTask.java
+++ b/src/main/java/land/face/strife/tasks/BarrierTask.java
@@ -33,7 +33,7 @@ public BarrierTask(StrifeMob parentMob) {
@Override
public void run() {
StrifeMob mob = parentMob.get();
- if (mob == null || mob.getEntity() == null) {
+ if (mob == null || mob.getEntity() == null || !mob.getEntity().isValid()) {
cancel();
return;
}
diff --git a/src/main/java/land/face/strife/tasks/DamageOverTimeTask.java b/src/main/java/land/face/strife/tasks/DamageOverTimeTask.java
index 0ffa0df4..f512306f 100644
--- a/src/main/java/land/face/strife/tasks/DamageOverTimeTask.java
+++ b/src/main/java/land/face/strife/tasks/DamageOverTimeTask.java
@@ -22,15 +22,19 @@
import static org.bukkit.potion.PotionEffectType.POISON;
import static org.bukkit.potion.PotionEffectType.WITHER;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.Map;
import java.util.Objects;
import java.util.Set;
import land.face.strife.StrifePlugin;
import land.face.strife.data.StrifeMob;
+import land.face.strife.data.buff.LoadedBuff;
import land.face.strife.stats.StrifeStat;
import land.face.strife.util.DamageUtil;
import land.face.strife.util.StatUtil;
+import org.bukkit.Material;
import org.bukkit.entity.LivingEntity;
import org.bukkit.scheduler.BukkitRunnable;
@@ -47,6 +51,8 @@ public class DamageOverTimeTask extends BukkitRunnable {
private final Set burningMobs = new HashSet<>();
private final Set witheredMobs = new HashSet<>();
+ private final LoadedBuff lavaDebuff;
+
public DamageOverTimeTask(StrifePlugin plugin) {
this.plugin = plugin;
BURN_FLAT_DAMAGE = (float) plugin.getSettings()
@@ -57,6 +63,10 @@ public DamageOverTimeTask(StrifePlugin plugin) {
.getDouble("config.mechanics.poison-flat-damage");
POISON_PERCENT_MAX_HEALTH_DAMAGE = (float) plugin.getSettings()
.getDouble("config.mechanics.poison-percent-damage");
+
+ Map debuffMap = new HashMap<>();
+ debuffMap.put(StrifeStat.BURNING_RESIST, -12.5f);
+ lavaDebuff = new LoadedBuff("BUILT-IN-LAVA-DEBUFF", debuffMap, 200, 10);
}
public void trackPoison(LivingEntity livingEntity) {
@@ -133,12 +143,15 @@ private void dealFireDamage() {
StrifeMob mob = plugin.getStrifeMobManager().getStatMob(le);
damage *= 1 - StatUtil.getFireResist(mob, false) / 100;
+ damage *= 1 - mob.getStat(StrifeStat.BURNING_RESIST) / 100;
damage = mob.damageBarrier(damage);
if (damage < 0.05) {
continue;
}
+ if (le.getWorld().getBlockAt(le.getLocation()).getType() == Material.LAVA) {
+ mob.addBuff(LoadedBuff.toRunningBuff(lavaDebuff), 10);
+ }
damage = plugin.getDamageManager().doEnergyAbsorb(mob, damage);
-
DamageUtil.dealRawDamage(le, damage);
}
}
diff --git a/src/main/java/land/face/strife/tasks/EnergyTask.java b/src/main/java/land/face/strife/tasks/EnergyTask.java
index 4181c57d..d591ec3e 100644
--- a/src/main/java/land/face/strife/tasks/EnergyTask.java
+++ b/src/main/java/land/face/strife/tasks/EnergyTask.java
@@ -33,7 +33,7 @@ public EnergyTask(StrifeMob parentMob) {
@Override
public void run() {
StrifeMob mob = parentMob.get();
- if (mob == null || mob.getEntity() == null) {
+ if (mob == null || mob.getEntity() == null || !mob.getEntity().isValid()) {
cancel();
return;
}
@@ -42,11 +42,6 @@ public void run() {
return;
}
- if (!mob.getEntity().isValid()) {
- energyRestore.clear();
- return;
- }
-
if (mob.getEnergy() >= mob.getMaxEnergy()) {
mob.setEnergy(mob.getMaxEnergy());
getBonusEnergy();
diff --git a/src/main/java/land/face/strife/tasks/LifeTask.java b/src/main/java/land/face/strife/tasks/LifeTask.java
index 8fb1f94a..42e2ab04 100644
--- a/src/main/java/land/face/strife/tasks/LifeTask.java
+++ b/src/main/java/land/face/strife/tasks/LifeTask.java
@@ -34,14 +34,11 @@ public LifeTask(StrifeMob parentMob) {
@Override
public void run() {
StrifeMob mob = parentMob.get();
- if (mob == null || mob.getEntity() == null) {
+ if (mob == null || mob.getEntity() == null || !mob.getEntity().isValid()) {
cancel();
return;
}
- if (!mob.getEntity().isValid() || mob.getEntity().getHealth() <= 0) {
- lifeRestore.clear();
- return;
- }
+
double maxLife = mob.getEntity().getAttribute(Attribute.GENERIC_MAX_HEALTH).getBaseValue();
if (mob.getEntity().getHealth() >= maxLife) {
diff --git a/src/main/java/land/face/strife/tasks/MinionTask.java b/src/main/java/land/face/strife/tasks/MinionTask.java
index eb9b727f..33f39504 100644
--- a/src/main/java/land/face/strife/tasks/MinionTask.java
+++ b/src/main/java/land/face/strife/tasks/MinionTask.java
@@ -35,13 +35,13 @@ public void run() {
if (!mob.getEntity().getPassengers().isEmpty()) {
return;
}
+ lifespan--;
if (lifespan > 0) {
- lifespan--;
return;
}
if (lifespan <= -15) {
minionMob.getEntity().damage(minionMob.getEntity().getMaxHealth() * 10);
- } else {
+ } else {
minionMob.getEntity().damage(minionMob.getEntity().getMaxHealth() / 10);
}
}
@@ -50,4 +50,11 @@ public StrifeMob getMaster() {
return master.get();
}
+ public int getLifespan() {
+ return lifespan;
+ }
+
+ public void forceStartDeath() {
+ lifespan = Math.min(0, lifespan);
+ }
}
diff --git a/src/main/java/land/face/strife/util/BorderEffectUtil.java b/src/main/java/land/face/strife/util/BorderEffectUtil.java
index eca81fbd..0dd1dd50 100644
--- a/src/main/java/land/face/strife/util/BorderEffectUtil.java
+++ b/src/main/java/land/face/strife/util/BorderEffectUtil.java
@@ -88,6 +88,7 @@ private static void sendWorldBorderPacket(Player p, int dist, double oldradius,
}
public static void sendBorder(Player p, double percentage, int fadeTime) {
+ percentage = Math.max(0, Math.min(0.95, percentage));
setBorder(p, percentage);
fadeBorder(p, percentage, fadeTime);
}
diff --git a/src/main/java/land/face/strife/util/DamageUtil.java b/src/main/java/land/face/strife/util/DamageUtil.java
index 4f379855..4efc99c5 100644
--- a/src/main/java/land/face/strife/util/DamageUtil.java
+++ b/src/main/java/land/face/strife/util/DamageUtil.java
@@ -118,13 +118,11 @@ public static boolean isGuildAlly(StrifeMob attacker, Player target) {
public static boolean preDamage(StrifeMob attacker, StrifeMob defender, DamageModifiers mods) {
- if (attacker.getEntity() instanceof Player) {
- plugin.getChampionManager().updateEquipmentStats(
- plugin.getChampionManager().getChampion((Player) attacker.getEntity()));
+ if (attacker.isUseEquipment()) {
+ plugin.getStrifeMobManager().updateEquipmentStats(attacker);
}
- if (defender.getEntity() instanceof Player) {
- plugin.getChampionManager().updateEquipmentStats(
- plugin.getChampionManager().getChampion((Player) defender.getEntity()));
+ if (defender.isUseEquipment()) {
+ plugin.getStrifeMobManager().updateEquipmentStats(defender);
plugin.getStealthManager().unstealthPlayer((Player) defender.getEntity());
}
@@ -164,11 +162,9 @@ public static boolean preDamage(StrifeMob attacker, StrifeMob defender, DamageMo
public static Map buildDamage(StrifeMob attacker, StrifeMob defender, DamageModifiers mods) {
Map damageMap = DamageUtil.buildDamageMap(attacker, defender, mods);
applyAttackTypeMods(attacker, mods.getAttackType(), damageMap);
- applyElementalEffects(attacker, defender, damageMap, mods);
return damageMap;
}
-
public static void reduceDamage(StrifeMob attacker, StrifeMob defender,
Map damageMap, DamageModifiers mods) {
DamageUtil.applyDamageReductions(attacker, defender, damageMap, mods.getAbilityMods());
@@ -252,6 +248,9 @@ public static float calculateFinalDamage(StrifeMob attacker, StrifeMob defender,
}
public static void postDamage(StrifeMob attacker, StrifeMob defender, DamageModifiers mods) {
+ if (mods.getAttackType() == AttackType.BONUS) {
+ return;
+ }
float ratio = mods.getDamageReductionRatio();
DamageUtil.applyHealthOnHit(attacker, ratio, mods.getHealMultiplier(),
@@ -436,6 +435,9 @@ public static void applyDamageReductions(StrifeMob attacker, StrifeMob defender,
}
public static void applyAttackTypeMods(StrifeMob attacker, AttackType attackType, Map damageMap) {
+ if (attackType == AttackType.BONUS) {
+ return;
+ }
if (damageMap.containsKey(DamageType.PHYSICAL)) {
float physicalDamage = damageMap.get(DamageType.PHYSICAL);
float physicalMult = attacker.getStat(StrifeStat.PHYSICAL_MULT);
@@ -472,28 +474,18 @@ public static void applyAttackTypeMods(StrifeMob attacker, AttackType attackType
}
}
- private static void applyElementalEffects(StrifeMob attacker, StrifeMob defender, Map damageMap,
+ public static void applyElementalEffects(StrifeMob attacker, StrifeMob defender, Map damageMap,
DamageModifiers mods) {
- int runes = plugin.getBlockManager().getEarthRunes(attacker.getEntity());
- if (damageMap.containsKey(DamageType.EARTH) && runes > 0) {
- damageMap.put(DamageType.EARTH, damageMap.get(DamageType.EARTH) * (1 + runes * 0.08f));
- if (mods.isConsumeEarthRunes()) {
- damageMap.put(DamageType.EARTH, damageMap.get(DamageType.EARTH) + StatUtil.getHealth(attacker) * 0.1f);
- plugin.getBlockManager().setEarthRunes(attacker, runes - 1);
- }
- }
- if (damageMap.containsKey(DamageType.FIRE) && defender.getEntity().getFireTicks() > 0) {
- damageMap.put(DamageType.FIRE, damageMap.get(DamageType.FIRE) * 1.5f);
- }
float darkDamage = damageMap.getOrDefault(DamageType.DARK, 0f);
if (darkDamage != 0) {
damageMap.put(DamageType.DARK, darkDamage * getDarknessManager().getCorruptionMult(defender.getEntity()));
}
- float chance = attacker.getStat(StrifeStat.ELEMENTAL_STATUS) / 100;
+ float chance = (mods.getAbilityMods().getOrDefault(AbilityMod.STATUS_CHANCE, 0f) +
+ attacker.getStat(StrifeStat.ELEMENTAL_STATUS)) / 100;
if (mods.isScaleChancesWithAttack()) {
- chance *= mods.getAttackMultiplier();
+ chance *= Math.min(1.0, mods.getAttackMultiplier());
}
- if (!DamageUtil.rollBool(chance, true)) {
+ if (mods.getAttackType() == AttackType.BONUS || !DamageUtil.rollBool(chance, true)) {
return;
}
float totalElementalDamage = 0;
@@ -542,6 +534,13 @@ private static void applyElementalEffects(StrifeMob attacker, StrifeMob defender
mods.getElementalStatuses().add(ElementalStatus.CORRUPT);
applyCorrupt(defender.getEntity(), 5 + darkDamage / 3);
break;
+ case EARTH:
+ mods.getElementalStatuses().add(ElementalStatus.CRUNCH);
+ int runes = plugin.getBlockManager().getEarthRunes(attacker.getEntity());
+ float maxLife = (float) attacker.getEntity().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
+ float newDamage = damageMap.get(DamageType.EARTH) * 1.1f + (runes * 0.02f * maxLife);
+ damageMap.put(DamageType.EARTH, newDamage);
+ break;
case LIGHT:
bonus = getLightBonus(damageMap.get(finalElementType), attacker, defender.getEntity());
if (bonus > damageMap.get(finalElementType) / 2) {
@@ -772,7 +771,7 @@ public static void applyEnergyOnHit(StrifeMob attacker, float attackMultiplier,
public static boolean attemptBleed(StrifeMob attacker, StrifeMob defender, float rawPhysical,
DamageModifiers mods, boolean bypassBarrier) {
- if (defender.getBarrier() > 0) {
+ if (defender.getBarrier() > 0 || mods.getAttackType() == AttackType.BONUS) {
return false;
}
if (defender.getStat(StrifeStat.BLEED_RESIST) > 99) {
@@ -988,10 +987,11 @@ public enum AbilityMod {
LIFE_STEAL,
HEALTH_ON_HIT,
BLEED_CHANCE,
- BLEED_DAMAGE
+ BLEED_DAMAGE,
+ STATUS_CHANCE
}
public enum AttackType {
- MELEE, PROJECTILE, AREA, OTHER
+ MELEE, PROJECTILE, AREA, OTHER, BONUS
}
}
diff --git a/src/main/java/land/face/strife/util/PlayerDataUtil.java b/src/main/java/land/face/strife/util/PlayerDataUtil.java
index 330bab30..9e07fba4 100644
--- a/src/main/java/land/face/strife/util/PlayerDataUtil.java
+++ b/src/main/java/land/face/strife/util/PlayerDataUtil.java
@@ -267,8 +267,8 @@ public static boolean areConditionsMet(StrifeMob caster, StrifeMob target, Set getStatMapFromSection(ConfigurationSection
return statMap;
}
+ public static Map getSkillMapFromSection(ConfigurationSection skillSection) {
+ Map skillMap = new HashMap<>();
+ if (skillSection == null) {
+ return skillMap;
+ }
+ for (String skillString : skillSection.getKeys(false)) {
+ LifeSkillType strifeStat;
+ try {
+ strifeStat = LifeSkillType.valueOf(skillString);
+ } catch (Exception e) {
+ LogUtil.printWarning("Invalid skill " + skillString + ". Skipping...");
+ continue;
+ }
+ skillMap.put(strifeStat, (float) skillSection.getDouble(skillString));
+ }
+ return skillMap;
+ }
+
+ public static Map getAttributeMapFromSection(ConfigurationSection attrSection) {
+ Map attributeMap = new HashMap<>();
+ if (attrSection == null) {
+ return attributeMap;
+ }
+ for (String attrString : attrSection.getKeys(false)) {
+ StrifeAttribute strifeAttr = StrifePlugin.getInstance()
+ .getAttributeManager().getAttribute(attrString);
+ if (strifeAttr == null) {
+ LogUtil.printWarning("Invalid attribute " + attrString + ". Skipping...");
+ } else {
+ attributeMap.put(strifeAttr, (float) attrSection.getDouble(attrString));
+ }
+ }
+ return attributeMap;
+ }
+
public static int getMobLevel(LivingEntity livingEntity) {
if (livingEntity instanceof Player) {
return ((Player) livingEntity).getLevel();