mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-01 19:46:42 +01:00
The light and dark gems will now interact with each other
This commit is contained in:
parent
5e3316e232
commit
1700ce9276
8 changed files with 294 additions and 108 deletions
|
@ -18,21 +18,21 @@ public class ParticleSphere extends Particle implements IAttachableParticle {
|
||||||
protected int tint;
|
protected int tint;
|
||||||
protected float alpha;
|
protected float alpha;
|
||||||
|
|
||||||
protected int radius;
|
protected float radius;
|
||||||
|
|
||||||
private ICaster<?> caster;
|
private ICaster<?> caster;
|
||||||
|
|
||||||
private static final ModelSphere model = new ModelSphere();
|
private static final ModelSphere model = new ModelSphere();
|
||||||
|
|
||||||
public ParticleSphere(int id, World w, double x, double y, double z, double vX, double vY, double vZ, int... args) {
|
public ParticleSphere(int id, World w, double x, double y, double z, double vX, double vY, double vZ, int... args) {
|
||||||
this(w, x, y, z, args[0], args[1], args[2]/255F);
|
this(w, x, y, z, args[0] / 1000F, args[1], args[2]/255F);
|
||||||
|
|
||||||
this.motionX = vX;
|
this.motionX = vX;
|
||||||
this.motionY = vY;
|
this.motionY = vY;
|
||||||
this.motionZ = vZ;
|
this.motionZ = vZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ParticleSphere(World w, double x, double y, double z, int radius, int tint, float alpha) {
|
public ParticleSphere(World w, double x, double y, double z, float radius, int tint, float alpha) {
|
||||||
super(w, x, y, z);
|
super(w, x, y, z);
|
||||||
|
|
||||||
this.radius = radius;
|
this.radius = radius;
|
||||||
|
@ -69,9 +69,7 @@ public class ParticleSphere extends Particle implements IAttachableParticle {
|
||||||
setPosition(e.posX, e.posY, e.posZ);
|
setPosition(e.posX, e.posY, e.posZ);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (this.rand.nextInt(10000) == 0) {
|
radius *= 0.9998281;
|
||||||
this.radius--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,17 +80,19 @@ public class ParticleSphere extends Particle implements IAttachableParticle {
|
||||||
|
|
||||||
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
|
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
|
||||||
|
|
||||||
GlStateManager.depthMask(false);
|
if (alpha < 0) {
|
||||||
GlStateManager.shadeModel(GL11.GL_SMOOTH);
|
GlStateManager.depthMask(false);
|
||||||
GlStateManager.tryBlendFuncSeparate(
|
GlStateManager.shadeModel(GL11.GL_SMOOTH);
|
||||||
GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA,
|
GlStateManager.tryBlendFuncSeparate(
|
||||||
GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
|
GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA,
|
||||||
|
GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
|
||||||
|
}
|
||||||
|
|
||||||
Color.glColor(tint, alpha);
|
Color.glColor(tint, alpha);
|
||||||
|
|
||||||
model.setPosition(posX, posY, posZ);
|
model.setPosition(posX, posY, posZ);
|
||||||
model.render(radius);
|
model.render(radius);
|
||||||
|
|
||||||
|
|
||||||
GlStateManager.color(1, 1, 1, 1);
|
GlStateManager.color(1, 1, 1, 1);
|
||||||
|
|
||||||
GL11.glPopAttrib();
|
GL11.glPopAttrib();
|
||||||
|
@ -101,7 +101,7 @@ public class ParticleSphere extends Particle implements IAttachableParticle {
|
||||||
@Override
|
@Override
|
||||||
public void setAttribute(int key, Object value) {
|
public void setAttribute(int key, Object value) {
|
||||||
if (key == 0) {
|
if (key == 0) {
|
||||||
radius = (int)value;
|
radius = (float)value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
package com.minelittlepony.unicopia.spell;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.entity.EntitySpell;
|
||||||
|
|
||||||
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
public abstract class AbstractAttachableSpell extends AbstractSpell {
|
||||||
|
|
||||||
|
boolean searching = true;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private UUID targettedEntityId;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private EntitySpell targettedEntity;
|
||||||
|
|
||||||
|
protected void setTarget(@Nonnull EntitySpell e) {
|
||||||
|
searching = false;
|
||||||
|
targettedEntity = e;
|
||||||
|
targettedEntityId = e.getUniqueID();
|
||||||
|
setDirty(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasTarget() {
|
||||||
|
if (targettedEntity != null && targettedEntity.isDead) {
|
||||||
|
targettedEntity = null;
|
||||||
|
targettedEntityId = null;
|
||||||
|
searching = true;
|
||||||
|
setDirty(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return targettedEntity != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
protected EntitySpell getTarget(ICaster<?> source) {
|
||||||
|
if (targettedEntity == null && targettedEntityId != null) {
|
||||||
|
source.getWorld().getEntities(EntitySpell.class, e -> e.getUniqueID().equals(targettedEntityId))
|
||||||
|
.stream()
|
||||||
|
.findFirst()
|
||||||
|
.ifPresent(this::setTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targettedEntity != null && targettedEntity.isDead) {
|
||||||
|
targettedEntity = null;
|
||||||
|
targettedEntityId = null;
|
||||||
|
searching = true;
|
||||||
|
setDirty(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return targettedEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean update(ICaster<?> source) {
|
||||||
|
|
||||||
|
if (searching) {
|
||||||
|
searchForTarget(source);
|
||||||
|
} else {
|
||||||
|
getTarget(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
return !getDead();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void searchForTarget(ICaster<?> source) {
|
||||||
|
BlockPos origin = source.getOrigin();
|
||||||
|
|
||||||
|
source.getWorld().getEntitiesInAABBexcluding(source.getEntity(), getSearchArea(source), e -> {
|
||||||
|
return e instanceof EntitySpell && canTargetEntity((EntitySpell)e);
|
||||||
|
}).stream()
|
||||||
|
.sorted((a, b) -> (int)(a.getDistanceSq(origin) - b.getDistanceSq(origin)))
|
||||||
|
.findFirst()
|
||||||
|
.map(EntitySpell.class::cast)
|
||||||
|
.ifPresent(this::setTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract AxisAlignedBB getSearchArea(ICaster<?> source);
|
||||||
|
|
||||||
|
protected abstract boolean canTargetEntity(EntitySpell e);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToNBT(NBTTagCompound compound) {
|
||||||
|
super.writeToNBT(compound);
|
||||||
|
|
||||||
|
if (targettedEntityId != null) {
|
||||||
|
compound.setUniqueId("target", targettedEntityId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readFromNBT(NBTTagCompound compound) {
|
||||||
|
super.readFromNBT(compound);
|
||||||
|
|
||||||
|
if (compound.hasKey("target")) {
|
||||||
|
targettedEntityId = compound.getUniqueId("target");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,6 +10,7 @@ import com.minelittlepony.unicopia.Predicates;
|
||||||
import com.minelittlepony.unicopia.player.PlayerSpeciesList;
|
import com.minelittlepony.unicopia.player.PlayerSpeciesList;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
@ -38,6 +39,15 @@ public class CasterUtils {
|
||||||
.map(Optional::get);
|
.map(Optional::get);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Stream<ICaster<?>> findAllSpells(ICaster<?> source) {
|
||||||
|
return source.getWorld().getEntities(EntityLivingBase.class, e -> {
|
||||||
|
return e instanceof ICaster || e instanceof EntityPlayer;
|
||||||
|
}).stream()
|
||||||
|
.map(CasterUtils::toCaster)
|
||||||
|
.filter(Optional::isPresent)
|
||||||
|
.map(Optional::get);
|
||||||
|
}
|
||||||
|
|
||||||
static Stream<ICaster<?>> findAllSpellsInRange(ICaster<?> source, AxisAlignedBB bb) {
|
static Stream<ICaster<?>> findAllSpellsInRange(ICaster<?> source, AxisAlignedBB bb) {
|
||||||
return source.getWorld().getEntitiesInAABBexcluding(source.getEntity(), bb, e ->
|
return source.getWorld().getEntitiesInAABBexcluding(source.getEntity(), bb, e ->
|
||||||
!e.isDead && (e instanceof ICaster || Predicates.MAGI.test(e))
|
!e.isDead && (e instanceof ICaster || Predicates.MAGI.test(e))
|
||||||
|
|
|
@ -84,6 +84,10 @@ public interface ICaster<E extends EntityLivingBase> extends IOwned<E>, ILevelle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default Stream<ICaster<?>> findAllSpells() {
|
||||||
|
return CasterUtils.findAllSpells(this);
|
||||||
|
}
|
||||||
|
|
||||||
default Stream<ICaster<?>> findAllSpellsInRange(double radius) {
|
default Stream<ICaster<?>> findAllSpellsInRange(double radius) {
|
||||||
return CasterUtils.findAllSpellsInRange(this, radius);
|
return CasterUtils.findAllSpellsInRange(this, radius);
|
||||||
}
|
}
|
||||||
|
@ -95,4 +99,6 @@ public interface ICaster<E extends EntityLivingBase> extends IOwned<E>, ILevelle
|
||||||
default Stream<Entity> findAllEntitiesInRange(double radius) {
|
default Stream<Entity> findAllEntitiesInRange(double radius) {
|
||||||
return VecHelper.findAllEntitiesInRange(getEntity(), getWorld(), getOrigin(), radius);
|
return VecHelper.findAllEntitiesInRange(getEntity(), getWorld(), getOrigin(), radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +1,15 @@
|
||||||
package com.minelittlepony.unicopia.spell;
|
package com.minelittlepony.unicopia.spell;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.UParticles;
|
import com.minelittlepony.unicopia.UParticles;
|
||||||
import com.minelittlepony.unicopia.entity.EntitySpell;
|
import com.minelittlepony.unicopia.entity.EntitySpell;
|
||||||
import com.minelittlepony.unicopia.particle.Particles;
|
import com.minelittlepony.unicopia.particle.Particles;
|
||||||
import com.minelittlepony.util.shape.IShape;
|
import com.minelittlepony.util.shape.IShape;
|
||||||
import com.minelittlepony.util.shape.Line;
|
import com.minelittlepony.util.shape.Line;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
public class SpellCharge extends AbstractSpell {
|
public class SpellCharge extends AbstractAttachableSpell {
|
||||||
|
|
||||||
boolean searching = true;
|
|
||||||
|
|
||||||
private UUID targettedEntityId;
|
|
||||||
private EntitySpell targettedEntity;
|
|
||||||
|
|
||||||
private static final AxisAlignedBB searchArea = new AxisAlignedBB(-15, -15, -15, 15, 15, 15);
|
private static final AxisAlignedBB searchArea = new AxisAlignedBB(-15, -15, -15, 15, 15, 15);
|
||||||
|
|
||||||
|
@ -40,6 +28,16 @@ public class SpellCharge extends AbstractSpell {
|
||||||
return 0x7272B7;
|
return 0x7272B7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean canTargetEntity(EntitySpell e) {
|
||||||
|
return e.hasEffect();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected AxisAlignedBB getSearchArea(ICaster<?> source) {
|
||||||
|
return searchArea.offset(source.getOriginVector());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(ICaster<?> source) {
|
public void render(ICaster<?> source) {
|
||||||
if (source.getWorld().rand.nextInt(4 + source.getCurrentLevel() * 4) == 0) {
|
if (source.getWorld().rand.nextInt(4 + source.getCurrentLevel() * 4) == 0) {
|
||||||
|
@ -58,48 +56,11 @@ public class SpellCharge extends AbstractSpell {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean canTargetEntity(Entity e) {
|
|
||||||
return e instanceof EntitySpell && ((EntitySpell)e).hasEffect();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setTarget(EntitySpell e) {
|
|
||||||
searching = false;
|
|
||||||
targettedEntity = e;
|
|
||||||
targettedEntityId = e.getUniqueID();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected EntitySpell getTarget(ICaster<?> source) {
|
|
||||||
if (targettedEntity == null && targettedEntityId != null) {
|
|
||||||
source.getWorld().getEntities(EntitySpell.class, e -> e.getUniqueID().equals(targettedEntityId))
|
|
||||||
.stream()
|
|
||||||
.findFirst()
|
|
||||||
.ifPresent(this::setTarget);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (targettedEntity != null && targettedEntity.isDead) {
|
|
||||||
targettedEntity = null;
|
|
||||||
targettedEntityId = null;
|
|
||||||
searching = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return targettedEntity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean update(ICaster<?> source) {
|
public boolean update(ICaster<?> source) {
|
||||||
|
super.update(source);
|
||||||
|
|
||||||
if (searching) {
|
if (!searching) {
|
||||||
BlockPos origin = source.getOrigin();
|
|
||||||
|
|
||||||
List<Entity> list = source.getWorld().getEntitiesInAABBexcluding(source.getEntity(),
|
|
||||||
searchArea.offset(origin), this::canTargetEntity).stream().sorted((a, b) ->
|
|
||||||
(int)(a.getDistanceSq(origin) - b.getDistanceSq(origin))
|
|
||||||
).collect(Collectors.toList());
|
|
||||||
|
|
||||||
if (list.size() > 0) {
|
|
||||||
setTarget((EntitySpell)list.get(0));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
EntitySpell target = getTarget(source);
|
EntitySpell target = getTarget(source);
|
||||||
|
|
||||||
if (target != null && !target.overLevelCap() && source.getCurrentLevel() > 0) {
|
if (target != null && !target.overLevelCap() && source.getCurrentLevel() > 0) {
|
||||||
|
@ -110,22 +71,4 @@ public class SpellCharge extends AbstractSpell {
|
||||||
|
|
||||||
return !getDead();
|
return !getDead();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeToNBT(NBTTagCompound compound) {
|
|
||||||
super.writeToNBT(compound);
|
|
||||||
|
|
||||||
if (targettedEntityId != null) {
|
|
||||||
compound.setUniqueId("target", targettedEntityId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void readFromNBT(NBTTagCompound compound) {
|
|
||||||
super.readFromNBT(compound);
|
|
||||||
|
|
||||||
if (compound.hasKey("target")) {
|
|
||||||
targettedEntityId = compound.getUniqueId("target");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,19 @@
|
||||||
package com.minelittlepony.unicopia.spell;
|
package com.minelittlepony.unicopia.spell;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.UParticles;
|
import com.minelittlepony.unicopia.UParticles;
|
||||||
import com.minelittlepony.unicopia.entity.EntitySpell;
|
import com.minelittlepony.unicopia.entity.EntitySpell;
|
||||||
import com.minelittlepony.unicopia.particle.Particles;
|
import com.minelittlepony.unicopia.particle.Particles;
|
||||||
import com.minelittlepony.util.MagicalDamageSource;
|
import com.minelittlepony.util.MagicalDamageSource;
|
||||||
|
import com.minelittlepony.util.PosHelper;
|
||||||
|
import com.minelittlepony.util.shape.IShape;
|
||||||
import com.minelittlepony.util.shape.Sphere;
|
import com.minelittlepony.util.shape.Sphere;
|
||||||
|
|
||||||
|
import net.minecraft.block.IGrowable;
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.entity.ai.EntityAIAvoidEntity;
|
import net.minecraft.entity.ai.EntityAIAvoidEntity;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
@ -16,10 +22,13 @@ import net.minecraft.init.SoundEvents;
|
||||||
import net.minecraft.potion.PotionEffect;
|
import net.minecraft.potion.PotionEffect;
|
||||||
import net.minecraft.util.SoundCategory;
|
import net.minecraft.util.SoundCategory;
|
||||||
import net.minecraft.util.SoundEvent;
|
import net.minecraft.util.SoundEvent;
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
public class SpellDarkness extends AbstractSpell.RangedAreaSpell {
|
public class SpellDarkness extends AbstractAttachableSpell {
|
||||||
|
|
||||||
|
private static final AxisAlignedBB searchArea = new AxisAlignedBB(-5, -5, -5, 5, 5, 5);
|
||||||
|
|
||||||
final SoundEvent[] scarySounds = new SoundEvent[] {
|
final SoundEvent[] scarySounds = new SoundEvent[] {
|
||||||
SoundEvents.AMBIENT_CAVE,
|
SoundEvents.AMBIENT_CAVE,
|
||||||
|
@ -62,22 +71,71 @@ public class SpellDarkness extends AbstractSpell.RangedAreaSpell {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean update(ICaster<?> source) {
|
public boolean update(ICaster<?> source) {
|
||||||
|
super.update(source);
|
||||||
|
|
||||||
|
int soundChance = 15;
|
||||||
|
|
||||||
int radius = 7 + (source.getCurrentLevel() * 3);
|
int radius = 7 + (source.getCurrentLevel() * 3);
|
||||||
|
|
||||||
if (source.getWorld().rand.nextInt(15) == 0) {
|
if (hasTarget()) {
|
||||||
source.getWorld().playSound(null, source.getOrigin(), getScarySoundEffect(source.getWorld().rand), SoundCategory.AMBIENT,
|
soundChance *= 10;
|
||||||
|
|
||||||
|
source.getEntity().motionY -= 0.01;
|
||||||
|
|
||||||
|
applyBlocks(source, radius);
|
||||||
|
applyEntities(source, radius, e -> applyLight(source, e));
|
||||||
|
} else {
|
||||||
|
applyEntities(source, radius, e -> applyDark(source, e));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source.getWorld().rand.nextInt(soundChance) == 0) {
|
||||||
|
source.getWorld().playSound(null, source.getOrigin(),
|
||||||
|
getSoundEffect(source.getWorld().rand), SoundCategory.AMBIENT,
|
||||||
0.2F + source.getWorld().rand.nextFloat(), 0.3F);
|
0.2F + source.getWorld().rand.nextFloat(), 0.3F);
|
||||||
}
|
}
|
||||||
source.findAllEntitiesInRange(radius * 1.5F)
|
|
||||||
.filter(e -> e instanceof EntityLivingBase)
|
|
||||||
.map(EntityLivingBase.class::cast)
|
|
||||||
.forEach(e -> applyDarkness(source, e));
|
|
||||||
|
|
||||||
return false;
|
|
||||||
|
return !getDead();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void applyDarkness(ICaster<?> source, EntityLivingBase entity) {
|
private void applyBlocks(ICaster<?> source, int radius) {
|
||||||
if (!CasterUtils.isHoldingEffect("light", entity)) {
|
for (BlockPos pos : PosHelper.getAllInRegionMutable(source.getOrigin(), new Sphere(false, radius))) {
|
||||||
|
if (source.getWorld().rand.nextInt(500) == 0) {
|
||||||
|
IBlockState state = source.getWorld().getBlockState(pos);
|
||||||
|
|
||||||
|
if (state.getBlock() instanceof IGrowable) {
|
||||||
|
IGrowable growable = (IGrowable)state.getBlock();
|
||||||
|
|
||||||
|
if (growable.canGrow(source.getWorld(), pos, state, source.getWorld().isRemote)) {
|
||||||
|
growable.grow(source.getWorld(), source.getWorld().rand, pos, state);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyEntities(ICaster<?> source, int radius, Consumer<EntityLivingBase> consumer) {
|
||||||
|
source.findAllEntitiesInRange(radius * 1.5F)
|
||||||
|
.filter(e -> e instanceof EntityLivingBase)
|
||||||
|
.map(EntityLivingBase.class::cast)
|
||||||
|
.forEach(consumer);;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyLight(ICaster<?> source, EntityLivingBase entity) {
|
||||||
|
if (entity.getHealth() < entity.getMaxHealth()) {
|
||||||
|
entity.heal(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyDark(ICaster<?> source, EntityLivingBase entity) {
|
||||||
|
|
||||||
|
if (isAreaOccupied(source, entity.getPositionVector())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isLightholder(entity)) {
|
||||||
entity.addPotionEffect(new PotionEffect(MobEffects.BLINDNESS, 100, 3));
|
entity.addPotionEffect(new PotionEffect(MobEffects.BLINDNESS, 100, 3));
|
||||||
|
|
||||||
Vec3d origin = source.getOriginVector();
|
Vec3d origin = source.getOriginVector();
|
||||||
|
@ -102,7 +160,12 @@ public class SpellDarkness extends AbstractSpell.RangedAreaSpell {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected SoundEvent getScarySoundEffect(Random rand) {
|
public SoundEvent getSoundEffect(Random rand) {
|
||||||
|
|
||||||
|
if (hasTarget()) {
|
||||||
|
return SoundEvents.BLOCK_NOTE_CHIME;
|
||||||
|
}
|
||||||
|
|
||||||
return scarySounds[rand.nextInt(scarySounds.length)];
|
return scarySounds[rand.nextInt(scarySounds.length)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,22 +173,80 @@ public class SpellDarkness extends AbstractSpell.RangedAreaSpell {
|
||||||
public void render(ICaster<?> source) {
|
public void render(ICaster<?> source) {
|
||||||
int radius = 7 + (source.getCurrentLevel() * 3);
|
int radius = 7 + (source.getCurrentLevel() * 3);
|
||||||
|
|
||||||
source.spawnParticles(new Sphere(false, radius), radius * 6, pos -> {
|
boolean tamed = hasTarget();
|
||||||
if (!source.getWorld().isAirBlock(new BlockPos(pos).down())) {
|
|
||||||
int size = source.getWorld().rand.nextInt(4);
|
|
||||||
|
|
||||||
if (size > 0) {
|
int tint = tamed ? 0xFFFFFF : getTint();
|
||||||
double vX = (source.getWorld().rand.nextFloat() - 0.5) * 2;
|
|
||||||
double vZ = (source.getWorld().rand.nextFloat() - 0.5) * 2;
|
|
||||||
|
|
||||||
Particles.instance().spawnParticle(UParticles.SPHERE, false, pos, vX, 0, vZ, size, getTint(), 100);
|
if (tamed) {
|
||||||
}
|
radius /= 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IShape shape = new Sphere(false, radius);
|
||||||
|
|
||||||
|
source.spawnParticles(shape, radius * 6, pos -> {
|
||||||
|
spawnSphere(source, pos, tint, searching ? 4 : 2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
source.findAllEntitiesInRange(radius * 1.5F).filter(this::isLightholder).forEach(e -> {
|
||||||
|
Vec3d pos = shape.computePoint(source.getWorld().rand).add(e.getPositionEyes(1));
|
||||||
|
|
||||||
|
spawnSphere(source, pos, 0xFFFFFF, 1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLightholder(Entity e) {
|
||||||
|
if (e instanceof EntitySpell) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return e instanceof EntityLivingBase && CasterUtils.isHoldingEffect("light", (EntityLivingBase)e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAreaOccupied(ICaster<?> source, Vec3d pos) {
|
||||||
|
if (source.getWorld().isAirBlock(new BlockPos(pos).down())) {
|
||||||
|
return source.findAllSpells().anyMatch(spell -> {
|
||||||
|
SpellShield effect = spell.getEffect(SpellShield.class, false);
|
||||||
|
|
||||||
|
if (effect != null) {
|
||||||
|
return pos.distanceTo(spell.getOriginVector()) <= effect.getDrawDropOffRange(spell);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void spawnSphere(ICaster<?> source, Vec3d pos, int tint, int maxSize) {
|
||||||
|
if (isAreaOccupied(source, pos)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float size = source.getWorld().rand.nextFloat() * maxSize;
|
||||||
|
|
||||||
|
float particleSpeed = hasTarget() ? 0.3F : 0.5F;
|
||||||
|
|
||||||
|
if (size > 0) {
|
||||||
|
double vX = (source.getWorld().rand.nextFloat() - 0.5) * particleSpeed;
|
||||||
|
double vZ = (source.getWorld().rand.nextFloat() - 0.5) * particleSpeed;
|
||||||
|
|
||||||
|
Particles.instance().spawnParticle(UParticles.SPHERE, false, pos, vX, 0, vZ, (int)(size * 1000), tint, 100);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SpellAffinity getAffinity() {
|
public SpellAffinity getAffinity() {
|
||||||
return SpellAffinity.BAD;
|
return SpellAffinity.BAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected AxisAlignedBB getSearchArea(ICaster<?> source) {
|
||||||
|
return searchArea.offset(source.getOriginVector());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean canTargetEntity(EntitySpell e) {
|
||||||
|
return e.hasEffect() && "light".equals(e.getEffect().getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,14 +37,14 @@ public class SpellShield extends AbstractSpell.RangedAreaSpell {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(ICaster<?> source) {
|
public void render(ICaster<?> source) {
|
||||||
int radius = 4 + (source.getCurrentLevel() * 2);
|
float radius = 4 + (source.getCurrentLevel() * 2);
|
||||||
|
|
||||||
source.spawnParticles(new Sphere(true, radius), radius * 6, pos -> {
|
source.spawnParticles(new Sphere(true, radius), (int)(radius * 6), pos -> {
|
||||||
Particles.instance().spawnParticle(UParticles.UNICORN_MAGIC, false, pos, 0, 0, 0);
|
Particles.instance().spawnParticle(UParticles.UNICORN_MAGIC, false, pos, 0, 0, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
particlEffect
|
particlEffect
|
||||||
.ifMissing(source, () -> Particles.instance().spawnParticle(UParticles.SPHERE, true, source.getOriginVector(), 0, 0, 0, radius, getTint(), 30))
|
.ifMissing(source, () -> Particles.instance().spawnParticle(UParticles.SPHERE, true, source.getOriginVector(), 0, 0, 0, 1, getTint(), 30))
|
||||||
.ifPresent(p -> p.setAttribute(0, radius));
|
.ifPresent(p -> p.setAttribute(0, radius));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ public class SpellShield extends AbstractSpell.RangedAreaSpell {
|
||||||
return !getDead();
|
return !getDead();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected double getDrawDropOffRange(ICaster<?> source) {
|
public double getDrawDropOffRange(ICaster<?> source) {
|
||||||
return 4 + (source.getCurrentLevel() * 2);
|
return 4 + (source.getCurrentLevel() * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ public class SpellVortex extends SpellShield {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double getDrawDropOffRange(ICaster<?> caster) {
|
public double getDrawDropOffRange(ICaster<?> caster) {
|
||||||
return 10 + (caster.getCurrentLevel() * 2);
|
return 10 + (caster.getCurrentLevel() * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue