Implement blast modifier support for all applicable constructs, plus misc construct-related cleanup and fixes

This commit is contained in:
Electroblob77
2020-06-28 16:56:18 +01:00
parent 97c21b5057
commit 3a68ba8927
36 changed files with 296 additions and 201 deletions
@@ -1,17 +1,23 @@
package electroblob.wizardry.entity.construct;
import electroblob.wizardry.registry.Spells;
import electroblob.wizardry.spell.Spell;
import net.minecraft.entity.projectile.EntityTippedArrow;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
public class EntityArrowRain extends EntityMagicConstruct {
public class EntityArrowRain extends EntityScaledConstruct {
public EntityArrowRain(World world){
super(world);
this.height = 3.0f;
this.width = 5.0f;
setSize(Spells.arrow_rain.getProperty(Spell.EFFECT_RADIUS).floatValue() * 2, 5);
}
@Override
protected boolean shouldScaleHeight(){
return false;
}
public void onUpdate(){
@@ -19,14 +25,21 @@ public class EntityArrowRain extends EntityMagicConstruct {
super.onUpdate();
if(!this.world.isRemote){
EntityTippedArrow arrow = new EntityTippedArrow(world, this.posX + rand.nextDouble() * 6 - 3,
this.posY + rand.nextDouble() * 4 - 2, this.posZ + rand.nextDouble() * 6 - 3);
double x = posX + (world.rand.nextDouble() - 0.5D) * (double)width;
double y = posY + world.rand.nextDouble() * (double)height;
double z = posZ + (world.rand.nextDouble() - 0.5D) * (double)width;
EntityTippedArrow arrow = new EntityTippedArrow(world, x, y, z);
arrow.motionX = MathHelper.cos((float)Math.toRadians(this.rotationYaw + 90));
arrow.motionY = -0.6;
arrow.motionZ = MathHelper.sin((float)Math.toRadians(this.rotationYaw + 90));
arrow.shootingEntity = this.getCaster();
arrow.setDamage(7.0d * damageMultiplier);
arrow.setPotionEffect(new ItemStack(Items.ARROW));
this.world.spawnEntity(arrow);
}
}
@@ -3,8 +3,10 @@ package electroblob.wizardry.entity.construct;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.EntityLevitatingBlock;
import electroblob.wizardry.item.ItemArtefact;
import electroblob.wizardry.registry.Spells;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.spell.Spell;
import electroblob.wizardry.util.BlockUtils;
import electroblob.wizardry.util.EntityUtils;
import electroblob.wizardry.util.MagicDamage;
@@ -27,7 +29,7 @@ import net.minecraftforge.fml.relauncher.SideOnly;
import java.util.List;
public class EntityBlackHole extends EntityMagicConstruct {
public class EntityBlackHole extends EntityScaledConstruct {
private static final double SUCTION_STRENGTH = 0.075;
/** The maximum number of blocks that can be unhooked each tick, reduces lag from excessive numbers of entities. */
@@ -38,8 +40,8 @@ public class EntityBlackHole extends EntityMagicConstruct {
public EntityBlackHole(World world){
super(world);
this.width = 6.0f;
this.height = 3.0f;
float r = Spells.black_hole.getProperty(Spell.EFFECT_RADIUS).floatValue();
setSize(r * 2, r);
randomiser = new int[30];
for(int i = 0; i < randomiser.length; i++){
randomiser[i] = this.rand.nextInt(10);
@@ -91,7 +93,7 @@ public class EntityBlackHole extends EntityMagicConstruct {
if(!this.world.isRemote){
double radius = 6; // TODO: Support for spell properties and modifiers
double radius = 6 * sizeMultiplier; // TODO: Support for spell properties
boolean suckInBlocks = getCaster() instanceof EntityPlayer && EntityUtils.canDamageBlocks(getCaster(), world)
&& ItemArtefact.isArtefactActive((EntityPlayer)getCaster(), WizardryItems.charm_black_hole);
@@ -16,12 +16,18 @@ import net.minecraft.world.World;
import java.util.List;
public class EntityBlizzard extends EntityMagicConstruct {
public class EntityBlizzard extends EntityScaledConstruct {
public EntityBlizzard(World world){
super(world);
this.height = 1.0f;
this.width = 1.0f;
// TODO: Set the size properly and do whatever forcefield does to allow block and entity interaction inside it
// (Probably need to do this for several others too)
setSize(Spells.blizzard.getProperty(Spell.EFFECT_RADIUS).floatValue() * 2, 3);
}
@Override
protected boolean shouldScaleHeight(){
return false;
}
public void onUpdate(){
@@ -34,7 +40,7 @@ public class EntityBlizzard extends EntityMagicConstruct {
// This is a good example of why you might define a spell base property without necessarily using it in the
// spell - in fact, blizzard doesn't even have a spell class (yet)
double radius = Spells.blizzard.getProperty(Spell.EFFECT_RADIUS).doubleValue();
double radius = Spells.blizzard.getProperty(Spell.EFFECT_RADIUS).doubleValue() * sizeMultiplier;
if(!this.world.isRemote){
@@ -64,13 +70,13 @@ public class EntityBlizzard extends EntityMagicConstruct {
for(int i=0; i<6; i++){
double speed = (rand.nextBoolean() ? 1 : -1) * (0.1 + 0.05 * rand.nextDouble());
ParticleBuilder.create(Type.SNOW).pos(this.posX, this.posY + rand.nextDouble() * 3, this.posZ).vel(0, 0, 0)
ParticleBuilder.create(Type.SNOW).pos(this.posX, this.posY + rand.nextDouble() * height, this.posZ).vel(0, 0, 0)
.time(100).scale(2).spin(rand.nextDouble() * (radius - 0.5) + 0.5, speed).shaded(true).spawn(world);
}
for(int i=0; i<3; i++){
double speed = (rand.nextBoolean() ? 1 : -1) * (0.05 + 0.02 * rand.nextDouble());
ParticleBuilder.create(Type.CLOUD).pos(this.posX, this.posY + rand.nextDouble() * 2.5, this.posZ)
ParticleBuilder.create(Type.CLOUD).pos(this.posX, this.posY + rand.nextDouble() * (height - 0.5), this.posZ)
.clr(0xffffff).shaded(true).spin(rand.nextDouble() * (radius - 1) + 0.5, speed).spawn(world);
}
}
@@ -10,12 +10,21 @@ import net.minecraft.world.World;
import java.util.List;
public class EntityCombustionRune extends EntityMagicConstruct {
public class EntityCombustionRune extends EntityScaledConstruct {
public EntityCombustionRune(World world){
super(world);
this.height = 0.2f;
this.width = 2.0f;
setSize(2, 0.2f);
}
@Override
protected boolean shouldScaleWidth(){
return false; // We're using the blast modifier for an actual explosion here, rather than the entity size
}
@Override
protected boolean shouldScaleHeight(){
return false;
}
@Override
@@ -31,7 +40,7 @@ public class EntityCombustionRune extends EntityMagicConstruct {
if(this.isValidTarget(target)){
float strength = Spells.combustion_rune.getProperty(Spell.BLAST_RADIUS).floatValue();
float strength = Spells.combustion_rune.getProperty(Spell.BLAST_RADIUS).floatValue() * sizeMultiplier;
world.newExplosion(this.getCaster(), this.posX, this.posY, this.posZ, strength, true,
getCaster() != null && EntityUtils.canDamageBlocks(getCaster(), world));
@@ -48,9 +57,6 @@ public class EntityCombustionRune extends EntityMagicConstruct {
}
}
@Override
protected void entityInit(){}
@Override
public boolean canRenderOnFire(){
return false;
@@ -17,7 +17,7 @@ import java.util.List;
public class EntityDecay extends EntityMagicConstruct {
public int textureIndex = 0;
public int textureIndex;
public EntityDecay(World world){
super(world);
@@ -62,8 +62,7 @@ public class EntityDecay extends EntityMagicConstruct {
}
}
@Override protected void entityInit(){}
// TESTME: What the heck are these two doing?! (Are they a throwback to when this was not a construct?)
@Override protected void readEntityFromNBT(NBTTagCompound nbttagcompound){}
@Override protected void writeEntityToNBT(NBTTagCompound nbttagcompound){}
@@ -18,12 +18,11 @@ import net.minecraft.world.World;
import java.util.List;
public class EntityEarthquake extends EntityMagicConstruct {
public class EntityEarthquake extends EntityMagicConstruct { // NOT a scaled construct, the size is controlled by time
public EntityEarthquake(World world){
super(world);
this.height = 1.0f;
this.width = 1.0f;
setSize(1, 1); // This one probably should be small
}
public void onUpdate(){
@@ -12,14 +12,16 @@ import net.minecraft.world.World;
import java.util.List;
public class EntityFireRing extends EntityMagicConstruct {
// TODO: Implement blast modifiers
public class EntityFireRing extends EntityScaledConstruct {
public EntityFireRing(World world){
super(world);
this.height = 1.0f;
this.width = 5.0f;
setSize(Spells.ring_of_fire.getProperty(Spell.EFFECT_RADIUS).floatValue() * 2, 1);
}
@Override
protected boolean shouldScaleHeight(){
return false;
}
public void onUpdate(){
@@ -32,8 +34,7 @@ public class EntityFireRing extends EntityMagicConstruct {
if(!this.world.isRemote){
List<EntityLivingBase> targets = EntityUtils.getLivingWithinRadius(2.5d, this.posX, this.posY,
this.posZ, this.world);
List<EntityLivingBase> targets = EntityUtils.getLivingWithinRadius(width/2, this.posX, this.posY, this.posZ, this.world);
for(EntityLivingBase target : targets){
@@ -14,12 +14,17 @@ import net.minecraft.world.World;
import java.util.List;
public class EntityFireSigil extends EntityMagicConstruct {
// TODO: Try to collect sigils into one superclass
public class EntityFireSigil extends EntityScaledConstruct {
public EntityFireSigil(World world){
super(world);
this.height = 0.2f;
this.width = 2.0f;
setSize(Spells.fire_sigil.getProperty(Spell.EFFECT_RADIUS).floatValue() * 2, 0.2f);
}
@Override
protected boolean shouldScaleHeight(){
return false;
}
@Override
@@ -59,16 +64,13 @@ public class EntityFireSigil extends EntityMagicConstruct {
}
}
}else if(this.rand.nextInt(15) == 0){
double radius = 0.5 + rand.nextDouble() * 0.3;
float angle = rand.nextFloat() * (float)Math.PI * 2;;
double radius = (0.5 + rand.nextDouble() * 0.3) * width/2;
float angle = rand.nextFloat() * (float)Math.PI * 2;
world.spawnParticle(EnumParticleTypes.FLAME, this.posX + radius * MathHelper.cos(angle), this.posY + 0.1,
this.posZ + radius * MathHelper.sin(angle), 0, 0, 0);
}
}
@Override
protected void entityInit(){}
@Override
public boolean canRenderOnFire(){
return false;
@@ -6,16 +6,19 @@ import electroblob.wizardry.entity.projectile.EntityMagicArrow;
import electroblob.wizardry.item.ItemArtefact;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.*;
import electroblob.wizardry.util.EntityUtils;
import electroblob.wizardry.util.GeometryUtils;
import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityXPOrb;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.projectile.EntityArrow;
import net.minecraft.entity.projectile.EntityThrowable;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.play.server.SPacketEntityVelocity;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.MathHelper;
@@ -32,6 +35,7 @@ import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
// TODO: Possibly convert this to EntityScaledConstruct
@Mod.EventBusSubscriber
public class EntityForcefield extends EntityMagicConstruct implements ICustomHitbox {
@@ -63,16 +67,6 @@ public class EntityForcefield extends EntityMagicConstruct implements ICustomHit
return radius;
}
@Override
public boolean canBeCollidedWith(){
return false;//!this.isDead;
}
@Override
public AxisAlignedBB getCollisionBox(Entity entity){
return null;//entity.getEntityBoundingBox();
}
@Nullable
@Override
public AxisAlignedBB getCollisionBoundingBox(){
@@ -244,31 +238,28 @@ public class EntityForcefield extends EntityMagicConstruct implements ICustomHit
return closestPoint.subtract(line.normalize().scale(MathHelper.sqrt(rsquared - dsquared)));
}
// Need to sync the caster because we're now dealing with client-side motion
@Override
public void writeSpawnData(ByteBuf data){
super.writeSpawnData(data);
data.writeFloat(getRadius());
if(getCaster() != null) data.writeInt(getCaster().getEntityId());
}
@Override
public void readSpawnData(ByteBuf data){
super.readSpawnData(data);
setRadius(data.readFloat());
}
if(!data.isReadable()) return;
@Override
protected void writeEntityToNBT(NBTTagCompound nbt){
super.writeEntityToNBT(nbt);
nbt.setFloat("radius", radius);
}
Entity entity = world.getEntityByID(data.readInt());
if(entity instanceof EntityLivingBase){
setCaster((EntityLivingBase)entity);
}else{
Wizardry.logger.warn("Forcefield caster with ID in spawn data not found");
}
@Override
protected void readEntityFromNBT(NBTTagCompound nbt){
super.readEntityFromNBT(nbt);
radius = nbt.getFloat("radius");
}
@Override
@@ -17,12 +17,16 @@ import net.minecraft.world.World;
import java.util.List;
public class EntityFrostSigil extends EntityMagicConstruct {
public class EntityFrostSigil extends EntityScaledConstruct {
public EntityFrostSigil(World world){
super(world);
this.height = 0.2f;
this.width = 2.0f;
setSize(Spells.frost_sigil.getProperty(Spell.EFFECT_RADIUS).floatValue() * 2, 0.2f);
}
@Override
protected boolean shouldScaleHeight(){
return false;
}
@Override
@@ -32,7 +36,7 @@ public class EntityFrostSigil extends EntityMagicConstruct {
if(!this.world.isRemote){
List<EntityLivingBase> targets = EntityUtils.getLivingWithinRadius(1.0d, this.posX, this.posY,
List<EntityLivingBase> targets = EntityUtils.getLivingWithinRadius(width/2, this.posX, this.posY,
this.posZ, this.world);
for(EntityLivingBase target : targets){
@@ -56,8 +60,8 @@ public class EntityFrostSigil extends EntityMagicConstruct {
}
}
}else if(this.rand.nextInt(15) == 0){
double radius = 0.5 + rand.nextDouble() * 0.3;
float angle = rand.nextFloat() * (float)Math.PI * 2;;
double radius = (0.5 + rand.nextDouble() * 0.3) * width/2;
float angle = rand.nextFloat() * (float)Math.PI * 2;
ParticleBuilder.create(Type.SNOW)
.pos(this.posX + radius * MathHelper.cos(angle), this.posY + 0.1, this.posZ + radius * MathHelper.sin(angle))
.vel(0, 0, 0) // Required since default for snow is not stationary
@@ -65,9 +69,6 @@ public class EntityFrostSigil extends EntityMagicConstruct {
}
}
@Override
protected void entityInit(){}
@Override
public boolean canRenderOnFire(){
return false;
@@ -1,15 +1,21 @@
package electroblob.wizardry.entity.construct;
import electroblob.wizardry.entity.projectile.EntityIceShard;
import electroblob.wizardry.registry.Spells;
import electroblob.wizardry.spell.Spell;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
public class EntityHailstorm extends EntityMagicConstruct {
public class EntityHailstorm extends EntityScaledConstruct {
public EntityHailstorm(World world){
super(world);
this.height = 3.0f;
this.width = 5.0f;
setSize(Spells.hailstorm.getProperty(Spell.EFFECT_RADIUS).floatValue() * 2, 5);
}
@Override
protected boolean shouldScaleHeight(){
return false;
}
public void onUpdate(){
@@ -17,15 +23,21 @@ public class EntityHailstorm extends EntityMagicConstruct {
super.onUpdate();
if(!this.world.isRemote){
// System.out.println(this.rotationYaw);
double x = posX + (world.rand.nextDouble() - 0.5D) * (double)width;
double y = posY + world.rand.nextDouble() * (double)height;
double z = posZ + (world.rand.nextDouble() - 0.5D) * (double)width;
EntityIceShard iceshard = new EntityIceShard(world);
iceshard.setPosition(this.posX + rand.nextDouble() * 6 - 3, this.posY + rand.nextDouble() * 4 - 2,
this.posZ + rand.nextDouble() * 6 - 3);
iceshard.setPosition(x, y, z);
iceshard.motionX = MathHelper.cos((float)Math.toRadians(this.rotationYaw + 90));
iceshard.motionY = -0.6;
iceshard.motionZ = MathHelper.sin((float)Math.toRadians(this.rotationYaw + 90));
iceshard.setCaster(this.getCaster());
iceshard.damageMultiplier = this.damageMultiplier;
this.world.spawnEntity(iceshard);
}
}
@@ -15,14 +15,11 @@ import net.minecraft.world.World;
import java.util.List;
public class EntityHealAura extends EntityMagicConstruct {
// TODO: Implement blast modifiers
public class EntityHealAura extends EntityScaledConstruct {
public EntityHealAura(World world){
super(world);
this.height = 1.0f;
this.width = 5.0f;
setSize(Spells.healing_aura.getProperty(Spell.EFFECT_RADIUS).floatValue() * 2, 1);
}
@Override
@@ -36,7 +33,7 @@ public class EntityHealAura extends EntityMagicConstruct {
if(!this.world.isRemote){
List<EntityLivingBase> targets = EntityUtils.getLivingWithinRadius(2.5, posX, posY, posZ, world);
List<EntityLivingBase> targets = EntityUtils.getLivingWithinRadius(width/2, posX, posY, posZ, world);
for(EntityLivingBase target : targets){
@@ -69,8 +66,8 @@ public class EntityHealAura extends EntityMagicConstruct {
}else{
for(int i=1; i<3; i++){
float brightness = 0.5f + (rand.nextFloat() * 0.5f);
double radius = rand.nextDouble() * 2.0;
float angle = rand.nextFloat() * (float)Math.PI * 2;;
double radius = rand.nextDouble() * (width/2);
float angle = rand.nextFloat() * (float)Math.PI * 2;
ParticleBuilder.create(Type.SPARKLE)
.pos(this.posX + radius * MathHelper.cos(angle), this.posY, this.posZ + radius * MathHelper.sin(angle))
.vel(0, 0.05, 0)
@@ -63,7 +63,8 @@ public class EntityIceSpike extends EntityMagicConstruct {
for(Object entity : this.world.getEntitiesWithinAABBExcludingEntity(this, this.getEntityBoundingBox())){
if(entity instanceof EntityLivingBase && this.isValidTarget((EntityLivingBase)entity)){
DamageSource source = this.getCaster() == null ? DamageSource.MAGIC : MagicDamage.causeDirectMagicDamage(this.getCaster(), DamageType.FROST);
// Potion effect only gets added if the damage succeeded.
// Potion effect only gets added if the damage succeeded
// We DO want knockback here or the entity gets stuck on the spike, which is a bit of a cheat
if(((EntityLivingBase)entity).attackEntityFrom(source, Spells.ice_spikes.getProperty(Spell.DAMAGE).floatValue() * this.damageMultiplier))
((EntityLivingBase)entity).addPotionEffect(new PotionEffect(WizardryPotions.frost,
Spells.ice_spikes.getProperty(Spell.EFFECT_DURATION).intValue(),
@@ -15,14 +15,19 @@ import net.minecraft.world.World;
import java.util.List;
public class EntityLightningSigil extends EntityMagicConstruct {
public class EntityLightningSigil extends EntityScaledConstruct {
public static final String SECONDARY_RANGE = "secondary_range";
public static final String SECONDARY_MAX_TARGETS = "secondary_max_targets";
public EntityLightningSigil(World world){
super(world);
this.height = 0.2f;
this.width = 2.0f;
setSize(Spells.frost_sigil.getProperty(Spell.EFFECT_RADIUS).floatValue() * 2, 0.2f);
}
@Override
protected boolean shouldScaleHeight(){
return false;
}
@Override
@@ -34,7 +39,7 @@ public class EntityLightningSigil extends EntityMagicConstruct {
this.setDead();
}
List<EntityLivingBase> targets = EntityUtils.getLivingWithinRadius(1.0d, this.posX, this.posY,
List<EntityLivingBase> targets = EntityUtils.getLivingWithinRadius(width/2, this.posX, this.posY,
this.posZ, this.world);
for(EntityLivingBase target : targets){
@@ -58,7 +63,7 @@ public class EntityLightningSigil extends EntityMagicConstruct {
this.playSound(WizardrySounds.ENTITY_LIGHTNING_SIGIL_TRIGGER, 1.0f, 1.0f);
// Secondary chaining effect
double seekerRange = Spells.lightning_sigil.getProperty(Spell.EFFECT_RADIUS).doubleValue();
double seekerRange = Spells.lightning_sigil.getProperty(SECONDARY_RANGE).doubleValue();
List<EntityLivingBase> secondaryTargets = EntityUtils.getLivingWithinRadius(seekerRange,
target.posX, target.posY + target.height / 2, target.posZ, world);
@@ -96,8 +101,8 @@ public class EntityLightningSigil extends EntityMagicConstruct {
}
if(this.world.isRemote && this.rand.nextInt(15) == 0){
double radius = 0.5 + rand.nextDouble() * 0.3;
float angle = rand.nextFloat() * (float)Math.PI * 2;;
double radius = (0.5 + rand.nextDouble() * 0.3) * width/2;
float angle = rand.nextFloat() * (float)Math.PI * 2;
ParticleBuilder.create(Type.SPARK)
.pos(this.posX + radius * MathHelper.cos(angle), this.posY + 0.1, this.posZ + radius * MathHelper.sin(angle))
.spawn(world);
@@ -24,13 +24,10 @@ import javax.annotation.Nullable;
import java.util.UUID;
/**
* This class is for all inanimate magical constructs which are not projectiles. It was made from scratch to provide a
* unifying superclass for black hole, blizzard, tornado and a few others which all share some characteristics. The
* caster UUID, lifetime and damage multiplier are stored here, and lifetime is also synced here.
* <p></p>
* When extending this class, override both constructors. Generally speaking, subclasses of this class are areas of
* effect which deal damage or apply effects over time.
*
* This class is for all inanimate magical constructs which are not projectiles. Generally speaking, subclasses of this
* class are areas of effect which deal damage or apply effects over time, including black hole, blizzard, tornado and
* a few others. The caster UUID, lifetime and damage multiplier are stored here, and lifetime is also synced here.
*
* @since Wizardry 1.0
*/
public abstract class EntityMagicConstruct extends Entity implements IEntityOwnable, IEntityAdditionalSpawnData {
@@ -40,10 +37,8 @@ public abstract class EntityMagicConstruct extends Entity implements IEntityOwna
* {@link EntityMagicConstruct#getCaster()}. */
private UUID casterUUID;
/**
* The time in ticks this magical construct lasts for; defaults to 600 (30 seconds). If this is -1 the construct
* doesn't despawn.
*/
/** The time in ticks this magical construct lasts for; defaults to 600 (30 seconds). If this is -1 the construct
* doesn't despawn. */
public int lifetime = 600;
/** The damage multiplier for this construct, determined by the wand with which it was cast. */
@@ -78,6 +73,7 @@ public abstract class EntityMagicConstruct extends Entity implements IEntityOwna
@Override
public EnumActionResult applyPlayerInteraction(EntityPlayer player, Vec3d vec, EnumHand hand){
// Permanent constructs can now be dispelled by sneak-right-clicking
if(lifetime == -1 && getCaster() == player && player.isSneaking() && player.getHeldItem(hand).getItem() instanceof ISpellCastingItem){
this.despawn();
return EnumActionResult.SUCCESS;
@@ -98,7 +94,7 @@ public abstract class EntityMagicConstruct extends Entity implements IEntityOwna
@Override
protected void entityInit(){
// We could leave this unimplemented, but since the majority of subclasses don't use it, let's make it optional
}
@Override
@@ -19,13 +19,23 @@ import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
public class EntityRadiantTotem extends EntityMagicConstruct {
public class EntityRadiantTotem extends EntityScaledConstruct {
private static final int PERIMETER_PARTICLE_DENSITY = 6;
public EntityRadiantTotem(World world){
super(world);
this.setSize(1, 1);
this.setSize(1, 1); // This entity is different in that its area of effect is kind of 'outside' it
}
@Override
protected boolean shouldScaleWidth(){
return false;
}
@Override
protected boolean shouldScaleHeight(){
return false;
}
@Override
@@ -37,7 +47,7 @@ public class EntityRadiantTotem extends EntityMagicConstruct {
super.onUpdate();
double radius = Spells.radiant_totem.getProperty(Spell.EFFECT_RADIUS).floatValue(); // TODO: Blast modifiers
double radius = Spells.radiant_totem.getProperty(Spell.EFFECT_RADIUS).floatValue() * sizeMultiplier;
if(world.isRemote){
@@ -0,0 +1,68 @@
package electroblob.wizardry.entity.construct;
import io.netty.buffer.ByteBuf;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
/**
* Extension of {@link EntityMagicConstruct} that implements saving and loading of size (blast) multipliers. What
* the entity actually does with the multiplier value is up to subclasses to define; however, by default this class
* scales the entity bounding box according to the size multiplier (this can be controlled by overriding
* {@link EntityScaledConstruct#shouldScaleWidth()} and {@link EntityScaledConstruct#shouldScaleHeight()}).
*
* @author Electroblob
* @since Wizardry 4.3
*/
public abstract class EntityScaledConstruct extends EntityMagicConstruct {
/** The size multiplier for this construct, usually determined by the blast modifier the spell was cast with. */
protected float sizeMultiplier = 1;
public EntityScaledConstruct(World world){
super(world);
}
public float getSizeMultiplier(){
return sizeMultiplier;
}
public void setSizeMultiplier(float sizeMultiplier){
this.sizeMultiplier = sizeMultiplier;
setSize(shouldScaleWidth() ? width * sizeMultiplier : width, shouldScaleHeight() ? height * sizeMultiplier : height);
}
/** Returns true if the width of this entity's bounding box should be scaled by the size multiplier on creation. */
protected boolean shouldScaleWidth(){
return true;
}
/** Returns true if the height of this entity's bounding box should be scaled by the size multiplier on creation. */
protected boolean shouldScaleHeight(){
return true;
}
@Override
protected void readEntityFromNBT(NBTTagCompound nbt){
super.readEntityFromNBT(nbt);
setSizeMultiplier(nbt.getFloat("sizeMultiplier"));
}
@Override
protected void writeEntityToNBT(NBTTagCompound nbt){
super.writeEntityToNBT(nbt);
nbt.setFloat("sizeMultiplier", sizeMultiplier);
}
@Override
public void readSpawnData(ByteBuf data){
super.readSpawnData(data);
setSizeMultiplier(data.readFloat()); // Set the width correctly on the client side
}
@Override
public void writeSpawnData(ByteBuf data){
super.writeSpawnData(data);
data.writeFloat(sizeMultiplier);
}
}
@@ -1,6 +1,5 @@
package electroblob.wizardry.entity.construct;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.registry.Spells;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.spell.Spell;
@@ -8,47 +7,27 @@ import electroblob.wizardry.util.EntityUtils;
import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.world.World;
import java.util.List;
public class EntityStormcloud extends EntityMagicConstruct {
// private static final DataParameter<Float> RADIUS = new DataParameter<>(21, DataSerializers.FLOAT);
public class EntityStormcloud extends EntityScaledConstruct {
public EntityStormcloud(World world){
super(world);
this.height = 2.0f;
this.width = Spells.stormcloud.getProperty(Spell.EFFECT_RADIUS).floatValue() * 2;
setSize(Spells.stormcloud.getProperty(Spell.EFFECT_RADIUS).floatValue() * 2, 2);
}
// @Override
// protected void entityInit(){
// super.entityInit();
// this.getDataManager().register(RADIUS, width); // TODO: This doesn't work, implement blast modifiers properly into SpellConstruct
// }
// public void multiplyWidth(float multiplier){
// this.setSize(width * multiplier, height);
// this.getDataManager().set(RADIUS, width);
// }
@Override
protected boolean shouldScaleHeight(){
return false;
}
public void onUpdate(){
super.onUpdate();
// if(world.isRemote){
// float radius = this.getDataManager().get(RADIUS);
// if(radius != width) this.setSize(radius, height);
// }else{
// if(this.getDataManager().get(RADIUS) != width) this.getDataManager().set(RADIUS, width);
// }
// if(this.ticksExisted % 35 == 0) this.playSound(WizardrySounds.ENTITY_STORMCLOUD_AMBIENT, 1, 1);
if(this.world.isRemote){
float areaFactor = (width * width) / 36; // Ensures cloud/raindrop density stays the same for different sizes
@@ -83,16 +62,6 @@ public class EntityStormcloud extends EntityMagicConstruct {
}
}
// BlockPos pos = new BlockPos(this);
//
// for(int x = -(int)(this.width/2); x <= this.width/2 + 0.5; x++){
// for(int z = -(int)(this.width/2); z <= this.width/2 + 0.5; z++){
//
// int y = WizardryUtilities.getNearestFloor()
//
// }
// }
}
}
@@ -7,8 +7,11 @@ import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.spell.Spell;
import electroblob.wizardry.spell.Tornado;
import electroblob.wizardry.util.*;
import electroblob.wizardry.util.BlockUtils;
import electroblob.wizardry.util.EntityUtils;
import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import io.netty.buffer.ByteBuf;
import net.minecraft.block.material.Material;
@@ -27,17 +30,21 @@ import net.minecraft.world.World;
import java.util.List;
public class EntityTornado extends EntityMagicConstruct {
public class EntityTornado extends EntityScaledConstruct {
private double velX, velZ;
public EntityTornado(World world){
super(world);
this.height = 8.0f;
this.width = 5.0f;
setSize(Spells.tornado.getProperty(Spell.EFFECT_RADIUS).floatValue(), 8);
this.isImmuneToFire = false;
}
@Override
protected boolean shouldScaleHeight(){
return false;
}
public void setHorizontalVelocity(double velX, double velZ){
this.velX = velX;
this.velZ = velZ;
@@ -48,7 +55,7 @@ public class EntityTornado extends EntityMagicConstruct {
super.onUpdate();
double radius = Spells.tornado.getProperty(Spell.EFFECT_RADIUS).doubleValue();
double radius = width/2;
if(this.ticksExisted % 120 == 1 && world.isRemote){
// Repeat is false so that the sound fades out when the tornado does rather than stopping suddenly