Merge pull request #584 from SettingDust/bugfix/lighting-web-concurrent-modification

Try to fix lighting web concurrent modification
This commit is contained in:
Electroblob
2020-12-21 16:39:15 +00:00
committed by GitHub
@@ -49,52 +49,62 @@ public class LightningWeb extends SpellRay {
protected void playSound(World world, double x, double y, double z, int ticksInUse, int duration, SpellModifiers modifiers, String... sounds){ protected void playSound(World world, double x, double y, double z, int ticksInUse, int duration, SpellModifiers modifiers, String... sounds){
this.playSoundLoop(world, x, y, z, ticksInUse, duration); this.playSoundLoop(world, x, y, z, ticksInUse, duration);
} }
@Override @Override
protected boolean onEntityHit(World world, Entity target, Vec3d hit, EntityLivingBase caster, Vec3d origin, int ticksInUse, SpellModifiers modifiers){ protected boolean onEntityHit(World world, Entity target, Vec3d hit, EntityLivingBase caster, Vec3d origin, int ticksInUse, SpellModifiers modifiers){
if(EntityUtils.isLiving(target)){ if(EntityUtils.isLiving(target)){
electrocute(world, caster, origin, target, getProperty(PRIMARY_DAMAGE).floatValue() electrocute(world, caster, origin, target, getProperty(PRIMARY_DAMAGE).floatValue()
* modifiers.get(SpellModifiers.POTENCY), ticksInUse); * modifiers.get(SpellModifiers.POTENCY), ticksInUse);
// Secondary chaining effect
List<EntityLivingBase> secondaryTargets = EntityUtils.getLivingWithinRadius( // Secondary chaining effect
getProperty(SECONDARY_RANGE).floatValue(), target.posX, target.posY + target.height / 2,
target.posZ, world);
secondaryTargets.remove(target);
secondaryTargets.removeIf(e -> !EntityUtils.isLiving(e));
secondaryTargets.removeIf(e -> !AllyDesignationSystem.isValidTarget(caster, e));
if(secondaryTargets.size() > getProperty(SECONDARY_MAX_TARGETS).intValue())
secondaryTargets = secondaryTargets.subList(0, getProperty(SECONDARY_MAX_TARGETS).intValue());
for(EntityLivingBase secondaryTarget : secondaryTargets){ List<EntityLivingBase> secondaryTargets = EntityUtils.getLivingWithinRadius(
getProperty(SECONDARY_RANGE).floatValue(), target.posX, target.posY + target.height / 2,
target.posZ, world);
electrocute(world, caster, target.getPositionVector().add(0, target.height/2, 0), secondaryTarget, secondaryTargets.stream()
getProperty(SECONDARY_DAMAGE).floatValue() * modifiers.get(SpellModifiers.POTENCY), ticksInUse); .filter(entity -> !entity.equals(target))
.filter(EntityUtils::isLiving)
.filter(e -> AllyDesignationSystem.isValidTarget(caster, e))
.limit(getProperty(SECONDARY_MAX_TARGETS).intValue())
.forEach(secondaryTarget -> {
electrocute(world, caster,
target.getPositionVector().add(0, target.height / 2, 0),
secondaryTarget,
getProperty(SECONDARY_DAMAGE).floatValue() * modifiers.get(SpellModifiers.POTENCY),
ticksInUse
);
// Tertiary chaining effect // Tertiary chaining effect
List<EntityLivingBase> tertiaryTargets = EntityUtils.getLivingWithinRadius( List<EntityLivingBase> tertiaryTargets =
getProperty(TERTIARY_RANGE).floatValue(), secondaryTarget.posX, EntityUtils.getLivingWithinRadius(
secondaryTarget.posY + secondaryTarget.height / 2, secondaryTarget.posZ, world); getProperty(TERTIARY_RANGE).floatValue(),
secondaryTarget.posX,
tertiaryTargets.remove(target); secondaryTarget.posY + secondaryTarget.height / 2,
tertiaryTargets.removeAll(secondaryTargets); secondaryTarget.posZ,
tertiaryTargets.removeIf(e -> !EntityUtils.isLiving(e)); world
tertiaryTargets.removeIf(e -> !AllyDesignationSystem.isValidTarget(caster, e)); );
if(tertiaryTargets.size() > getProperty(TERTIARY_MAX_TARGETS).intValue())
tertiaryTargets = tertiaryTargets.subList(0, getProperty(TERTIARY_MAX_TARGETS).intValue());
for(EntityLivingBase tertiaryTarget : tertiaryTargets){ tertiaryTargets.stream()
electrocute(world, caster, secondaryTarget.getPositionVector().add(0, secondaryTarget.height/2, 0), .filter(entity -> !secondaryTargets.contains(entity))
tertiaryTarget, getProperty(TERTIARY_DAMAGE).floatValue() * modifiers.get(SpellModifiers.POTENCY), ticksInUse); .filter(entity -> !entity.equals(target))
} .filter(EntityUtils::isLiving)
} .filter(e -> AllyDesignationSystem.isValidTarget(caster, e))
.limit(getProperty(TERTIARY_MAX_TARGETS).intValue())
.forEach(tertiaryTarget ->
electrocute(world, caster,
secondaryTarget.getPositionVector().add(0, secondaryTarget.height / 2, 0),
tertiaryTarget,
getProperty(TERTIARY_DAMAGE).floatValue() * modifiers.get(SpellModifiers.POTENCY),
ticksInUse
)
);
});
} }
return true; return true;
} }
@@ -128,10 +138,10 @@ public class LightningWeb extends SpellRay {
} }
} }
} }
return true; return true;
} }
private void electrocute(World world, Entity caster, Vec3d origin, Entity target, float damage, int ticksInUse){ private void electrocute(World world, Entity caster, Vec3d origin, Entity target, float damage, int ticksInUse){
if(MagicDamage.isEntityImmune(DamageType.SHOCK, target)){ if(MagicDamage.isEntityImmune(DamageType.SHOCK, target)){
@@ -142,12 +152,12 @@ public class LightningWeb extends SpellRay {
EntityUtils.attackEntityWithoutKnockback(target, EntityUtils.attackEntityWithoutKnockback(target,
MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), damage); MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), damage);
} }
if(world.isRemote){ if(world.isRemote){
ParticleBuilder.create(Type.BEAM).entity(caster).clr(0.2f, 0.6f, 1) ParticleBuilder.create(Type.BEAM).entity(caster).clr(0.2f, 0.6f, 1)
.pos(caster != null ? origin.subtract(caster.getPositionVector()) : origin).target(target).spawn(world); .pos(caster != null ? origin.subtract(caster.getPositionVector()) : origin).target(target).spawn(world);
if(ticksInUse % 3 == 0){ if(ticksInUse % 3 == 0){
ParticleBuilder.create(Type.LIGHTNING).entity(caster) ParticleBuilder.create(Type.LIGHTNING).entity(caster)
.pos(caster != null ? origin.subtract(caster.getPositionVector()) : origin).target(target).spawn(world); .pos(caster != null ? origin.subtract(caster.getPositionVector()) : origin).target(target).spawn(world);