Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 135 additions & 0 deletions core/src/main/java/com/nisovin/magicspells/spells/buff/ProxySpell.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package com.nisovin.magicspells.spells.buff;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import org.jetbrains.annotations.NotNull;

import org.bukkit.entity.LivingEntity;
import org.bukkit.event.Listener;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageByEntityEvent;

import com.nisovin.magicspells.events.SpellTargetEvent;
import com.nisovin.magicspells.events.SpellPreImpactEvent;
import com.nisovin.magicspells.events.MagicSpellsEntityDamageByEntityEvent;
import com.nisovin.magicspells.spells.BuffSpell;
import com.nisovin.magicspells.spelleffects.EffectPosition;
import com.nisovin.magicspells.util.MagicConfig;
import com.nisovin.magicspells.util.SpellData;
Comment thread
JasperLorelai marked this conversation as resolved.
Outdated

public class ProxySpell extends BuffSpell implements Listener {
Comment thread
JasperLorelai marked this conversation as resolved.
Outdated

private final Map<UUID, SpellData> proxies;
Comment thread
JasperLorelai marked this conversation as resolved.
Outdated
private final Set<UUID> redirecting;

public ProxySpell(MagicConfig config, String spellName) {
super(config, spellName);

proxies = new HashMap<>();
redirecting = new HashSet<>();
}
Comment thread
JasperLorelai marked this conversation as resolved.
Outdated

@Override
public boolean castBuff(SpellData data) {
proxies.put(data.target().getUniqueId(), data);
return true;
}

@Override
public boolean recastBuff(SpellData data) {
stopEffects(data.target());
Comment thread
DragonsAscent marked this conversation as resolved.
return castBuff(data);
}

@Override
public boolean isActive(LivingEntity entity) {
return proxies.containsKey(entity.getUniqueId());
}

@Override
public void turnOffBuff(LivingEntity entity) {
proxies.remove(entity.getUniqueId());
}

@Override
protected @NotNull Collection<UUID> getActiveEntities() {
return proxies.keySet();
}

@EventHandler(ignoreCancelled = true)
public void onSpellTarget(SpellTargetEvent event) {
LivingEntity target = event.getTarget();
if (target == null || !target.isValid()) return;

LivingEntity proxyTarget = getProxyTarget(target);
if (proxyTarget == null) return;

SpellData subData = event.getSpellData().target(proxyTarget);
playRedirectEffects(target, proxyTarget, subData);

event.setTarget(proxyTarget);
Comment thread
JasperLorelai marked this conversation as resolved.
Comment thread
DragonsAscent marked this conversation as resolved.
Outdated
addUseAndChargeCost(target);
}

@EventHandler(ignoreCancelled = true)
public void onSpellPreImpact(SpellPreImpactEvent event) {
LivingEntity target = event.getTarget();
if (target == null || !target.isValid()) return;

LivingEntity proxyTarget = getProxyTarget(target);
if (proxyTarget == null) return;

SpellData subData = new SpellData(event.getCaster(), proxyTarget, event.getPower());
playRedirectEffects(target, proxyTarget, subData);

event.setRedirected(true);
Comment thread
JasperLorelai marked this conversation as resolved.
Outdated
addUseAndChargeCost(target);
}

@EventHandler(ignoreCancelled = true)
Comment thread
JasperLorelai marked this conversation as resolved.
Outdated
public void onEntityDamage(EntityDamageByEntityEvent event) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the proxy receive damage from events not dealt by another entity?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel like it should be a config option

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, idk. The only purpose the damager has in this handler atm is that it's used for the spell effects. So imo, if a proxy receives any damage, it should be relayed, even if it wasn't caused by a third entity.

if (!(event.getEntity() instanceof LivingEntity target) || !target.isValid()) return;

LivingEntity proxyTarget = getProxyTarget(target);
if (proxyTarget == null) return;
if (!redirecting.add(proxyTarget.getUniqueId())) return;

SpellData subData = new SpellData(event.getDamager() instanceof LivingEntity damager ? damager : null, proxyTarget);
playRedirectEffects(target, proxyTarget, subData);

event.setCancelled(true);
try {
proxyTarget.damage(event.getDamage(), event.getDamager());
Comment thread
DragonsAscent marked this conversation as resolved.
Outdated
addUseAndChargeCost(target);
} finally {
redirecting.remove(proxyTarget.getUniqueId());
}
}

@EventHandler(ignoreCancelled = true)
public void onLegacyDamage(MagicSpellsEntityDamageByEntityEvent event) {
onEntityDamage(event);
}

Comment thread
DragonsAscent marked this conversation as resolved.
Outdated
private LivingEntity getProxyTarget(LivingEntity target) {
SpellData proxyData = proxies.get(target.getUniqueId());
if (proxyData == null) return null;

LivingEntity proxyTarget = proxyData.caster();
if (proxyTarget != null && proxyTarget.isValid()) return proxyTarget;

turnOff(target);
return null;
}

private void playRedirectEffects(LivingEntity target, LivingEntity proxyTarget, SpellData data) {
playSpellEffects(EffectPosition.TARGET, target, data);
Comment thread
DragonsAscent marked this conversation as resolved.
Outdated
playSpellEffects(EffectPosition.END_POSITION, proxyTarget, data);
}

}
Loading