Skip to content

Commit 8bc2d7d

Browse files
authored
Merge pull request #600 from Chronoken/main
Add `potion-effects` to PotionEffectSpell, cleanup, targeting fixes for Subspells
2 parents 1f20076 + e43899e commit 8bc2d7d

5 files changed

Lines changed: 156 additions & 67 deletions

File tree

core/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
plugins {
22
id("org.jetbrains.kotlin.jvm") version "1.7.0"
3-
id("io.papermc.paperweight.userdev") version "1.3.8-SNAPSHOT"
3+
id("io.papermc.paperweight.userdev") version "1.3.8"
44
id("com.github.johnrengelman.shadow") version "7.1.2"
55
id("dev.magicspells.mspaperweight")
66
}
77

88
dependencies {
99
shadow(group: "org.apache.commons", name: "commons-math3", version: "3.6.1")
10-
shadow(group: "com.github.Chronoken", name: "EffectLib", version: "f3259bd357")
10+
shadow(group: "com.github.Chronoken", name: "EffectLib", version: "1be5ee7fd7")
1111
shadow(group: "co.aikar", name: "acf-paper", version: "0.5.0-SNAPSHOT")
1212
shadow(group: "org.jetbrains.kotlin", name: "kotlin-stdlib-jdk8", version: "1.7.0")
1313

core/src/main/java/com/nisovin/magicspells/MagicSpells.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -367,11 +367,7 @@ public void load() {
367367
boolean opsIgnoreReagents = config.getBoolean(path + "ops-ignore-reagents", true);
368368
boolean opsIgnoreCooldowns = config.getBoolean(path + "ops-ignore-cooldowns", true);
369369
boolean opsIgnoreCastTimes = config.getBoolean(path + "ops-ignore-cast-times", true);
370-
addPermission(pm, "noreagents", opsIgnoreReagents? PermissionDefault.OP : PermissionDefault.FALSE, "Allows casting without needing reagents");
371-
addPermission(pm, "nocooldown", opsIgnoreCooldowns? PermissionDefault.OP : PermissionDefault.FALSE, "Allows casting without being affected by cooldowns");
372-
addPermission(pm, "nocasttime", opsIgnoreCastTimes? PermissionDefault.OP : PermissionDefault.FALSE, "Allows casting without being affected by cast times");
373-
addPermission(pm, "notarget", PermissionDefault.FALSE, "Prevents being targeted by any targeted spells");
374-
addPermission(pm, "silent", PermissionDefault.FALSE, "Prevents cast messages from being broadcast to players");
370+
375371
Map<String, Boolean> permGrantChildren = new HashMap<>();
376372
Map<String, Boolean> permLearnChildren = new HashMap<>();
377373
Map<String, Boolean> permCastChildren = new HashMap<>();
@@ -439,6 +435,13 @@ public void load() {
439435
addPermission(pm, "cast.*", defaultAllPermsFalse ? PermissionDefault.FALSE : PermissionDefault.TRUE, permCastChildren);
440436
addPermission(pm, "teach.*", defaultAllPermsFalse ? PermissionDefault.FALSE : PermissionDefault.TRUE, permTeachChildren);
441437

438+
// Op permissions
439+
addPermission(pm, "noreagents", opsIgnoreReagents? PermissionDefault.OP : PermissionDefault.FALSE, "Allows casting without needing reagents");
440+
addPermission(pm, "nocooldown", opsIgnoreCooldowns? PermissionDefault.OP : PermissionDefault.FALSE, "Allows casting without being affected by cooldowns");
441+
addPermission(pm, "nocasttime", opsIgnoreCastTimes? PermissionDefault.OP : PermissionDefault.FALSE, "Allows casting without being affected by cast times");
442+
addPermission(pm, "notarget", PermissionDefault.FALSE, "Prevents being targeted by any targeted spells");
443+
addPermission(pm, "silent", PermissionDefault.FALSE, "Prevents cast messages from being broadcast to players");
444+
442445
// Advanced permissions
443446
addPermission(pm, "advanced.list", PermissionDefault.FALSE);
444447
addPermission(pm, "advanced.forget", PermissionDefault.FALSE);

core/src/main/java/com/nisovin/magicspells/Subspell.java

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,12 @@ private boolean castAtEntityReal(LivingEntity caster, LivingEntity target, float
174174

175175
if (!spellTarget.isCancelled()) {
176176
if (passTargeting) success = passTargetingEntity(caster, target, power);
177-
else success = ((TargetedEntitySpell) spell).castAtEntity(caster, target, power);
177+
else {
178+
success = spell.getValidTargetList().canTarget(caster, target);
179+
if (!success) return false;
180+
181+
success = ((TargetedEntitySpell) spell).castAtEntity(caster, target, power);
182+
}
178183
}
179184

180185
if (success) {
@@ -205,6 +210,9 @@ private boolean castAtEntityReal(LivingEntity caster, LivingEntity target, float
205210
if (!spellTarget.isCancelled() && !event.isCancelled() && event.getSpellCastState() == SpellCastState.NORMAL) {
206211
if (passTargeting) success = passTargetingEntity(caster, target, power);
207212
else {
213+
success = caster != null ? spell.getValidTargetList().canTarget(caster, target) : spell.getValidTargetList().canTarget(target);
214+
if (!success) return false;
215+
208216
if (caster != null) success = ((TargetedEntitySpell) spell).castAtEntity(caster, target, power);
209217
else success = ((TargetedEntitySpell) spell).castAtEntity(target, power);
210218
}
@@ -213,6 +221,9 @@ private boolean castAtEntityReal(LivingEntity caster, LivingEntity target, float
213221
} else {
214222
if (passTargeting) success = passTargetingEntity(caster, target, power * subPower);
215223
else {
224+
success = caster != null ? spell.getValidTargetList().canTarget(caster, target) : spell.getValidTargetList().canTarget(target);
225+
if (!success) return false;
226+
216227
if (caster != null) success = ((TargetedEntitySpell) spell).castAtEntity(caster, target, power * subPower);
217228
else success = ((TargetedEntitySpell) spell).castAtEntity(target, power * subPower);
218229
}
@@ -221,20 +232,6 @@ private boolean castAtEntityReal(LivingEntity caster, LivingEntity target, float
221232
return success;
222233
}
223234

224-
public boolean passTargetingEntity(LivingEntity caster, LivingEntity target, float power) {
225-
ValidTargetList list = spell.getValidTargetList();
226-
ValidTargetList originalList = list.clone();
227-
if (caster.equals(target) && !list.canTargetSelf()) list.setTargetCaster(true);
228-
if (!list.canTargetEntity(target)) {
229-
list.addEntityTarget(target);
230-
spell.setValidTargetList(list);
231-
}
232-
233-
boolean success = caster != null ? ((TargetedEntitySpell) spell).castAtEntity(caster, target, power) : ((TargetedEntitySpell) spell).castAtEntity(target, power);
234-
spell.setValidTargetList(originalList);
235-
return success;
236-
}
237-
238235
public boolean castAtLocation(final LivingEntity caster, final Location target, final float power) {
239236
if (delay < 0) return castAtLocationReal(caster, target, power);
240237
MagicSpells.scheduleDelayedTask(() -> castAtLocationReal(caster, target, power), delay);
@@ -332,7 +329,12 @@ private boolean castAtEntityFromLocationReal(LivingEntity caster, Location from,
332329

333330
if (!spellLocation.isCancelled() && !spellTarget.isCancelled()) {
334331
if (passTargeting) success = passTargetingEntityFromLocation(caster, from, target, power);
335-
else success = ((TargetedEntityFromLocationSpell) spell).castAtEntityFromLocation(caster, from, target, power);
332+
else {
333+
success = spell.getValidTargetList().canTarget(caster, target);
334+
if (!success) return false;
335+
336+
success = ((TargetedEntityFromLocationSpell) spell).castAtEntityFromLocation(caster, from, target, power);
337+
}
336338
}
337339
if (success) {
338340
if (spell instanceof TargetedSpell targetedSpell) {
@@ -366,6 +368,9 @@ private boolean castAtEntityFromLocationReal(LivingEntity caster, Location from,
366368
if (!spellLocation.isCancelled() && !spellTarget.isCancelled() && !event.isCancelled() && event.getSpellCastState() == SpellCastState.NORMAL) {
367369
if (passTargeting) success = passTargetingEntityFromLocation(caster, from, target, power);
368370
else {
371+
success = caster != null ? spell.getValidTargetList().canTarget(caster, target) : spell.getValidTargetList().canTarget(target);
372+
if (!success) return false;
373+
369374
if (caster != null) success = ((TargetedEntityFromLocationSpell) spell).castAtEntityFromLocation(caster, from, target, power);
370375
else success = ((TargetedEntityFromLocationSpell) spell).castAtEntityFromLocation(from, target, power);
371376
}
@@ -374,6 +379,9 @@ private boolean castAtEntityFromLocationReal(LivingEntity caster, Location from,
374379
} else {
375380
if (passTargeting) success = passTargetingEntityFromLocation(caster, from, target, power * subPower);
376381
else {
382+
success = caster != null ? spell.getValidTargetList().canTarget(caster, target) : spell.getValidTargetList().canTarget(target);
383+
if (!success) return false;
384+
377385
if (caster != null) success = ((TargetedEntityFromLocationSpell) spell).castAtEntityFromLocation(caster, from, target, power * subPower);
378386
else success = ((TargetedEntityFromLocationSpell) spell).castAtEntityFromLocation(from, target, power * subPower);
379387
}
@@ -382,6 +390,24 @@ private boolean castAtEntityFromLocationReal(LivingEntity caster, Location from,
382390
return success;
383391
}
384392

393+
public boolean passTargetingEntity(LivingEntity caster, LivingEntity target, float power) {
394+
ValidTargetList list = spell.getValidTargetList();
395+
ValidTargetList originalList = list.clone();
396+
if (caster.equals(target) && !list.canTargetSelf()) list.setTargetCaster(true);
397+
if (!list.canTargetEntity(target)) {
398+
list.addEntityTarget(target);
399+
spell.setValidTargetList(list);
400+
}
401+
402+
// handle targeting
403+
boolean success = caster != null ? list.canTarget(caster, target) : list.canTarget(target);
404+
if (!success) return false;
405+
406+
success = caster != null ? ((TargetedEntitySpell) spell).castAtEntity(caster, target, power) : ((TargetedEntitySpell) spell).castAtEntity(target, power);
407+
spell.setValidTargetList(originalList);
408+
return success;
409+
}
410+
385411
public boolean passTargetingEntityFromLocation(LivingEntity caster, Location from, LivingEntity target, float power) {
386412
ValidTargetList list = spell.getValidTargetList();
387413
ValidTargetList originalList = list.clone();
@@ -391,7 +417,11 @@ public boolean passTargetingEntityFromLocation(LivingEntity caster, Location fro
391417
spell.setValidTargetList(list);
392418
}
393419

394-
boolean success = caster != null ? ((TargetedEntityFromLocationSpell) spell).castAtEntityFromLocation(caster, from, target, power) : ((TargetedEntityFromLocationSpell) spell).castAtEntityFromLocation(from, target, power);
420+
// handle targeting
421+
boolean success = caster != null ? list.canTarget(caster, target) : list.canTarget(target);
422+
if (!success) return false;
423+
424+
success = caster != null ? ((TargetedEntityFromLocationSpell) spell).castAtEntityFromLocation(caster, from, target, power) : ((TargetedEntityFromLocationSpell) spell).castAtEntityFromLocation(from, target, power);
395425
spell.setValidTargetList(originalList);
396426
return success;
397427
}

core/src/main/java/com/nisovin/magicspells/handlers/PotionEffectHandler.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public enum PotionEffectHandler {
1919
CONFUSION("nausea"),
2020
REGENERATION("regeneration"),
2121
DAMAGE_RESISTANCE("resistance"),
22+
DARKNESS("darkness"),
2223
FIRE_RESISTANCE("fire_resistance"),
2324
WATER_BREATHING("water_breathing"),
2425
INVISIBILITY("invisibility"),
@@ -55,13 +56,13 @@ private static void initialize() {
5556

5657
namesToType = new HashMap<>();
5758

58-
for (PotionEffectHandler pe: PotionEffectHandler.values()) {
59-
PotionEffectType type = PotionEffectType.getByName(pe.name());
59+
for (PotionEffectHandler potionEffect : PotionEffectHandler.values()) {
60+
PotionEffectType type = PotionEffectType.getByName(potionEffect.name());
6061
if (type == null) continue;
6162

6263
// handle the names
63-
namesToType.put(pe.name().toLowerCase(), type);
64-
for (String s: pe.names) {
64+
namesToType.put(potionEffect.name().toLowerCase(), type);
65+
for (String s: potionEffect.names) {
6566
namesToType.put(s.toLowerCase(), type);
6667
}
6768
}
Lines changed: 94 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
package com.nisovin.magicspells.spells.targeted;
22

3+
import java.util.Set;
4+
import java.util.List;
5+
import java.util.HashSet;
6+
import java.util.ArrayList;
7+
38
import org.bukkit.entity.LivingEntity;
49
import org.bukkit.potion.PotionEffect;
510
import org.bukkit.potion.PotionEffectType;
@@ -14,36 +19,88 @@
1419
import com.nisovin.magicspells.spelleffects.EffectPosition;
1520
import com.nisovin.magicspells.events.SpellApplyDamageEvent;
1621

22+
import org.apache.commons.math3.util.FastMath;
23+
1724
public class PotionEffectSpell extends TargetedSpell implements TargetedEntitySpell {
18-
25+
26+
private Set<PotionEffect> potionEffects;
27+
28+
private List<String> potionEffectData;
29+
1930
private PotionEffectType type;
31+
private PotionEffect potionEffect;
2032

2133
private int duration;
2234
private int strength;
2335

36+
private boolean icon;
2437
private boolean hidden;
2538
private boolean ambient;
26-
private boolean targeted;
2739

2840
private boolean override;
2941
private boolean spellPowerAffectsDuration;
3042
private boolean spellPowerAffectsStrength;
3143

3244
public PotionEffectSpell(MagicConfig config, String spellName) {
3345
super(config, spellName);
34-
35-
type = Util.getPotionEffectType(getConfigString("type", "1"));
46+
47+
//Format: <PotionType> <Duration> <Strength> <Hidden> <Ambient> <Icon>
48+
potionEffectData = getConfigStringList("potion-effects", new ArrayList<>());
49+
potionEffects = new HashSet<>();
50+
51+
type = Util.getPotionEffectType(getConfigString("type", "speed"));
3652

3753
duration = getConfigInt("duration", 0);
3854
strength = getConfigInt("strength", 0);
3955

56+
icon = getConfigBoolean("icon", true);
4057
hidden = getConfigBoolean("hidden", false);
4158
ambient = getConfigBoolean("ambient", false);
42-
targeted = getConfigBoolean("targeted", false);
4359
override = getConfigBoolean("override", false);
60+
4461
spellPowerAffectsDuration = getConfigBoolean("spell-power-affects-duration", true);
4562
spellPowerAffectsStrength = getConfigBoolean("spell-power-affects-strength", true);
4663
}
64+
65+
@Override
66+
public void initialize() {
67+
super.initialize();
68+
69+
if (type != null) potionEffect = new PotionEffect(type, duration, strength, ambient, !hidden, icon);
70+
71+
if (potionEffectData.isEmpty()) return;
72+
73+
PotionEffect p;
74+
75+
PotionEffectType t = null;
76+
int d = 0;
77+
int s = 0;
78+
boolean h = false;
79+
boolean a = false;
80+
boolean i = true;
81+
82+
for (String str : potionEffectData) {
83+
String[] args = str.split(" ");
84+
85+
if (args.length <= 0) continue;
86+
87+
if (args.length >= 1) t = Util.getPotionEffectType(args[0]);
88+
if (args.length >= 2) d = Integer.parseInt(args[1]);
89+
if (args.length >= 3) s = Integer.parseInt(args[2]);
90+
if (args.length >= 4) h = Boolean.parseBoolean(args[3]);
91+
if (args.length >= 5) a = Boolean.parseBoolean(args[4]);
92+
if (args.length >= 6) i = Boolean.parseBoolean(args[5]);
93+
94+
if (t == null) continue;
95+
p = new PotionEffect(t, d, s, h, a, i);
96+
potionEffects.add(p);
97+
}
98+
99+
}
100+
101+
public Set<PotionEffect> getPotionEffects() {
102+
return potionEffects;
103+
}
47104

48105
public PotionEffectType getPotionType() {
49106
return type;
@@ -56,25 +113,15 @@ public int getDuration() {
56113
@Override
57114
public PostCastAction castSpell(LivingEntity caster, SpellCastState state, float power, String[] args) {
58115
if (state == SpellCastState.NORMAL) {
59-
LivingEntity target = null;
60-
if (targeted) {
61-
TargetInfo<LivingEntity> targetInfo = getTargetedEntity(caster, power);
62-
if (targetInfo != null) {
63-
target = targetInfo.getTarget();
64-
power = targetInfo.getPower();
65-
}
66-
} else target = caster;
67-
68-
if (target == null) return noTarget(caster);
69-
70-
int dur = spellPowerAffectsDuration ? Math.round(duration * power) : duration;
71-
int str = spellPowerAffectsStrength ? Math.round(strength * power) : strength;
72-
73-
applyPotionEffect(caster, target, new PotionEffect(type, dur, str, ambient, !hidden));
74-
if (targeted) playSpellEffects(caster, target);
75-
else playSpellEffects(EffectPosition.CASTER, caster);
116+
TargetInfo<LivingEntity> targetInfo = getTargetedEntity(caster, power);
117+
if (targetInfo == null) return noTarget(caster);
118+
119+
LivingEntity target = targetInfo.getTarget();
76120

121+
handlePotionEffects(caster, target, power);
122+
playSpellEffects(caster, target);
77123
sendMessages(caster, target, args);
124+
78125
return PostCastAction.NO_MESSAGES;
79126
}
80127
return PostCastAction.HANDLE_NORMALLY;
@@ -83,37 +130,45 @@ public PostCastAction castSpell(LivingEntity caster, SpellCastState state, float
83130
@Override
84131
public boolean castAtEntity(LivingEntity caster, LivingEntity target, float power) {
85132
if (!validTargetList.canTarget(caster, target)) return false;
86-
int dur = spellPowerAffectsDuration ? Math.round(duration * power) : duration;
87-
int str = spellPowerAffectsStrength ? Math.round(strength * power) : strength;
88-
PotionEffect effect = new PotionEffect(type, dur, str, ambient, !hidden);
89-
if (targeted) {
90-
applyPotionEffect(caster, target, effect);
91-
playSpellEffects(caster, target);
92-
} else {
93-
applyPotionEffect(caster, caster, effect);
94-
playSpellEffects(EffectPosition.CASTER, caster);
95-
}
133+
handlePotionEffects(caster, target, power);
134+
playSpellEffects(caster, target);
96135
return true;
97136
}
98137

99138
@Override
100139
public boolean castAtEntity(LivingEntity target, float power) {
101140
if (!validTargetList.canTarget(target)) return false;
102-
int dur = spellPowerAffectsDuration ? Math.round(duration * power) : duration;
103-
int str = spellPowerAffectsStrength ? Math.round(strength * power) : strength;
104-
PotionEffect effect = new PotionEffect(type, dur, str, ambient, !hidden);
105-
applyPotionEffect(null, target, effect);
141+
handlePotionEffects(null, target, power);
106142
playSpellEffects(EffectPosition.TARGET, target);
107143
return true;
108144
}
109145

110-
private void applyPotionEffect(LivingEntity caster, LivingEntity target, PotionEffect effect) {
146+
private void handlePotionEffects(LivingEntity caster, LivingEntity target, float power) {
147+
if (potionEffects.isEmpty()) {
148+
applyPotionEffect(caster, target, potionEffect, power);
149+
return;
150+
}
151+
152+
for (PotionEffect effect : potionEffects) {
153+
applyPotionEffect(caster, target, effect, power);
154+
}
155+
}
156+
157+
private void applyPotionEffect(LivingEntity caster, LivingEntity target, PotionEffect effect, float power) {
158+
if (effect == null) return;
159+
111160
DamageCause cause = null;
112161
if (effect.getType() == PotionEffectType.POISON) cause = DamageCause.POISON;
113162
else if (effect.getType() == PotionEffectType.WITHER) cause = DamageCause.WITHER;
114-
if (cause != null) EventUtil.call(new SpellApplyDamageEvent(this, caster, target, effect.getAmplifier(), cause, ""));
163+
164+
int d = spellPowerAffectsDuration ? FastMath.round(effect.getDuration() * power) : effect.getDuration();
165+
int s = spellPowerAffectsStrength ? FastMath.round(effect.getAmplifier() * power) : effect.getAmplifier();
166+
167+
if (cause != null) EventUtil.call(new SpellApplyDamageEvent(this, caster, target, s, cause, ""));
168+
115169
if (override && target.hasPotionEffect(effect.getType())) target.removePotionEffect(effect.getType());
116-
target.addPotionEffect(effect);
170+
171+
target.addPotionEffect(new PotionEffect(effect.getType(), d, s, effect.isAmbient(), effect.hasParticles(), effect.hasIcon()));
117172
}
118173

119174
}

0 commit comments

Comments
 (0)