diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4432ec2d..68f3202a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -49,8 +49,10 @@ Pull requests aren't just for code - if you would like to help translate Wizardr - `#image tag` adds an image to the text with the given tag. Image tags are defined in the `"images": {...}` block at the start of the file. Each named entry in this block defines a single image with that name as its tag. Each entry is a JSON object containing a file location and optional caption/dimensions. - `#recipe tag` adds a crafting recipe to the text with the given tag. Similar to image tags, recipe tags are defined in the `"recipes": {...}` block at the start of the file. Each named entry in this block defines a recipe with that name as its tag. Each entry contains a list of one or more locations or recipes to display (if more than one is specified, the display will cycle through the different recipes). - - Anything else with a `#` directly before it (with no space) will be treated as a format argument if possible. This means everything between the `#` and the next space will be replaced with something else at runtime, similar to the `%X$s` bits in a normal .lang file. The current available format arguments can be found [here](https://github.com/Electroblob77/Wizardry/blob/1.12.2/src/main/java/electroblob/wizardry/client/gui/handbook/GuiWizardHandbook.java#L177-L203). + - Anything else with a `#` directly before it (with no space) will be treated as a format argument if possible. This means the text after the `#` will be replaced with something else at runtime, similar to the `%X$s` bits in a normal .lang file, if it matches one of the available format arguments. The current format arguments can be found [here](https://github.com/Electroblob77/Wizardry/blob/1.12.2/src/main/java/electroblob/wizardry/client/gui/handbook/GuiWizardHandbook.java#L177-L203). - `@section@` adds a hyperlink to the given section, which will display as the name of that section. `@section alt text@` is the same, except alt text is displayed instead of the section name (alt text may contain spaces). It is also possible to hyperlink to a webpage, simply replace the section name with the url (e.g. `@https://example.com/@` or `@https://example.com/ alt text@`). + +> Translators for Chinese, Japanese, Korean and similar East Asian languages: Due to how Minecraft's word wrapping works, for best results you should _remove spaces before and after hyperlinks and formatting tags_, excluding images and recipes. However, do not remove the space between a hyperlink's destination and its alt text or the link will break! If all of that confused you, the simple rule is: _Don't translate anything directly after an `@` symbol, directly after a `#`, or the first word after `#image` or `#recipe`_. However, you should translate the `"caption"` entries in the `images` block. diff --git a/src/main/java/electroblob/wizardry/spell/LightningWeb.java b/src/main/java/electroblob/wizardry/spell/LightningWeb.java index 8bb275e1..126f57cd 100644 --- a/src/main/java/electroblob/wizardry/spell/LightningWeb.java +++ b/src/main/java/electroblob/wizardry/spell/LightningWeb.java @@ -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){ this.playSoundLoop(world, x, y, z, ticksInUse, duration); } - + @Override protected boolean onEntityHit(World world, Entity target, Vec3d hit, EntityLivingBase caster, Vec3d origin, int ticksInUse, SpellModifiers modifiers){ - + if(EntityUtils.isLiving(target)){ electrocute(world, caster, origin, target, getProperty(PRIMARY_DAMAGE).floatValue() * modifiers.get(SpellModifiers.POTENCY), ticksInUse); - - // Secondary chaining effect - List secondaryTargets = EntityUtils.getLivingWithinRadius( - 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()); + // Secondary chaining effect - for(EntityLivingBase secondaryTarget : secondaryTargets){ + List 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, - getProperty(SECONDARY_DAMAGE).floatValue() * modifiers.get(SpellModifiers.POTENCY), ticksInUse); + secondaryTargets.stream() + .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 tertiaryTargets = EntityUtils.getLivingWithinRadius( - getProperty(TERTIARY_RANGE).floatValue(), secondaryTarget.posX, - secondaryTarget.posY + secondaryTarget.height / 2, secondaryTarget.posZ, world); - - tertiaryTargets.remove(target); - tertiaryTargets.removeAll(secondaryTargets); - tertiaryTargets.removeIf(e -> !EntityUtils.isLiving(e)); - tertiaryTargets.removeIf(e -> !AllyDesignationSystem.isValidTarget(caster, e)); - if(tertiaryTargets.size() > getProperty(TERTIARY_MAX_TARGETS).intValue()) - tertiaryTargets = tertiaryTargets.subList(0, getProperty(TERTIARY_MAX_TARGETS).intValue()); + List tertiaryTargets = + EntityUtils.getLivingWithinRadius( + getProperty(TERTIARY_RANGE).floatValue(), + secondaryTarget.posX, + secondaryTarget.posY + secondaryTarget.height / 2, + secondaryTarget.posZ, + world + ); - for(EntityLivingBase tertiaryTarget : tertiaryTargets){ - electrocute(world, caster, secondaryTarget.getPositionVector().add(0, secondaryTarget.height/2, 0), - tertiaryTarget, getProperty(TERTIARY_DAMAGE).floatValue() * modifiers.get(SpellModifiers.POTENCY), ticksInUse); - } - } + tertiaryTargets.stream() + .filter(entity -> !secondaryTargets.contains(entity)) + .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; } @@ -128,10 +138,10 @@ public class LightningWeb extends SpellRay { } } } - + return true; } - + private void electrocute(World world, Entity caster, Vec3d origin, Entity target, float damage, int ticksInUse){ if(MagicDamage.isEntityImmune(DamageType.SHOCK, target)){ @@ -142,12 +152,12 @@ public class LightningWeb extends SpellRay { EntityUtils.attackEntityWithoutKnockback(target, MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), damage); } - + if(world.isRemote){ - + ParticleBuilder.create(Type.BEAM).entity(caster).clr(0.2f, 0.6f, 1) .pos(caster != null ? origin.subtract(caster.getPositionVector()) : origin).target(target).spawn(world); - + if(ticksInUse % 3 == 0){ ParticleBuilder.create(Type.LIGHTNING).entity(caster) .pos(caster != null ? origin.subtract(caster.getPositionVector()) : origin).target(target).spawn(world);