Spell hierarchisation and refactoring, plus miscellaneous renaming and minor refactoring

- Adds new generic spell superclasses which aim to group spells such that duplicate code is eliminated, and functions standardised, as much as possible.
- Removes numerous spell classes which are no longer required as a result of this change, and replaces them with instances of the relevant generic spell classes.
- Changes the remaining spell classes to fit with the new system, mostly by having them extend the generic spell classes.
- Completes the transfer of particle spawning to the ParticleBuilder system.
This commit is contained in:
Electroblob
2018-06-20 22:25:54 +01:00
parent b6400c72a7
commit 29261082f1
222 changed files with 4412 additions and 9016 deletions
@@ -1,51 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.MobEffects;
import net.minecraft.item.EnumAction;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class Agility extends Spell {
public Agility(){
super(Tier.APPRENTICE, 20, Element.SORCERY, "agility", SpellType.UTILITY, 40, EnumAction.BOW, false);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
// 1.10 allows the particles to be completely hidden.
caster.addPotionEffect(new PotionEffect(MobEffects.SPEED,
(int)(600 * modifiers.get(WizardryItems.duration_upgrade)), 1, false, false));
caster.addPotionEffect(new PotionEffect(MobEffects.JUMP_BOOST,
(int)(600 * modifiers.get(WizardryItems.duration_upgrade)), 1, false, false));
if(world.isRemote){
for(int i = 0; i < 10; i++){
double x1 = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat());
double z1 = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
ParticleBuilder.create(Type.SPARKLE).pos(x1, y1, z1).vel(0, 0.1F, 0)
.lifetime(48 + world.rand.nextInt(12)).colour(0.4f, 1.0f, 0.8f).spawn(world);
}
Wizardry.proxy.spawnEntityParticle(world, caster, 15, 0.4f, 1.0f, 0.8f);
}
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F,
world.rand.nextFloat() * 0.4F + 1.0F);
return true;
}
}
@@ -1,119 +1,68 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.EntityArc;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.World;
// This spell was the 'guinea pig' for damage types, so to speak, so there's a bit of commentary on them here that may
// be useful for future reference.
public class Arc extends Spell {
public class Arc extends SpellRay {
private static final float BASE_DAMAGE = 3;
public Arc(){
super(Tier.BASIC, 5, Element.LIGHTNING, "arc", SpellType.ATTACK, 15, EnumAction.NONE, false);
super("arc", Tier.BASIC, Element.LIGHTNING, SpellType.ATTACK, 5, 15, false, 8, null);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster,
8 * modifiers.get(WizardryItems.range_upgrade), 4.0f);
if(rayTrace != null && rayTrace.entityHit != null && WizardryUtilities.isLiving(rayTrace.entityHit)){
Entity target = rayTrace.entityHit;
protected boolean onEntityHit(World world, Entity target, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
if(WizardryUtilities.isLiving(target)){
if(!world.isRemote){
EntityArc arc = new EntityArc(world);
arc.setEndpointCoords(caster.posX, caster.posY + 1, caster.posZ, target.posX,
target.posY + target.height / 2, target.posZ);
arc.setEndpointCoords(caster.posX, caster.posY + 1, caster.posZ, target.posX, target.posY + target.height / 2, target.posZ);
world.spawnEntity(arc);
}else{
for(int i = 0; i < 8; i++){
Wizardry.proxy.spawnParticle(Type.SPARK, world,
target.posX + world.rand.nextFloat() - 0.5,
target.getEntityBoundingBox().minY + target.height / 2 + world.rand.nextFloat() * 2 - 1,
target.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3);
world.spawnParticle(EnumParticleTypes.SMOKE_LARGE, target.posX + world.rand.nextFloat() - 0.5,
target.getEntityBoundingBox().minY + target.height / 2 + world.rand.nextFloat() * 2 - 1,
target.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0);
}
ParticleBuilder.spawnShockParticles(world, target.posX, target.getEntityBoundingBox().minY + target.height/2, target.posZ);
}
// This is a lot neater than it was, thanks to the damage type system.
if(MagicDamage.isEntityImmune(DamageType.SHOCK, target)){
if(!world.isRemote) caster.sendMessage(new TextComponentTranslation("spell.resist", target.getName(),
this.getNameForTranslationFormatted()));
}else{
target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK),
3.0f * modifiers.get(SpellModifiers.DAMAGE));
BASE_DAMAGE * modifiers.get(SpellModifiers.POTENCY));
}
caster.swingArm(hand);
// TODO: Does this mean that players hit by the spell hear no sound?
target.playSound(WizardrySounds.SPELL_SPARK, 1.0F, world.rand.nextFloat() * 0.4F + 1.5F);
return true;
}
return false;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
if(!world.isRemote){
EntityArc arc = new EntityArc(world);
arc.setEndpointCoords(caster.posX, caster.posY + 1, caster.posZ, target.posX,
target.posY + target.height / 2, target.posZ);
world.spawnEntity(arc);
}else{
for(int i = 0; i < 8; i++){
Wizardry.proxy.spawnParticle(Type.SPARK, world,
target.posX + world.rand.nextFloat() - 0.5,
target.getEntityBoundingBox().minY + target.height / 2 + world.rand.nextFloat() * 2 - 1,
target.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3);
world.spawnParticle(EnumParticleTypes.SMOKE_LARGE, target.posX + world.rand.nextFloat() - 0.5,
target.getEntityBoundingBox().minY + target.height / 2 + world.rand.nextFloat() * 2 - 1,
target.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0);
}
}
// What's great about the damage type system is that, because I don't need to know if the creature resisted
// the damage here, I can simply call this without having to check for immunities at all.
target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK),
3.0f * modifiers.get(SpellModifiers.DAMAGE));
caster.swingArm(hand);
target.playSound(WizardrySounds.SPELL_SPARK, 1.0F, world.rand.nextFloat() * 0.4F + 1.5F);
return true;
}
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
}
@@ -1,6 +1,5 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
@@ -10,105 +9,65 @@ import electroblob.wizardry.registry.WizardryAdvancementTriggers;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardryPotions;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
@Mod.EventBusSubscriber
public class ArcaneJammer extends Spell {
public class ArcaneJammer extends SpellRay {
public ArcaneJammer(){
super(Tier.ADVANCED, 30, Element.HEALING, "arcane_jammer", SpellType.ATTACK, 50, EnumAction.NONE, false);
super("arcane_jammer", Tier.ADVANCED, Element.HEALING, SpellType.ATTACK, 30, 50, false, 10, WizardrySounds.SPELL_DEFLECTION);
this.soundValues(0.7f, 1, 0.4f);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
Vec3d look = caster.getLookVec();
RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster,
10 * modifiers.get(WizardryItems.range_upgrade));
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY && WizardryUtilities.isLiving(rayTrace.entityHit)){
EntityLivingBase entity = (EntityLivingBase)rayTrace.entityHit;
if(entity instanceof EntityWizard) WizardryAdvancementTriggers.jam_wizard.triggerFor(caster);
protected boolean onEntityHit(World world, Entity target, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
if(WizardryUtilities.isLiving(target)){
if(target instanceof EntityWizard && caster instanceof EntityPlayer)
WizardryAdvancementTriggers.jam_wizard.triggerFor((EntityPlayer)caster);
if(!world.isRemote){
entity.addPotionEffect(new PotionEffect(WizardryPotions.arcane_jammer,
((EntityLivingBase)target).addPotionEffect(new PotionEffect(WizardryPotions.arcane_jammer,
(int)(300 * modifiers.get(WizardryItems.duration_upgrade)), 0));
}
}
if(world.isRemote){
for(int i = 1; i < (int)(25 * modifiers.get(WizardryItems.range_upgrade)); i += 2){
double x1 = caster.posX + look.x * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
double y1 = WizardryUtilities.getPlayerEyesPos(caster) - 0.4f + look.y * i / 2
+ world.rand.nextFloat() / 5 - 0.1f;
double z1 = caster.posZ + look.z * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d,
12 + world.rand.nextInt(8), 0.9f, 0.3f, 0.7f);
}
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_DEFLECTION, 0.7F,
world.rand.nextFloat() * 0.4F + 0.8F);
return true;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
if(!world.isRemote){
target.addPotionEffect(new PotionEffect(WizardryPotions.arcane_jammer,
(int)(300 * modifiers.get(WizardryItems.duration_upgrade)), 0));
}
if(world.isRemote){
double dx = (target.posX - caster.posX) / caster.getDistance(target);
double dy = (target.posY - caster.posY) / caster.getDistance(target);
double dz = (target.posZ - caster.posZ) / caster.getDistance(target);
for(int i = 1; i < (int)(25 * modifiers.get(WizardryItems.range_upgrade)); i += 2){
double x1 = caster.posX + dx * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
double y1 = caster.posY + caster.getEyeHeight() - 0.4f + dy * i / 2 + world.rand.nextFloat() / 5
- 0.1f;
double z1 = caster.posZ + dz * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d,
12 + world.rand.nextInt(8), 0.9f, 0.3f, 0.7f);
}
}
caster.swingArm(hand);
caster.playSound(WizardrySounds.SPELL_DEFLECTION, 0.7F, world.rand.nextFloat() * 0.4F + 0.8F);
}
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@Override
public boolean canBeCastByNPCs(){
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return true;
}
@Override
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).lifetime(12 + world.rand.nextInt(8)).colour(0.9f, 0.3f, 0.7f)
.spawn(world);
}
@SubscribeEvent
public static void onSpellCastPreEvent(SpellCastEvent.Pre event){
// Arcane jammer prevents spell casting.
if(event.getEntityLiving().isPotionActive(WizardryPotions.arcane_jammer)) event.setCanceled(true);
if(event.getCaster() != null && event.getCaster().isPotionActive(WizardryPotions.arcane_jammer)) event.setCanceled(true);
}
}
@@ -4,58 +4,38 @@ import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.construct.EntityArrowRain;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.world.World;
public class ArrowRain extends Spell {
public class ArrowRain extends SpellConstructRanged<EntityArrowRain> {
public ArrowRain(){
super(Tier.MASTER, 75, Element.SORCERY, "arrow_rain", SpellType.ATTACK, 300, EnumAction.NONE, false);
super("arrow_rain", Tier.MASTER, Element.SORCERY, SpellType.ATTACK, 75, 300, EntityArrowRain::new, 120, 20, WizardrySounds.SPELL_SUMMONING);
this.floor(true);
}
@Override
public boolean doesSpellRequirePacket(){
return false;
protected boolean spawnConstruct(World world, double x, double y, double z, EntityLivingBase caster, SpellModifiers modifiers){
// Moves the entity back towards the caster a bit, so the area of effect is better centred on the position.
// 3 is the distance to move the entity back towards the caster.
double dx = caster.posX - x;
double dz = caster.posZ - z;
double distRatio = 3 / Math.sqrt(dx * dx + dz * dz);
x += dx * distRatio;
z += dz * distRatio;
// Moves the entity up 5 blocks so that it is above mobs' heads.
y += 5;
return super.spawnConstruct(world, x, y, z, caster, modifiers);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
RayTraceResult rayTrace = WizardryUtilities.rayTrace(20 * modifiers.get(WizardryItems.range_upgrade), world,
caster, false);
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){
if(!world.isRemote){
double x = rayTrace.hitVec.x;
double y = rayTrace.hitVec.y;
double z = rayTrace.hitVec.z;
// Moves the entity back towards the caster a bit, so the area of effect is better centred on the
// position.
// 3.0d is the distance to move the entity back towards the caster.
double dx = caster.posX - x;
double dz = caster.posZ - z;
double distRatio = 3.0d / Math.sqrt(dx * dx + dz * dz);
x += dx * distRatio;
z += dz * distRatio;
EntityArrowRain arrowrain = new EntityArrowRain(world, x, y + 5, z, caster,
(int)(120 * modifiers.get(WizardryItems.duration_upgrade)),
modifiers.get(SpellModifiers.DAMAGE));
arrowrain.rotationYaw = caster.rotationYawHead;
world.spawnEntity(arrowrain);
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_SUMMONING, 1.0F, 1.0F);
return true;
}
return false;
protected void addConstructExtras(EntityArrowRain construct, EntityLivingBase caster, SpellModifiers modifiers){
// Makes the arrows shoot in the direction the caster was looking when they cast the spell.
construct.rotationYaw = caster.rotationYawHead;
}
}
@@ -1,58 +1,48 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
public class Banish extends Spell {
public class Banish extends SpellRay {
public Banish(){
super(Tier.APPRENTICE, 15, Element.NECROMANCY, "banish", SpellType.ATTACK, 40, EnumAction.NONE, false);
super("banish", Tier.APPRENTICE, Element.NECROMANCY, SpellType.ATTACK, 15, 40, false, 10, SoundEvents.ENTITY_ENDERMEN_TELEPORT);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
protected boolean onEntityHit(World world, Entity target, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
if(target instanceof EntityLivingBase){
Vec3d look = caster.getLookVec();
RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster,
10 * modifiers.get(WizardryItems.range_upgrade));
// Left as EntityLivingBase, since it's reasonable to teleport armour stands around.
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY && rayTrace.entityHit instanceof EntityLivingBase){
EntityLivingBase target = (EntityLivingBase)rayTrace.entityHit;
EntityLivingBase entity = (EntityLivingBase)target;
double radius = (8 + world.rand.nextDouble() * 8) * modifiers.get(WizardryItems.range_upgrade);
double angle = world.rand.nextDouble() * Math.PI * 2;
int x = MathHelper.floor(target.posX + Math.sin(angle) * radius);
int z = MathHelper.floor(target.posZ - Math.cos(angle) * radius);
int x = MathHelper.floor(entity.posX + Math.sin(angle) * radius);
int z = MathHelper.floor(entity.posZ - Math.cos(angle) * radius);
int y = WizardryUtilities.getNearestFloorLevel(world,
new BlockPos(x, (int)caster.getEntityBoundingBox().minY, z), (int)radius);
if(world.isRemote){
for(int i = 0; i < 10; i++){
double dx1 = target.posX;
double dy1 = target.getEntityBoundingBox().minY + target.height * world.rand.nextFloat();
double dz1 = target.posZ;
for(int i=0; i<10; i++){
double dx1 = entity.posX;
double dy1 = entity.getEntityBoundingBox().minY + entity.height * world.rand.nextFloat();
double dz1 = entity.posZ;
world.spawnParticle(EnumParticleTypes.PORTAL, dx1, dy1, dz1, world.rand.nextDouble() - 0.5,
world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5);
}
@@ -60,7 +50,7 @@ public class Banish extends Spell {
if(y > -1){
// This means stuff like snow layers is ignored, meaning when on snow-covered ground the caster does
// This means stuff like snow layers is ignored, meaning when on snow-covered ground the target does
// not teleport 1 block above the ground.
if(!world.getBlockState(new BlockPos(x, y, z)).getMaterial().blocksMovement()){
y--;
@@ -72,101 +62,30 @@ public class Banish extends Spell {
}
if(!world.isRemote){
target.setPositionAndUpdate(x + 0.5, y + 1, z + 0.5);
entity.setPositionAndUpdate(x + 0.5, y + 1, z + 0.5);
}
target.playSound(SoundEvents.ENTITY_ENDERMEN_TELEPORT, 1.0F, 1.0f);
entity.playSound(SoundEvents.ENTITY_ENDERMEN_TELEPORT, 1.0F, 1.0f);
}
}
if(world.isRemote){
for(int i = 1; i < (int)(25 * modifiers.get(WizardryItems.range_upgrade)); i += 2){
double x1 = caster.posX + look.x * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
double y1 = WizardryUtilities.getPlayerEyesPos(caster) - 0.4f + look.y * i / 2
+ world.rand.nextFloat() / 5 - 0.1f;
double z1 = caster.posZ + look.z * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
world.spawnParticle(EnumParticleTypes.PORTAL, x1, y1 - 0.5, z1, 0.0d, 0.0d, 0.0d);
Wizardry.proxy.spawnParticle(Type.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0,
0.2f, 0.0f, 0.2f);
}
}
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_ENDERMEN_TELEPORT, 1.0F, 1.0f);
caster.swingArm(hand);
return true;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
double radius = (8 + world.rand.nextDouble() * 8) * modifiers.get(WizardryItems.range_upgrade);
double angle = world.rand.nextDouble() * Math.PI * 2;
int x = MathHelper.floor(target.posX + Math.sin(angle) * radius);
int z = MathHelper.floor(target.posZ - Math.cos(angle) * radius);
int y = WizardryUtilities.getNearestFloorLevel(world,
new BlockPos(x, (int)caster.getEntityBoundingBox().minY, z), (int)radius);
if(world.isRemote){
double dx = (target.posX - caster.posX) / caster.getDistance(target);
double dy = (target.posY - caster.posY) / caster.getDistance(target);
double dz = (target.posZ - caster.posZ) / caster.getDistance(target);
for(int i = 1; i < 25; i += 2){
double x1 = caster.posX + dx * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
double y1 = caster.posY + caster.getEyeHeight() - 0.4f + dy * i / 2 + world.rand.nextFloat() / 5
- 0.1f;
double z1 = caster.posZ + dz * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
world.spawnParticle(EnumParticleTypes.PORTAL, x1, y1 - 0.5, z1, 0.0d, 0.0d, 0.0d);
Wizardry.proxy.spawnParticle(Type.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d,
0, 0.2f, 0.0f, 0.2f);
}
for(int i = 0; i < 10; i++){
double dx1 = target.posX;
double dy1 = target.getEntityBoundingBox().minY + target.height * world.rand.nextFloat();
double dz1 = target.posZ;
world.spawnParticle(EnumParticleTypes.PORTAL, dx1, dy1, dz1, world.rand.nextDouble() - 0.5,
world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5);
}
}
if(y > -1){
// This means stuff like snow layers is ignored, meaning when on snow-covered ground the caster does
// not teleport 1 block above the ground.
if(!world.getBlockState(new BlockPos(x, y, z)).getMaterial().blocksMovement()){
y--;
}
if(world.getBlockState(new BlockPos(x, y + 1, z)).getMaterial().blocksMovement()
|| world.getBlockState(new BlockPos(x, y + 2, z)).getMaterial().blocksMovement()){
return false;
}
if(!world.isRemote){
target.setPositionAndUpdate(x + 0.5, y + 1, z + 0.5);
}
target.playSound(SoundEvents.ENTITY_ENDERMEN_TELEPORT, 1.0F, 1.0f);
}
}
caster.playSound(SoundEvents.ENTITY_ENDERMEN_TELEPORT, 1.0F, 1.0f);
caster.swingArm(hand);
return true;
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@Override
public boolean canBeCastByNPCs(){
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return true;
}
@Override
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
world.spawnParticle(EnumParticleTypes.PORTAL, x, y - 0.5, z, 0, 0, 0);
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).colour(0.2f, 0, 0.2f).spawn(world);
}
}
@@ -1,70 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.construct.EntityBlackHole;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World;
public class BlackHole extends Spell {
public BlackHole(){
super(Tier.MASTER, 150, Element.SORCERY, "black_hole", SpellType.ATTACK, 400, EnumAction.NONE, false);
}
@Override
public boolean doesSpellRequirePacket(){
return false;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
RayTraceResult rayTrace = WizardryUtilities.rayTrace(10 * modifiers.get(WizardryItems.range_upgrade), world,
caster, false);
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){
// This demonstrates beautifully the elegance of BlockPos. In 1.7.10 this required a 50-line long switch
// statement and a flag variable; now it only needs a few lines.
BlockPos pos = new BlockPos(rayTrace.hitVec).offset(rayTrace.sideHit);
if(world.isAirBlock(pos)){
if(!world.isRemote){
world.spawnEntity(new EntityBlackHole(world, pos.getX() + 0.5, pos.getY() - 1 + 0.5,
pos.getZ() + 0.5, caster, (int)(600 * modifiers.get(WizardryItems.duration_upgrade)),
modifiers.get(SpellModifiers.DAMAGE)));
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_WITHER_SPAWN, 2.0f, 0.7f);
return true;
}
}else{
int x = (int)(Math.floor(caster.posX) + caster.getLookVec().x * 8);
int y = (int)(Math.floor(caster.posY) + caster.eyeHeight + caster.getLookVec().y * 8);
int z = (int)(Math.floor(caster.posZ) + caster.getLookVec().z * 8);
if(!world.isRemote){
world.spawnEntity(new EntityBlackHole(world, x, y, z, caster,
(int)(600 * modifiers.get(WizardryItems.duration_upgrade)),
modifiers.get(SpellModifiers.DAMAGE)));
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_WITHER_SPAWN, 2.0f, 0.7f);
return true;
}
return false;
}
}
@@ -22,14 +22,14 @@ import net.minecraft.world.World;
public class Blink extends Spell {
public Blink(){
super(Tier.APPRENTICE, 15, Element.SORCERY, "blink", SpellType.UTILITY, 25, EnumAction.NONE, false);
super("blink", Tier.APPRENTICE, Element.SORCERY, SpellType.UTILITY, 15, 25, EnumAction.NONE, false);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
RayTraceResult rayTrace = WizardryUtilities.rayTrace(25 * modifiers.get(WizardryItems.range_upgrade), world,
caster, false);
RayTraceResult rayTrace = WizardryUtilities.standardBlockRayTrace(world, caster,
25 * modifiers.get(WizardryItems.range_upgrade), false);
// It's worth noting that on the client side, the cast() method only gets called if the server side
// cast method succeeded, so you need not check any conditions for spawning particles.
@@ -1,81 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.construct.EntityBlizzard;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World;
public class Blizzard extends Spell {
public Blizzard(){
super(Tier.ADVANCED, 40, Element.ICE, "blizzard", SpellType.ATTACK, 100, EnumAction.NONE, false);
}
@Override
public boolean doesSpellRequirePacket(){
return false;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
RayTraceResult rayTrace = WizardryUtilities.rayTrace(20 * modifiers.get(WizardryItems.range_upgrade), world,
caster, false);
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){
if(!world.isRemote){
double x = rayTrace.hitVec.x;
double y = rayTrace.hitVec.y;
double z = rayTrace.hitVec.z;
EntityBlizzard blizzard = new EntityBlizzard(world, x, y + 0.5, z, caster,
(int)(600 * modifiers.get(WizardryItems.duration_upgrade)),
modifiers.get(SpellModifiers.DAMAGE));
world.spawnEntity(blizzard);
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 1.0F, 1.0F);
return true;
}
return false;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
if(!world.isRemote){
double x = target.posX;
double y = target.posY;
double z = target.posZ;
EntityBlizzard blizzard = new EntityBlizzard(world, x, y + 0.5, z, caster,
(int)(600 * modifiers.get(WizardryItems.duration_upgrade)),
modifiers.get(SpellModifiers.DAMAGE));
world.spawnEntity(blizzard);
}
caster.swingArm(hand);
caster.playSound(WizardrySounds.SPELL_ICE, 1.0F, 1.0F);
return true;
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
}
}
@@ -1,6 +1,5 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
@@ -9,115 +8,81 @@ import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class Bubble extends Spell {
public class Bubble extends SpellRay {
public Bubble(){
super(Tier.APPRENTICE, 15, Element.EARTH, "bubble", SpellType.ATTACK, 20, EnumAction.NONE, false);
super("bubble", Tier.APPRENTICE, Element.EARTH, SpellType.ATTACK, 15, 20, false, 10, WizardrySounds.SPELL_ICE);
this.soundValues(0.5f, 1.1f, 0.2f);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
// This spell uses more than one sound, so this is required...
boolean flag = super.cast(world, caster, hand, ticksInUse, modifiers);
if(flag) WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_GENERIC_SWIM, 1, 1 + 0.2f * world.rand.nextFloat());
return flag;
}
Vec3d look = caster.getLookVec();
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){
boolean flag = super.cast(world, caster, hand, ticksInUse, target, modifiers);
if(flag) caster.playSound(SoundEvents.ENTITY_GENERIC_SWIM, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F);
return flag;
}
RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster,
10 * modifiers.get(WizardryItems.range_upgrade));
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY && WizardryUtilities.isLiving(rayTrace.entityHit)){
EntityLivingBase entity = (EntityLivingBase)rayTrace.entityHit;
@Override
protected boolean onEntityHit(World world, Entity target, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
if(WizardryUtilities.isLiving(target)){
if(!world.isRemote){
entity.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.MAGIC),
1.0f * modifiers.get(SpellModifiers.DAMAGE));
// Deprecated in favour of entity riding method
// entity.addPotionEffect(new PotionEffect(Wizardry.bubblePotion, 200, 0));
EntityBubble entitybubble = new EntityBubble(world, entity.posX, entity.posY, entity.posZ, caster,
(int)(200 * modifiers.get(WizardryItems.duration_upgrade)), false,
modifiers.get(SpellModifiers.DAMAGE));
world.spawnEntity(entitybubble);
entity.startRiding(entitybubble);
// Deals a small amount damage so the target counts as being hit by the caster
target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.MAGIC), 1);
EntityBubble bubble = new EntityBubble(world);
bubble.setPosition(target.posX, target.posY, target.posZ);
bubble.setCaster(caster);
bubble.lifetime = ((int)(200 * modifiers.get(WizardryItems.duration_upgrade)));
bubble.isDarkOrb = false;
bubble.damageMultiplier = modifiers.get(SpellModifiers.POTENCY);
world.spawnEntity(bubble);
target.startRiding(bubble);
}
}
if(world.isRemote){
for(int i = 1; i < (int)(25 * modifiers.get(WizardryItems.range_upgrade)); i += 2){
double x1 = caster.posX + look.x * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
double y1 = WizardryUtilities.getPlayerEyesPos(caster) - 0.4f + look.y * i / 2
+ world.rand.nextFloat() / 5 - 0.1f;
double z1 = caster.posZ + look.z * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
world.spawnParticle(EnumParticleTypes.WATER_SPLASH, x1, y1, z1, 0.0d, 0.0d, 0.0d);
Wizardry.proxy.spawnParticle(Type.MAGIC_BUBBLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0);
}
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_GENERIC_SWIM, 1.0F,
world.rand.nextFloat() * 0.2F + 1.0F);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 0.5F,
world.rand.nextFloat() * 0.2F + 1.0F);
return true;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
if(!world.isRemote){
target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.MAGIC),
1.0f * modifiers.get(SpellModifiers.DAMAGE));
// Deprecated in favour of entity riding method
// entity.addPotionEffect(new PotionEffect(Wizardry.bubblePotion, 200, 0));
EntityBubble entitybubble = new EntityBubble(world, target.posX, target.posY, target.posZ, caster,
(int)(200 * modifiers.get(WizardryItems.duration_upgrade)), false,
modifiers.get(SpellModifiers.DAMAGE));
world.spawnEntity(entitybubble);
target.startRiding(entitybubble);
}
if(world.isRemote){
double dx = (target.posX - caster.posX) / caster.getDistance(target);
double dy = (target.posY - caster.posY) / caster.getDistance(target);
double dz = (target.posZ - caster.posZ) / caster.getDistance(target);
for(int i = 1; i < (int)(25 * modifiers.get(WizardryItems.range_upgrade)); i += 2){
double x1 = caster.posX + dx * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
double y1 = caster.posY + caster.getEyeHeight() - 0.4f + dy * i / 2 + world.rand.nextFloat() / 5
- 0.1f;
double z1 = caster.posZ + dz * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
world.spawnParticle(EnumParticleTypes.WATER_SPLASH, x1, y1, z1, 0.0d, 0.0d, 0.0d);
Wizardry.proxy.spawnParticle(Type.MAGIC_BUBBLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d,
0);
}
}
caster.swingArm(hand);
caster.playSound(SoundEvents.ENTITY_GENERIC_SWIM, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F);
caster.playSound(WizardrySounds.SPELL_ICE, 0.5F, world.rand.nextFloat() * 0.2F + 1.0F);
return true;
}
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@Override
public boolean canBeCastByNPCs(){
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return true;
}
@Override
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
world.spawnParticle(EnumParticleTypes.WATER_SPLASH, x, y, z, 0, 0, 0);
ParticleBuilder.create(Type.MAGIC_BUBBLE).pos(x, y, z).spawn(world);
}
}
@@ -2,181 +2,116 @@ package electroblob.wizardry.spell;
import java.util.List;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.EntityArc;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityArmorStand;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.World;
public class ChainLightning extends Spell {
public class ChainLightning extends SpellRay {
private static final float PRIMARY_DAMAGE = 10;
private static final float SECONDARY_DAMAGE = 8;
private static final float TERTIARY_DAMAGE = 6;
private static final double PRIMARY_RANGE = 10;
private static final double SECONDARY_RANGE = 5;
private static final double TERTIARY_RANGE = 5;
private static final int SECONDARY_MAX_TARGETS = 5;
private static final int TERTIARY_MAX_TARGETS = 2; // This is per secondary target, giving 10 in total
public ChainLightning(){
super(Tier.ADVANCED, 25, Element.LIGHTNING, "chain_lightning", SpellType.ATTACK, 50, EnumAction.NONE, false);
super("chain_lightning", Tier.ADVANCED, Element.LIGHTNING, SpellType.ATTACK, 25, 50, false, PRIMARY_RANGE, null);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
// First shot has range 10 (this is the only range affected by upgrades) and does 5 hearts of damage.
// Chains to up to 5 secondary targets within a range of 5 of the primary target, and then to up to 2
// tertiary targets per secondary target within a range of 5 of that. Secondary targets are dealt 4 hearts
// of damage; tertiary targets are dealt 3 hearts of damage.
RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster,
10 * modifiers.get(WizardryItems.range_upgrade), 8.0f);
protected boolean onEntityHit(World world, Entity target, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
// Anything can be attacked with the initial arc, because the player has control over where it goes. If they
// hit a minion or an ally, it's their problem!
if(rayTrace != null && rayTrace.entityHit != null && WizardryUtilities.isLiving(rayTrace.entityHit)){
if(WizardryUtilities.isLiving(target)){
Entity target = rayTrace.entityHit;
if(!world.isRemote){
EntityArc arc = new EntityArc(world);
arc.setEndpointCoords(caster.posX, caster.posY + caster.height / 2, caster.posZ, target.posX,
target.posY + target.height / 2, target.posZ);
world.spawnEntity(arc);
}else{
for(int i = 0; i < 8; i++){
Wizardry.proxy.spawnParticle(Type.SPARK, world,
target.posX + world.rand.nextFloat() - 0.5,
target.getEntityBoundingBox().minY + target.height / 2 + world.rand.nextFloat() * 2 - 1,
target.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3);
world.spawnParticle(EnumParticleTypes.SMOKE_LARGE, target.posX + world.rand.nextFloat() - 0.5,
target.getEntityBoundingBox().minY + target.height / 2 + world.rand.nextFloat() * 2 - 1,
target.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0);
}
}
target.playSound(WizardrySounds.SPELL_SPARK, 1.0F, world.rand.nextFloat() * 0.4F + 1.5F);
if(MagicDamage.isEntityImmune(DamageType.SHOCK, target)){
if(!world.isRemote) caster.sendMessage(new TextComponentTranslation("spell.resist", target.getName(),
this.getNameForTranslationFormatted()));
}else{
target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK),
10.0f * modifiers.get(SpellModifiers.DAMAGE));
}
electrocute(world, caster, caster, target, PRIMARY_DAMAGE * modifiers.get(SpellModifiers.POTENCY));
// Secondary chaining effect
double seekerRange = 5.0d;
List<EntityLivingBase> secondaryTargets = WizardryUtilities.getEntitiesWithinRadius(seekerRange,
List<EntityLivingBase> secondaryTargets = WizardryUtilities.getEntitiesWithinRadius(SECONDARY_RANGE,
target.posX, target.posY + target.height / 2, target.posZ, world);
secondaryTargets.removeIf(e -> e instanceof EntityArmorStand);
for(int i = 0; i < Math.min(secondaryTargets.size(), 5); i++){
secondaryTargets.remove(target);
secondaryTargets.removeIf(e -> !WizardryUtilities.isLiving(e));
secondaryTargets.removeIf(e -> !WizardryUtilities.isValidTarget(caster, e));
if(secondaryTargets.size() > SECONDARY_MAX_TARGETS) secondaryTargets = secondaryTargets.subList(0, SECONDARY_MAX_TARGETS);
EntityLivingBase secondaryTarget = secondaryTargets.get(i);
for(EntityLivingBase secondaryTarget : secondaryTargets){
if(secondaryTarget != target && WizardryUtilities.isValidTarget(caster, secondaryTarget)){
electrocute(world, caster, target, secondaryTarget,
SECONDARY_DAMAGE * modifiers.get(SpellModifiers.POTENCY));
if(!world.isRemote){
EntityArc arc = new EntityArc(world);
arc.setEndpointCoords(target.posX, target.posY + target.height / 2, target.posZ,
secondaryTarget.posX, secondaryTarget.posY + secondaryTarget.height / 2,
secondaryTarget.posZ);
world.spawnEntity(arc);
}else{
for(int j = 0; j < 8; j++){
Wizardry.proxy.spawnParticle(Type.SPARK, world,
secondaryTarget.posX + world.rand.nextFloat() - 0.5,
secondaryTarget.getEntityBoundingBox().minY + secondaryTarget.height / 2
+ world.rand.nextFloat() * 2 - 1,
secondaryTarget.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3);
world.spawnParticle(EnumParticleTypes.SMOKE_LARGE,
secondaryTarget.posX + world.rand.nextFloat() - 0.5,
secondaryTarget.getEntityBoundingBox().minY + secondaryTarget.height / 2
+ world.rand.nextFloat() * 2 - 1,
secondaryTarget.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0);
}
}
// Tertiary chaining effect
secondaryTarget.playSound(WizardrySounds.SPELL_SPARK, 1.0F, world.rand.nextFloat() * 0.4F + 1.5F);
List<EntityLivingBase> tertiaryTargets = WizardryUtilities.getEntitiesWithinRadius(TERTIARY_RANGE,
secondaryTarget.posX, secondaryTarget.posY + secondaryTarget.height / 2,
secondaryTarget.posZ, world);
if(MagicDamage.isEntityImmune(DamageType.SHOCK, secondaryTarget)){
if(!world.isRemote) caster.sendMessage(new TextComponentTranslation("spell.resist",
secondaryTarget.getName(), this.getNameForTranslationFormatted()));
}else{
secondaryTarget.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK),
8.0f * modifiers.get(SpellModifiers.DAMAGE));
}
tertiaryTargets.remove(target);
tertiaryTargets.removeAll(secondaryTargets);
tertiaryTargets.removeIf(e -> !WizardryUtilities.isLiving(e));
tertiaryTargets.removeIf(e -> !WizardryUtilities.isValidTarget(caster, e));
if(tertiaryTargets.size() > TERTIARY_MAX_TARGETS) tertiaryTargets = tertiaryTargets.subList(0, TERTIARY_MAX_TARGETS);
// Tertiary chaining effect
List<EntityLivingBase> tertiaryTargets = WizardryUtilities.getEntitiesWithinRadius(seekerRange,
secondaryTarget.posX, secondaryTarget.posY + secondaryTarget.height / 2,
secondaryTarget.posZ, world);
tertiaryTargets.removeIf(e -> e instanceof EntityArmorStand);
for(int j = 0; j < Math.min(tertiaryTargets.size(), 2); j++){
EntityLivingBase tertiaryTarget = (EntityLivingBase)tertiaryTargets.get(j);
if(tertiaryTarget != target && !secondaryTargets.contains(tertiaryTarget)
&& WizardryUtilities.isValidTarget(caster, tertiaryTarget)){
if(!world.isRemote){
EntityArc arc = new EntityArc(world);
arc.setEndpointCoords(secondaryTarget.posX,
secondaryTarget.posY + secondaryTarget.height / 2, secondaryTarget.posZ,
tertiaryTarget.posX, tertiaryTarget.posY + tertiaryTarget.height / 2,
tertiaryTarget.posZ);
world.spawnEntity(arc);
}else{
for(int k = 0; k < 8; k++){
Wizardry.proxy.spawnParticle(Type.SPARK, world,
tertiaryTarget.posX + world.rand.nextFloat() - 0.5,
tertiaryTarget.getEntityBoundingBox().minY + tertiaryTarget.height / 2
+ world.rand.nextFloat() * 2 - 1,
tertiaryTarget.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3);
world.spawnParticle(EnumParticleTypes.SMOKE_LARGE,
tertiaryTarget.posX + world.rand.nextFloat() - 0.5,
tertiaryTarget.getEntityBoundingBox().minY + tertiaryTarget.height / 2
+ world.rand.nextFloat() * 2 - 1,
tertiaryTarget.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0);
}
}
tertiaryTarget.playSound(WizardrySounds.SPELL_SPARK, 1.0F,
world.rand.nextFloat() * 0.4F + 1.5F);
if(MagicDamage.isEntityImmune(DamageType.SHOCK, tertiaryTarget)){
if(!world.isRemote) caster.sendMessage(new TextComponentTranslation("spell.resist",
tertiaryTarget.getName(), this.getNameForTranslationFormatted()));
}else{
tertiaryTarget.attackEntityFrom(
MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK),
6.0f * modifiers.get(SpellModifiers.DAMAGE));
}
}
}
for(EntityLivingBase tertiaryTarget : tertiaryTargets){
electrocute(world, caster, secondaryTarget, tertiaryTarget,
TERTIARY_DAMAGE * modifiers.get(SpellModifiers.POTENCY));
}
}
caster.swingArm(hand);
return true;
}
return false;
}
@Override
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@Override
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
private void electrocute(World world, Entity caster, Entity origin, Entity target, float damage){
if(MagicDamage.isEntityImmune(DamageType.SHOCK, target)){
if(!world.isRemote) caster.sendMessage(new TextComponentTranslation("spell.resist", target.getName(),
this.getNameForTranslationFormatted()));
}else{
target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), damage);
}
if(!world.isRemote){
EntityArc arc = new EntityArc(world);
arc.setEndpointCoords(caster.posX, caster.getEntityBoundingBox().minY + caster.height / 2, caster.posZ,
target.posX, target.getEntityBoundingBox().minY + target.height / 2, target.posZ);
world.spawnEntity(arc);
}else{
ParticleBuilder.spawnShockParticles(world, target.posX, target.getEntityBoundingBox().minY + target.height/2, target.posZ);
}
target.playSound(WizardrySounds.SPELL_SPARK, 1, 1.5f + 0.4f * world.rand.nextFloat());
}
}
@@ -1,7 +1,6 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.WizardData;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
@@ -11,9 +10,10 @@ import electroblob.wizardry.packet.WizardryPacketHandler;
import electroblob.wizardry.registry.Spells;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WandHelper;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.WizardryPathFinder;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.SharedMonsterAttributes;
@@ -40,7 +40,7 @@ public class Clairvoyance extends Spell {
public static final int PARTICLE_MOVEMENT_INTERVAL = 45;
public Clairvoyance(){
super(Tier.APPRENTICE, 20, Element.SORCERY, "clairvoyance", SpellType.UTILITY, 100, EnumAction.BOW, false);
super("clairvoyance", Tier.APPRENTICE, Element.SORCERY, SpellType.UTILITY, 20, 100, EnumAction.BOW, false);
}
@Override
@@ -123,9 +123,11 @@ public class Clairvoyance extends Spell {
nextPoint = path.getCurrentPathLength() - path.getCurrentPathIndex() <= 2 ? path.getFinalPathPoint()
: path.getPathPointFromIndex(path.getCurrentPathIndex() + 2);
Wizardry.proxy.spawnParticle(Type.PATH, world, point.x + 0.5, point.y + 0.5, point.z + 0.5,
(nextPoint.x - point.x) / (float)PARTICLE_MOVEMENT_INTERVAL, (nextPoint.y - point.y) / (float)PARTICLE_MOVEMENT_INTERVAL,
(nextPoint.z - point.z) / (float)PARTICLE_MOVEMENT_INTERVAL, (int)(1800 * durationMultiplier), 0, 1, 0.3f);
ParticleBuilder.create(Type.PATH).pos(point.x + 0.5, point.y + 0.5, point.z + 0.5).vel(
(nextPoint.x - point.x) / (float)PARTICLE_MOVEMENT_INTERVAL,
(nextPoint.y - point.y) / (float)PARTICLE_MOVEMENT_INTERVAL,
(nextPoint.z - point.z) / (float)PARTICLE_MOVEMENT_INTERVAL)
.lifetime((int)(1800 * durationMultiplier)).colour(0, 1, 0.3f).spawn(world);
path.incrementPathIndex();
path.incrementPathIndex();
@@ -133,8 +135,8 @@ public class Clairvoyance extends Spell {
point = path.getFinalPathPoint();
Wizardry.proxy.spawnParticle(Type.PATH, world, point.x + 0.5, point.y + 0.5, point.z + 0.5, 0, 0, 0,
(int)(1800 * durationMultiplier), 1, 1, 1);
ParticleBuilder.create(Type.PATH).pos(point.x + 0.5, point.y + 0.5, point.z + 0.5)
.lifetime((int)(1800 * durationMultiplier)).colour(1, 1, 1).spawn(world);
}
@SubscribeEvent
@@ -7,133 +7,69 @@ import electroblob.wizardry.registry.WizardryBlocks;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.tileentity.TileEntityTimer;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World;
public class Cobwebs extends Spell {
public class Cobwebs extends SpellRay {
private static final int baseDuration = 400;
private static final int BASE_DURATION = 400;
public Cobwebs(){
super(Tier.ADVANCED, 30, Element.EARTH, "cobwebs", SpellType.ATTACK, 70, EnumAction.NONE, false);
super("cobwebs", Tier.ADVANCED, Element.EARTH, SpellType.ATTACK, 30, 70, false, 12, SoundEvents.BLOCK_LAVA_EXTINGUISH);
this.ignoreEntities(true);
}
@Override public boolean doesSpellRequirePacket(){ return false; }
@Override
public boolean doesSpellRequirePacket(){
protected boolean onEntityHit(World world, Entity target, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
boolean flag = false;
pos = pos.offset(side);
RayTraceResult rayTrace = WizardryUtilities.rayTrace(12 * modifiers.get(WizardryItems.range_upgrade), world,
caster, true);
if(world.isAirBlock(pos)){
if(!world.isRemote){
world.setBlockState(pos, WizardryBlocks.vanishing_cobweb.getDefaultState());
if(world.getTileEntity(pos) instanceof TileEntityTimer){
((TileEntityTimer)world.getTileEntity(pos))
.setLifetime((int)(BASE_DURATION * modifiers.get(WizardryItems.duration_upgrade)));
}
}
flag = true;
}
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){
for(EnumFacing facing : EnumFacing.values()){
boolean flag = false;
BlockPos pos1 = pos.offset(facing);
BlockPos pos = rayTrace.getBlockPos().offset(rayTrace.sideHit);
if(world.isAirBlock(pos)){
if(world.isAirBlock(pos1)){
if(!world.isRemote){
world.setBlockState(pos, WizardryBlocks.vanishing_cobweb.getDefaultState());
if(world.getTileEntity(pos) instanceof TileEntityTimer){
((TileEntityTimer)world.getTileEntity(pos))
.setLifetime((int)(baseDuration * modifiers.get(WizardryItems.duration_upgrade)));
world.setBlockState(pos1, WizardryBlocks.vanishing_cobweb.getDefaultState());
if(world.getTileEntity(pos1) instanceof TileEntityTimer){
((TileEntityTimer)world.getTileEntity(pos1))
.setLifetime((int)(BASE_DURATION * modifiers.get(WizardryItems.duration_upgrade)));
}
}
flag = true;
}
for(EnumFacing side : EnumFacing.values()){
BlockPos pos1 = pos.offset(side);
if(world.isAirBlock(pos1)){
if(!world.isRemote){
world.setBlockState(pos1, WizardryBlocks.vanishing_cobweb.getDefaultState());
if(world.getTileEntity(pos1) instanceof TileEntityTimer){
((TileEntityTimer)world.getTileEntity(pos1))
.setLifetime((int)(baseDuration * modifiers.get(WizardryItems.duration_upgrade)));
}
}
flag = true;
}
}
if(flag){
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.BLOCK_LAVA_EXTINGUISH, 1.0f, 1.0f);
return true;
}
}
return false;
return flag;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
int x = MathHelper.floor(target.posX);
int y = (int)target.getEntityBoundingBox().minY;
int z = MathHelper.floor(target.posZ);
boolean flag = false;
BlockPos pos = new BlockPos(x, y, z);
if(world.isAirBlock(pos)){
if(!world.isRemote){
world.setBlockState(pos, WizardryBlocks.vanishing_cobweb.getDefaultState());
if(world.getTileEntity(pos) instanceof TileEntityTimer){
((TileEntityTimer)world.getTileEntity(pos))
.setLifetime((int)(baseDuration * modifiers.get(WizardryItems.duration_upgrade)));
}
}
flag = true;
}
for(EnumFacing side : EnumFacing.values()){
BlockPos pos1 = pos.offset(side);
if(world.isAirBlock(pos1)){
if(!world.isRemote){
world.setBlockState(pos1, WizardryBlocks.vanishing_cobweb.getDefaultState());
if(world.getTileEntity(pos1) instanceof TileEntityTimer){
((TileEntityTimer)world.getTileEntity(pos1))
.setLifetime((int)(baseDuration * modifiers.get(WizardryItems.duration_upgrade)));
}
}
flag = true;
}
}
if(flag){
caster.swingArm(hand);
caster.playSound(SoundEvents.BLOCK_LAVA_EXTINGUISH, 1.0f, 1.0f);
return true;
}
}
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
}
}
@@ -1,6 +1,5 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
@@ -8,31 +7,25 @@ import electroblob.wizardry.item.IConjuredItem;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.EnumAction;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class ConjureArmour extends Spell {
public class ConjureArmour extends SpellConjuration {
public ConjureArmour(){
super(Tier.ADVANCED, 45, Element.HEALING, "conjure_armour", SpellType.DEFENCE, 50, EnumAction.BOW, false);
super("conjure_armour", Tier.ADVANCED, Element.HEALING, SpellType.DEFENCE, 45, 50, null, WizardrySounds.SPELL_CONJURATION);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
protected boolean conjureItem(EntityPlayer caster, SpellModifiers modifiers){
ItemStack armour;
boolean flag = false;
// A blank "ench" tag is set to trick the renderer into showing the enchantment effect on the actual armour model.
// Used this rather than getArmorInventoryList because I need to access the slot itself.
// Used this rather than getArmorInventoryList because I need to access the slot itself
for(EntityEquipmentSlot slot : WizardryUtilities.ARMOUR_SLOTS){
if(caster.getItemStackFromSlot(slot).isEmpty() &&
@@ -40,28 +33,13 @@ public class ConjureArmour extends Spell {
armour = new ItemStack(WizardryItems.SPECTRAL_ARMOUR_MAP.get(slot));
IConjuredItem.setDurationMultiplier(armour, modifiers.get(WizardryItems.duration_upgrade));
// Sets a blank "ench" tag to trick the renderer into showing the enchantment effect on the armour model
armour.getTagCompound().setTag("ench", new NBTTagList());
caster.setItemStackToSlot(slot, armour);
flag = true;
}
}
if(flag){
if(world.isRemote){
for(int i = 0; i < 10; i++){
double x1 = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F
+ world.rand.nextFloat());
double z1 = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0,
48 + world.rand.nextInt(12), 0.7f, 0.9f, 1.0f);
}
}
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1.0f, 1.0f);
}
return flag;
}
@@ -1,60 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.item.IConjuredItem;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class ConjureBow extends Spell {
public ConjureBow(){
super(Tier.APPRENTICE, 40, Element.SORCERY, "conjure_bow", SpellType.UTILITY, 50, EnumAction.BOW, false);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
ItemStack bow = new ItemStack(WizardryItems.spectral_bow);
IConjuredItem.setDurationMultiplier(bow, modifiers.get(WizardryItems.duration_upgrade));
if(!WizardryUtilities.doesPlayerHaveItem(caster, WizardryItems.spectral_bow)
&& conjureItemInInventory(caster, bow)){
for(int i = 0; i < 10; i++){
double x1 = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat());
double z1 = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
if(world.isRemote){
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0,
48 + world.rand.nextInt(12), 0.7f, 0.9f, 1.0f);
}
}
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1.0f, 1.0f);
return true;
}
return false;
}
// TODO: When spells get superclassed, this method needs to be in the conjuration superclass.
/** Adds the given item to the given player's inventory, placing it in the main hand if the main hand is empty. */
public static boolean conjureItemInInventory(EntityPlayer caster, ItemStack item){
if(caster.getHeldItemMainhand().isEmpty()){
caster.setHeldItem(EnumHand.MAIN_HAND, item);
return true;
}else{
return caster.inventory.addItemStackToInventory(item);
}
}
}
@@ -1,50 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.item.IConjuredItem;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class ConjurePickaxe extends Spell {
public ConjurePickaxe(){
super(Tier.APPRENTICE, 25, Element.SORCERY, "conjure_pickaxe", SpellType.UTILITY, 50, EnumAction.BOW, false);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
ItemStack pickaxe = new ItemStack(WizardryItems.spectral_pickaxe);
IConjuredItem.setDurationMultiplier(pickaxe, modifiers.get(WizardryItems.duration_upgrade));
if(!WizardryUtilities.doesPlayerHaveItem(caster, WizardryItems.spectral_pickaxe)
&& ConjureBow.conjureItemInInventory(caster, pickaxe)){
if(world.isRemote){
for(int i = 0; i < 10; i++){
double x1 = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F
+ world.rand.nextFloat());
double z1 = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0,
48 + world.rand.nextInt(12), 0.7f, 0.9f, 1.0f);
}
}
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1.0f, 1.0f);
return true;
}
return false;
}
}
@@ -1,49 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.item.IConjuredItem;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class ConjureSword extends Spell {
public ConjureSword(){
super(Tier.APPRENTICE, 25, Element.SORCERY, "conjure_sword", SpellType.UTILITY, 50, EnumAction.BOW, false);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
ItemStack sword = new ItemStack(WizardryItems.spectral_sword);
IConjuredItem.setDurationMultiplier(sword, modifiers.get(WizardryItems.duration_upgrade));
if(!WizardryUtilities.doesPlayerHaveItem(caster, WizardryItems.spectral_sword)
&& ConjureBow.conjureItemInInventory(caster, sword)){
for(int i = 0; i < 10; i++){
double x1 = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat());
double z1 = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
if(world.isRemote){
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0,
48 + world.rand.nextInt(12), 0.7f, 0.9f, 1.0f);
}
}
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1.0f, 1.0f);
return true;
}
return false;
}
}
@@ -1,77 +1,28 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class CureEffects extends Spell {
public class CureEffects extends SpellBuff {
public CureEffects(){
super(Tier.APPRENTICE, 25, Element.HEALING, "cure_effects", SpellType.DEFENCE, 40, EnumAction.BOW, false);
super("cure_effects", Tier.APPRENTICE, Element.HEALING, SpellType.DEFENCE, 25, 40, WizardrySounds.SPELL_HEAL, 0.8f, 0.8f, 1);
this.soundValues(0.7f, 1.2f, 0.4f);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
if(world.isRemote){
for(int i = 0; i < 10; i++){
double x1 = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat());
double z1 = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0,
48 + world.rand.nextInt(12), 0.6f, 0.6f, 1.0f);
}
}
protected boolean applyEffects(EntityLivingBase caster, SpellModifiers modifiers){
if(!caster.getActivePotionEffects().isEmpty()){
caster.clearActivePotions();
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F,
world.rand.nextFloat() * 0.4F + 1.0F);
return true;
}
// Fixes the sound not playing in first person.
if(world.isRemote) WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F,
world.rand.nextFloat() * 0.4F + 1.0F);
return false;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(!caster.getActivePotionEffects().isEmpty()){
caster.clearActivePotions();
if(world.isRemote){
for(int i = 0; i < 10; i++){
double x1 = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
double y1 = (double)((float)caster.posY + caster.getEyeHeight() - 0.5F + world.rand.nextFloat());
double z1 = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0,
48 + world.rand.nextInt(12), 0.6f, 0.6f, 1.0f);
}
}
caster.playSound(WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F);
return true;
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
}
}
@@ -1,71 +1,63 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.WizardData;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.util.IElementalDamage;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.event.entity.living.LivingHurtEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
@Mod.EventBusSubscriber
public class CurseOfSoulbinding extends Spell {
public class CurseOfSoulbinding extends SpellRay {
public CurseOfSoulbinding(){
super(Tier.ADVANCED, 35, Element.NECROMANCY, "curse_of_soulbinding", SpellType.ATTACK, 100, EnumAction.NONE,
false);
super("curse_of_soulbinding", Tier.ADVANCED, Element.NECROMANCY, SpellType.ATTACK, 35, 100, false, 10, SoundEvents.ENTITY_WITHER_SPAWN);
this.soundValues(1, 1.1f, 0.2f);
}
@Override public boolean canBeCastByNPCs() { return false; }
@Override
protected boolean onEntityHit(World world, Entity target, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
if(WizardryUtilities.isLiving(target) && caster instanceof EntityPlayer
&& WizardData.get((EntityPlayer)caster) != null){
// Return false if soulbinding failed (e.g. if the target is already soulbound)
if(!WizardData.get((EntityPlayer)caster).soulbind((EntityLivingBase)target)) return false;
}
return true;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
Vec3d look = caster.getLookVec();
RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster,
10 * modifiers.get(WizardryItems.range_upgrade));
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY
&& WizardryUtilities.isLiving(rayTrace.entityHit) && WizardData.get(caster) != null){
EntityLivingBase target = (EntityLivingBase)rayTrace.entityHit;
if(!WizardData.get(caster).soulbind(target)) return false;
}
if(world.isRemote){
for(int i = 1; i < (int)(25 * modifiers.get(WizardryItems.range_upgrade)); i += 2){
// I figured it out! when on client side, entityplayer.posY is at the eyes, not the feet!
double x1 = caster.posX + look.x * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
double y1 = WizardryUtilities.getPlayerEyesPos(caster) - 0.4f + look.y * i / 2
+ world.rand.nextFloat() / 5 - 0.1f;
double z1 = caster.posZ + look.z * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
// world.spawnParticle("mobSpell", x1, y1, z1, -1*look.xCoord, -1*look.yCoord, -1*look.zCoord);
Wizardry.proxy.spawnParticle(Type.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0,
0.4f, 0.0f, 0.0f);
Wizardry.proxy.spawnParticle(Type.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0,
0.1f, 0.0f, 0.0f);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d,
12 + world.rand.nextInt(8), 1.0f, 0.8f, 1.0f);
}
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_WITHER_SPAWN, 1.0F,
world.rand.nextFloat() * 0.2F + 1.0F);
@Override
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return true;
}
@Override
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).colour(0.4f, 0, 0).spawn(world);
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).colour(0.1f, 0, 0).spawn(world);
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).lifetime(12 + world.rand.nextInt(8)).colour(1, 0.8f, 1).spawn(world);
}
@SubscribeEvent
public static void onLivingHurtEvent(LivingHurtEvent event){
@@ -1,68 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.projectile.EntityDarknessOrb;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class DarknessOrb extends Spell {
public DarknessOrb(){
super(Tier.ADVANCED, 20, Element.NECROMANCY, "darkness_orb", SpellType.ATTACK, 20, EnumAction.NONE, false);
}
@Override
public boolean doesSpellRequirePacket(){
return false;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
if(!world.isRemote){
EntityDarknessOrb darknessorb = new EntityDarknessOrb(world, caster, modifiers.get(SpellModifiers.DAMAGE));
world.spawnEntity(darknessorb);
}
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_WITHER_SHOOT, 1.0F,
0.4F / (world.rand.nextFloat() * 0.4F + 0.8F));
caster.swingArm(hand);
return true;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
if(!world.isRemote){
EntityDarknessOrb darknessorb = new EntityDarknessOrb(world, caster,
modifiers.get(SpellModifiers.DAMAGE));
darknessorb.directTowards(target, 0.5f);
world.spawnEntity(darknessorb);
}
caster.playSound(SoundEvents.ENTITY_WITHER_SHOOT, 1.0F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F));
caster.swingArm(hand);
return true;
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
}
}
@@ -1,45 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.MobEffects;
import net.minecraft.item.EnumAction;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class Darkvision extends Spell {
public Darkvision(){
super(Tier.APPRENTICE, 20, Element.EARTH, "darkvision", SpellType.UTILITY, 40, EnumAction.BOW, false);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
caster.addPotionEffect(new PotionEffect(MobEffects.NIGHT_VISION,
(int)(900 * modifiers.get(WizardryItems.duration_upgrade)), 0, false, false));
if(world.isRemote){
for(int i = 0; i < 10; i++){
double x1 = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat());
double z1 = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0,
48 + world.rand.nextInt(12), 0.0f, 0.4f, 0.7f);
}
}
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F,
world.rand.nextFloat() * 0.4F + 1.0F);
return true;
}
}
@@ -1,67 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.projectile.EntityDart;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class Dart extends Spell {
public Dart(){
super(Tier.BASIC, 5, Element.EARTH, "dart", SpellType.ATTACK, 10, EnumAction.NONE, false);
}
@Override
public boolean doesSpellRequirePacket(){
return false;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
if(!world.isRemote){
EntityDart dart = new EntityDart(world, caster, 2 * modifiers.get(WizardryItems.range_upgrade),
modifiers.get(SpellModifiers.DAMAGE));
world.spawnEntity(dart);
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_ARROW_SHOOT, 0.5F,
0.4F / (world.rand.nextFloat() * 0.4F + 0.8F));
return true;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
if(!world.isRemote){
EntityDart dart = new EntityDart(world, caster, target, 2 * modifiers.get(WizardryItems.range_upgrade),
2, modifiers.get(SpellModifiers.DAMAGE));
world.spawnEntity(dart);
}
caster.swingArm(hand);
caster.playSound(SoundEvents.ENTITY_ARROW_SHOOT, 0.5F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F));
return true;
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
}
}
@@ -7,94 +7,39 @@ import electroblob.wizardry.entity.construct.EntityDecay;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World;
public class Decay extends Spell {
public class Decay extends SpellConstructRanged<EntityDecay> {
private static final int BASE_SPAWN_COUNT = 5;
public Decay(){
super(Tier.ADVANCED, 50, Element.NECROMANCY, "decay", SpellType.ATTACK, 200, EnumAction.NONE, false);
super("decay", Tier.ADVANCED, Element.NECROMANCY, SpellType.ATTACK, 50, 200, EntityDecay::new, 400, 12, SoundEvents.ENTITY_WITHER_SHOOT);
this.soundValues(1, 1.1f, 0.1f);
this.floor(true);
this.overlap(true);
}
@Override
public boolean doesSpellRequirePacket(){
return false;
}
protected boolean spawnConstruct(World world, double x, double y, double z, EntityLivingBase caster, SpellModifiers modifiers){
if(world.getBlockState(new BlockPos(x, y, z)).isNormalCube()) return false;
super.spawnConstruct(world, x, y, z, caster, modifiers);
int quantity = (int)(BASE_SPAWN_COUNT * modifiers.get(WizardryItems.blast_upgrade));
int horizontalRange = (int)(2 * modifiers.get(WizardryItems.blast_upgrade));
int verticalRange = (int)(6 * modifiers.get(WizardryItems.blast_upgrade));
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
RayTraceResult rayTrace = WizardryUtilities.rayTrace(12 * modifiers.get(WizardryItems.range_upgrade), world,
caster, false);
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){
BlockPos pos = rayTrace.getBlockPos();
if(world.getBlockState(pos.up()).isNormalCube()) return false;
if(!world.isRemote){
world.spawnEntity(new EntityDecay(world, pos.getX() + 0.5, pos.getY() + 1, pos.getZ() + 0.5, caster));
for(int i = 0; i < 5; i++){
BlockPos pos1 = WizardryUtilities.findNearbyFloorSpace(caster, 2, 6);
if(pos1 == null) break;
world.spawnEntity(
new EntityDecay(world, pos1.getX() + 0.5, pos1.getY(), pos1.getZ() + 0.5, caster));
}
}
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_WITHER_SHOOT, 1.0F,
world.rand.nextFloat() * 0.2F + 1.0F);
caster.swingArm(hand);
return true;
for(int i=0; i<quantity; i++){
BlockPos pos = WizardryUtilities.findNearbyFloorSpace(caster, horizontalRange, verticalRange);
if(pos == null) break;
super.spawnConstruct(world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, caster, modifiers);
}
return false;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
int x = MathHelper.floor(target.posX);
int y = (int)(int)target.getEntityBoundingBox().minY;
int z = MathHelper.floor(target.posZ);
if(world.getBlockState(new BlockPos(x, y, z)).isNormalCube()) return false;
if(!world.isRemote){
world.spawnEntity(new EntityDecay(world, x + 0.5, y + 1, z + 0.5, caster));
for(int i = 0; i < 5; i++){
BlockPos pos = WizardryUtilities.findNearbyFloorSpace(caster, 2, 6);
if(pos == null) break;
world.spawnEntity(new EntityDecay(world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, caster));
}
}
caster.playSound(SoundEvents.ENTITY_WITHER_SHOOT, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F);
caster.swingArm(hand);
return true;
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
}
@@ -17,71 +17,55 @@ import net.minecraft.world.World;
public class Decoy extends Spell {
public Decoy(){
super(Tier.ADVANCED, 40, Element.SORCERY, "decoy", SpellType.UTILITY, 200, EnumAction.BOW, false);
super("decoy", Tier.ADVANCED, Element.SORCERY, SpellType.UTILITY, 40, 200, EnumAction.BOW, false);
}
@Override public boolean canBeCastByNPCs(){ return true; }
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
// Determines whether the caster moves left and the decoy moves right, or vice versa.
// Uses the synchronised entity id to ensure it is consistent on client and server, but not always the same.
double splitSpeed = caster.getEntityId() % 2 == 0 ? 0.3 : -0.3;
if(!world.isRemote){
EntityDecoy decoy = new EntityDecoy(world, caster.posX, caster.posY, caster.posZ, caster, 600);
decoy.setLocationAndAngles(caster.posX, caster.posY, caster.posZ, caster.rotationYaw, caster.rotationPitch);
decoy.addVelocity(-caster.getLookVec().z * splitSpeed, 0, caster.getLookVec().x * splitSpeed);
// Ignores the show names setting, since this would allow a player to easily detect a decoy
decoy.setCustomNameTag(caster.getName());
world.spawnEntity(decoy);
// Tricks any mobs that are targeting the caster into targeting the decoy instead.
for(EntityLiving creature : WizardryUtilities.getEntitiesWithinRadius(16, caster.posX, caster.posY,
caster.posZ, world, EntityLiving.class)){
// More likely to trick mobs the higher the damage multiplier. Starts off at 50%.
if(world.rand.nextInt((int)(6 * modifiers.get(SpellModifiers.DAMAGE))) < 3){
if(creature.getAttackTarget() == caster) creature.setAttackTarget(decoy);
}
}
}
caster.addVelocity(caster.getLookVec().z * splitSpeed, 0, -caster.getLookVec().x * splitSpeed);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1.0F,
0.4F / (world.rand.nextFloat() * 0.4F + 0.8F));
spawnDecoy(world, caster, modifiers, splitSpeed);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1.0F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F));
return true;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){
// Determines whether the caster moves left and the decoy moves right, or vice versa.
double splitSpeed = world.rand.nextBoolean() ? 0.3 : -0.3;
if(!world.isRemote){
EntityDecoy decoy = new EntityDecoy(world, caster.posX, caster.posY, caster.posZ, caster, 600);
decoy.setLocationAndAngles(caster.posX, caster.posY, caster.posZ, caster.rotationYaw, caster.rotationPitch);
decoy.addVelocity(-caster.getLookVec().z * splitSpeed, 0, caster.getLookVec().x * splitSpeed);
world.spawnEntity(decoy);
// Tricks any mobs that are targeting the caster into targeting the decoy instead.
for(EntityLiving creature : WizardryUtilities.getEntitiesWithinRadius(16, caster.posX, caster.posY,
caster.posZ, world, EntityLiving.class)){
// More likely to trick mobs the higher the damage multiplier. Starts off at 50%.
if(world.rand.nextInt((int)(6 * modifiers.get(SpellModifiers.DAMAGE))) < 3){
if(creature.getAttackTarget() == caster) creature.setAttackTarget(decoy);
}
}
}
caster.addVelocity(caster.getLookVec().z * splitSpeed, 0, -caster.getLookVec().x * splitSpeed);
spawnDecoy(world, caster, modifiers, splitSpeed);
caster.playSound(WizardrySounds.SPELL_CONJURATION, 1.0F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F));
return true;
}
private void spawnDecoy(World world, EntityLivingBase caster, SpellModifiers modifiers, double splitSpeed){
@Override
public boolean canBeCastByNPCs(){
return true;
if(!world.isRemote){
EntityDecoy decoy = new EntityDecoy(world);
decoy.setCaster(caster);
decoy.setLifetime(600);
decoy.setLocationAndAngles(caster.posX, caster.posY, caster.posZ, caster.rotationYaw, caster.rotationPitch);
decoy.addVelocity(-caster.getLookVec().z * splitSpeed, 0, caster.getLookVec().x * splitSpeed);
// Ignores the show names setting, since this would allow a player to easily detect a decoy
// Instead, a decoy player has its caster's name tag shown permanently and non-player decoys have nothing
if(caster instanceof EntityPlayer) decoy.setCustomNameTag(caster.getName());
world.spawnEntity(decoy);
// Tricks any mobs that are targeting the caster into targeting the decoy instead.
for(EntityLiving creature : WizardryUtilities.getEntitiesWithinRadius(16, caster.posX, caster.posY,
caster.posZ, world, EntityLiving.class)){
// More likely to trick mobs the higher the damage multiplier. Starts off at 50%.
if(world.rand.nextInt((int)(6 * modifiers.get(SpellModifiers.POTENCY))) < 3){
if(creature.getAttackTarget() == caster) creature.setAttackTarget(decoy);
}
}
}
caster.addVelocity(caster.getLookVec().z * splitSpeed, 0, -caster.getLookVec().x * splitSpeed);
}
}
@@ -10,115 +10,59 @@ import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class Detonate extends Spell {
public class Detonate extends SpellRay {
private static final double BASE_RADIUS = 3;
public Detonate(){
super(Tier.ADVANCED, 45, Element.FIRE, "detonate", SpellType.ATTACK, 50, EnumAction.NONE, false);
super("detonate", Tier.ADVANCED, Element.FIRE, SpellType.ATTACK, 45, 50, false, 16, SoundEvents.ENTITY_GENERIC_EXPLODE);
this.soundValues(4, 0.7f, 0.14f);
this.ignoreEntities(true);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
RayTraceResult rayTrace = WizardryUtilities.rayTrace(16 * modifiers.get(WizardryItems.range_upgrade), world,
caster, false);
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){
if(!world.isRemote){
List<EntityLivingBase> targets = WizardryUtilities.getEntitiesWithinRadius(
3.0d * modifiers.get(WizardryItems.blast_upgrade), (rayTrace.hitVec.x + 0.5),
(rayTrace.hitVec.y + 0.5), (rayTrace.hitVec.z + 0.5), world);
for(int i = 0; i < targets.size(); i++){
targets.get(i).attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.BLAST),
// Damage decreases with distance but cannot be less than 0, naturally.
Math.max(12.0f - (float)((EntityLivingBase)targets.get(i)).getDistance(
(rayTrace.hitVec.x + 0.5), (rayTrace.hitVec.y + 0.5),
(rayTrace.hitVec.z + 0.5)) * 4, 0) * modifiers.get(SpellModifiers.DAMAGE));
}
}
if(world.isRemote){
double dx = (rayTrace.hitVec.x + 0.5) - caster.posX;
double dy = (rayTrace.hitVec.y + 0.5) - WizardryUtilities.getPlayerEyesPos(caster);
double dz = (rayTrace.hitVec.z + 0.5) - caster.posZ;
world.spawnParticle(EnumParticleTypes.EXPLOSION_HUGE, (rayTrace.hitVec.x + 0.5),
(rayTrace.hitVec.y + 0.5), (rayTrace.hitVec.z + 0.5), 0, 0, 0);
for(int i = 1; i < 5; i++){
world.spawnParticle(EnumParticleTypes.FLAME,
caster.posX + (i * (dx / 5)) + world.rand.nextFloat() / 5,
WizardryUtilities.getPlayerEyesPos(caster) + (i * (dy / 5)) + world.rand.nextFloat() / 5,
caster.posZ + (i * (dz / 5)) + world.rand.nextFloat() / 5, 0, 0, 0);
world.spawnParticle(EnumParticleTypes.FLAME,
caster.posX + (i * (dx / 5)) + world.rand.nextFloat() / 5,
WizardryUtilities.getPlayerEyesPos(caster) + (i * (dy / 5)) + world.rand.nextFloat() / 5,
caster.posZ + (i * (dz / 5)) + world.rand.nextFloat() / 5, 0, 0, 0);
}
}
world.playSound(caster, (rayTrace.hitVec.x + 0.5), (rayTrace.hitVec.y + 0.5),
(rayTrace.hitVec.z + 0.5), SoundEvents.ENTITY_GENERIC_EXPLODE, SoundCategory.BLOCKS, 4.0F,
(1.0F + (world.rand.nextFloat() - world.rand.nextFloat()) * 0.2F) * 0.7F);
caster.swingArm(hand);
return true;
}
protected boolean onEntityHit(World world, Entity target, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
if(!world.isRemote){
List<EntityLivingBase> targets = WizardryUtilities.getEntitiesWithinRadius(3.0d, target.posX,
target.posY, target.posZ, world);
for(int i = 0; i < targets.size(); i++){
targets.get(i).attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.BLAST),
// Damage decreases with distance but cannot be less than 0, naturally.
Math.max(12.0f - (float)((EntityLivingBase)targets.get(i)).getDistance(target.posX,
target.posY, target.posZ) * 4, 0) * modifiers.get(SpellModifiers.DAMAGE));
}
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
if(!world.isRemote){
List<EntityLivingBase> targets = WizardryUtilities.getEntitiesWithinRadius(
BASE_RADIUS * modifiers.get(WizardryItems.blast_upgrade), pos.getX(), pos.getY(), pos.getZ(), world);
for(EntityLivingBase target : targets){
target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.BLAST),
// Damage decreases with distance but cannot be less than 0, naturally.
Math.max(12.0f - (float)target.getDistance(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5)
* 4, 0) * modifiers.get(SpellModifiers.POTENCY));
}
if(world.isRemote){
double dx = target.posX - caster.posX;
double dy = target.posY - (caster.posY + caster.getEyeHeight());
double dz = target.posZ - caster.posZ;
world.spawnParticle(EnumParticleTypes.EXPLOSION_HUGE, target.posX, target.posY, target.posZ, 0, 0, 0);
for(int i = 1; i < 5; i++){
world.spawnParticle(EnumParticleTypes.FLAME,
caster.posX + (i * (dx / 5)) + world.rand.nextFloat() / 5,
caster.posY + caster.getEyeHeight() + (i * (dy / 5)) + world.rand.nextFloat() / 5,
caster.posZ + (i * (dz / 5)) + world.rand.nextFloat() / 5, 0, 0, 0);
world.spawnParticle(EnumParticleTypes.FLAME,
caster.posX + (i * (dx / 5)) + world.rand.nextFloat() / 5,
caster.posY + caster.getEyeHeight() + (i * (dy / 5)) + world.rand.nextFloat() / 5,
caster.posZ + (i * (dz / 5)) + world.rand.nextFloat() / 5, 0, 0, 0);
}
}
// Player is null here because the sound was not caused by a player.
world.playSound(null, target.posX, target.posY, target.posZ, SoundEvents.ENTITY_GENERIC_EXPLODE,
SoundCategory.BLOCKS, 4.0F,
(1.0F + (world.rand.nextFloat() - world.rand.nextFloat()) * 0.2F) * 0.7F);
caster.swingArm(hand);
return true;
}else{
world.spawnParticle(EnumParticleTypes.EXPLOSION_HUGE, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, 0, 0, 0);
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
}
@Override
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@Override
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
world.spawnParticle(EnumParticleTypes.FLAME, x, y, z, 0, 0, 0);
}
}
@@ -1,53 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.MobEffects;
import net.minecraft.item.EnumAction;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class Diamondflesh extends Spell {
public Diamondflesh(){
super(Tier.MASTER, 100, Element.HEALING, "diamondflesh", SpellType.DEFENCE, 300, EnumAction.BOW, false);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
caster.addPotionEffect(new PotionEffect(MobEffects.RESISTANCE,
(int)(600 * modifiers.get(WizardryItems.duration_upgrade)), 4, false, false));
if(world.isRemote){
for(int i = 0; i < 10; i++){
double x1 = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat());
double z1 = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0,
48 + world.rand.nextInt(12), 0.0f, 0.5f, 1.0f);
x1 = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat());
z1 = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0,
48 + world.rand.nextInt(12), 0.6f, 0.7f, 0.9f);
}
}
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F,
world.rand.nextFloat() * 0.4F + 1.0F);
return true;
}
}
@@ -1,4 +1,4 @@
package electroblob.wizardry.spell;
package electroblob.wizardry.spell;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
@@ -10,54 +10,54 @@ import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.world.World;
public class Earthquake extends Spell {
public class Earthquake extends SpellConstruct<EntityEarthquake> {
public Earthquake(){
super(Tier.MASTER, 75, Element.EARTH, "earthquake", SpellType.ATTACK, 250, EnumAction.NONE, false);
super("earthquake", Tier.MASTER, Element.EARTH, SpellType.ATTACK, 75, 250, EnumAction.NONE, EntityEarthquake::new, -1, WizardrySounds.SPELL_EARTHQUAKE);
this.soundValues(2, 1, 0);
this.overlap(true);
this.floor(true);
}
// This one spawns particles
@Override public boolean doesSpellRequirePacket(){ return true; }
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
protected void addConstructExtras(EntityEarthquake construct, EntityLivingBase caster, SpellModifiers modifiers){
construct.lifetime = (int)(20 * modifiers.get(WizardryItems.blast_upgrade));
}
@Override
protected boolean spawnConstruct(World world, double x, double y, double z, EntityLivingBase caster, SpellModifiers modifiers){
// TODO: Couldn't this be moved to EntityEarthquake?
if(world.isRemote){
if(caster.onGround){
world.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, caster.posX,
caster.getEntityBoundingBox().minY + 0.1, caster.posZ, 0, 0, 0);
if(!world.isRemote){
world.spawnEntity(new EntityEarthquake(world, caster.posX, caster.getEntityBoundingBox().minY,
caster.posZ, caster, (int)(20 * modifiers.get(WizardryItems.blast_upgrade)),
modifiers.get(SpellModifiers.DAMAGE)));
}else{
double particleX, particleZ;
world.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, caster.posX,
caster.getEntityBoundingBox().minY + 0.1, caster.posZ, 0, 0, 0);
for(int i=0; i<40; i++){
double particleX, particleZ;
particleX = caster.posX - 1.0d + 2 * world.rand.nextDouble();
particleZ = caster.posZ - 1.0d + 2 * world.rand.nextDouble();
for(int i = 0; i < 40; i++){
particleX = caster.posX - 1.0d + 2 * world.rand.nextDouble();
particleZ = caster.posZ - 1.0d + 2 * world.rand.nextDouble();
IBlockState block = WizardryUtilities.getBlockEntityIsStandingOn(caster);
if(block != null){
world.spawnParticle(EnumParticleTypes.BLOCK_DUST, particleX, caster.getEntityBoundingBox().minY,
particleZ, particleX - caster.posX, 0, particleZ - caster.posZ,
Block.getStateId(block));
}
IBlockState block = WizardryUtilities.getBlockEntityIsStandingOn(caster);
if(block != null){
world.spawnParticle(EnumParticleTypes.BLOCK_DUST, particleX, caster.getEntityBoundingBox().minY,
particleZ, particleX - caster.posX, 0, particleZ - caster.posZ,
Block.getStateId(block));
}
}
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_EARTHQUAKE, 2, 1);
caster.swingArm(hand);
return true;
}
return false;
return super.spawnConstruct(world, x, y, z, caster, modifiers);
}
}
@@ -1,6 +1,5 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
@@ -8,112 +7,63 @@ import electroblob.wizardry.entity.construct.EntityBubble;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class Entrapment extends Spell {
public class Entrapment extends SpellRay {
public Entrapment(){
super(Tier.ADVANCED, 35, Element.NECROMANCY, "entrapment", SpellType.ATTACK, 75, EnumAction.NONE, false);
super("entrapment", Tier.ADVANCED, Element.NECROMANCY, SpellType.ATTACK, 35, 75, false, 10, SoundEvents.ENTITY_WITHER_SHOOT);
this.soundValues(1, 0.85f, 0.3f);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
Vec3d look = caster.getLookVec();
RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster,
10 * modifiers.get(WizardryItems.range_upgrade));
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY && WizardryUtilities.isLiving(rayTrace.entityHit)){
EntityLivingBase entity = (EntityLivingBase)rayTrace.entityHit;
protected boolean onEntityHit(World world, Entity target, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
if(WizardryUtilities.isLiving(target)){
if(!world.isRemote){
entity.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.MAGIC),
1.0f * modifiers.get(SpellModifiers.DAMAGE));
EntityBubble entitybubble = new EntityBubble(world, entity.posX, entity.posY, entity.posZ, caster,
(int)(200 * modifiers.get(WizardryItems.duration_upgrade)), true,
modifiers.get(SpellModifiers.DAMAGE));
world.spawnEntity(entitybubble);
entity.startRiding(entitybubble);
// Deals a small amount damage so the target counts as being hit by the caster
target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.MAGIC), 1);
EntityBubble bubble = new EntityBubble(world);
bubble.setPosition(target.posX, target.posY, target.posZ);
bubble.setCaster(caster);
bubble.lifetime = ((int)(200 * modifiers.get(WizardryItems.duration_upgrade)));
bubble.isDarkOrb = true;
bubble.damageMultiplier = modifiers.get(SpellModifiers.POTENCY);
world.spawnEntity(bubble);
target.startRiding(bubble);
}
}
if(world.isRemote){
for(int i = 1; i < (int)(25 * modifiers.get(WizardryItems.range_upgrade)); i += 2){
double x1 = caster.posX + look.x * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
double y1 = WizardryUtilities.getPlayerEyesPos(caster) - 0.4f + look.y * i / 2
+ world.rand.nextFloat() / 5 - 0.1f;
double z1 = caster.posZ + look.z * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
world.spawnParticle(EnumParticleTypes.PORTAL, x1, y1 - 0.5, z1, 0.0d, 0.0d, 0.0d);
Wizardry.proxy.spawnParticle(Type.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0,
0.1f, 0.0f, 0.0f);
}
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_WITHER_SHOOT, 1.0F,
world.rand.nextFloat() * 0.3F + 0.7F);
return true;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
if(!world.isRemote){
target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.MAGIC),
1.0f * modifiers.get(SpellModifiers.DAMAGE));
// Deprecated in favour of entity riding method
// entity.addPotionEffect(new PotionEffect(Wizardry.bubblePotion, 200, 0));
EntityBubble entitybubble = new EntityBubble(world, target.posX, target.posY, target.posZ, caster,
(int)(200 * modifiers.get(WizardryItems.duration_upgrade)), true,
modifiers.get(SpellModifiers.DAMAGE));
world.spawnEntity(entitybubble);
target.startRiding(entitybubble);
}
if(world.isRemote){
double dx = (target.posX - caster.posX) / caster.getDistance(target);
double dy = (target.posY - caster.posY) / caster.getDistance(target);
double dz = (target.posZ - caster.posZ) / caster.getDistance(target);
for(int i = 1; i < 25; i += 2){
double x1 = caster.posX + dx * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
double y1 = caster.posY + caster.getEyeHeight() - 0.4f + dy * i / 2 + world.rand.nextFloat() / 5
- 0.1f;
double z1 = caster.posZ + dz * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
world.spawnParticle(EnumParticleTypes.PORTAL, x1, y1 - 0.5, z1, 0.0d, 0.0d, 0.0d);
Wizardry.proxy.spawnParticle(Type.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d,
0, 0.1f, 0.0f, 0.0f);
}
}
caster.swingArm(hand);
caster.playSound(SoundEvents.ENTITY_WITHER_SHOOT, 1.0F, world.rand.nextFloat() * 0.3F + 0.7F);
return true;
}
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@Override
public boolean canBeCastByNPCs(){
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return true;
}
@Override
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
world.spawnParticle(EnumParticleTypes.PORTAL, x, y - 0.5, z, 0, 0, 0);
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).colour(0.1f, 0, 0).spawn(world);
}
}
@@ -1,78 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.MobEffects;
import net.minecraft.item.EnumAction;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class FireResistance extends Spell {
public FireResistance(){
super(Tier.ADVANCED, 20, Element.FIRE, "fire_resistance", SpellType.DEFENCE, 80, EnumAction.BOW, false);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
caster.addPotionEffect(new PotionEffect(MobEffects.FIRE_RESISTANCE,
(int)(600 * modifiers.get(WizardryItems.duration_upgrade)), 0, false, false));
if(world.isRemote){
for(int i = 0; i < 10; i++){
double x1 = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat());
double z1 = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0,
48 + world.rand.nextInt(12), 1.0f, 0.5f, 0.0f);
}
}
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F,
world.rand.nextFloat() * 0.4F + 1.0F);
return true;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
// Like witches, wizards who have this spell will only cast it if they are on fire.
if(caster.isBurning() && !caster.isPotionActive(MobEffects.FIRE_RESISTANCE)){
caster.addPotionEffect(new PotionEffect(MobEffects.FIRE_RESISTANCE,
(int)(600 * modifiers.get(WizardryItems.duration_upgrade)), 0, false, false));
if(world.isRemote){
for(int i = 0; i < 10; i++){
double x1 = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
double y1 = (double)((float)caster.posY + caster.getEyeHeight() - 0.5F + world.rand.nextFloat());
double z1 = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0,
48 + world.rand.nextInt(12), 1.0f, 0.5f, 0.0f);
}
}
caster.playSound(WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F);
return true;
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
}
}
@@ -1,51 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.construct.EntityFireSigil;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World;
public class FireSigil extends Spell {
public FireSigil(){
super(Tier.APPRENTICE, 10, Element.FIRE, "fire_sigil", SpellType.ATTACK, 20, EnumAction.NONE, false);
}
@Override
public boolean doesSpellRequirePacket(){
return false;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
RayTraceResult rayTrace = WizardryUtilities.rayTrace(10 * modifiers.get(WizardryItems.range_upgrade), world,
caster, false);
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK && rayTrace.sideHit == EnumFacing.UP){
if(!world.isRemote){
double x = rayTrace.hitVec.x;
double y = rayTrace.hitVec.y;
double z = rayTrace.hitVec.z;
EntityFireSigil firesigil = new EntityFireSigil(world, x, y, z, caster,
modifiers.get(SpellModifiers.DAMAGE));
world.spawnEntity(firesigil);
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ITEM_FLINTANDSTEEL_USE, 1.0F, 1.0F);
return true;
}
return false;
}
}
@@ -18,7 +18,7 @@ import net.minecraft.world.World;
public class Fireball extends Spell {
public Fireball(){
super(Tier.APPRENTICE, 10, Element.FIRE, "fireball", SpellType.ATTACK, 15, EnumAction.NONE, false);
super("fireball", Tier.APPRENTICE, Element.FIRE, SpellType.ATTACK, 10, 15, EnumAction.NONE, false);
// Does 2.5 hearts of damage and 5 seconds of fire, for reference.
}
@@ -1,69 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.projectile.EntityFirebolt;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class Firebolt extends Spell {
public Firebolt(){
super(Tier.APPRENTICE, 10, Element.FIRE, "firebolt", SpellType.ATTACK, 10, EnumAction.NONE, false);
}
@Override
public boolean doesSpellRequirePacket(){
return false;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
if(!world.isRemote){
EntityFirebolt firebolt = new EntityFirebolt(world, caster, modifiers.get(SpellModifiers.DAMAGE));
firebolt.motionX *= 2.5;
firebolt.motionY *= 2.5;
firebolt.motionZ *= 2.5;
world.spawnEntity(firebolt);
}
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_BLAZE_SHOOT, 1, 1);
caster.swingArm(hand);
return true;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
if(!world.isRemote){
EntityFirebolt firebolt = new EntityFirebolt(world, caster, modifiers.get(SpellModifiers.DAMAGE));
firebolt.directTowards(target, 2.5f);
world.spawnEntity(firebolt);
}
caster.playSound(SoundEvents.ENTITY_BLAZE_SHOOT, 1, 1);
caster.swingArm(hand);
return true;
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
}
}
@@ -1,70 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.projectile.EntityFirebomb;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class Firebomb extends Spell {
public Firebomb(){
super(Tier.APPRENTICE, 15, Element.FIRE, "firebomb", SpellType.ATTACK, 25, EnumAction.NONE, false);
}
@Override
public boolean doesSpellRequirePacket(){
return false;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
if(!world.isRemote){
EntityFirebomb firebomb = new EntityFirebomb(world, caster, modifiers.get(SpellModifiers.DAMAGE),
modifiers.get(WizardryItems.blast_upgrade));
world.spawnEntity(firebomb);
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_SNOWBALL_THROW, 0.5F,
0.4F / (world.rand.nextFloat() * 0.4F + 0.8F));
return true;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
if(!world.isRemote){
EntityFirebomb firebomb = new EntityFirebomb(world, caster, modifiers.get(SpellModifiers.DAMAGE),
modifiers.get(WizardryItems.blast_upgrade));
firebomb.directTowards(target, 1.5f);
world.spawnEntity(firebomb);
}
caster.swingArm(hand);
caster.playSound(SoundEvents.ENTITY_SNOWBALL_THROW, 0.5F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F));
return true;
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
}
}
@@ -1,70 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardryPotions;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.EnumAction;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class Fireskin extends Spell {
public Fireskin(){
super(Tier.ADVANCED, 40, Element.FIRE, "fireskin", SpellType.DEFENCE, 250, EnumAction.BOW, false);
}
@Override
public boolean doesSpellRequirePacket(){
return false;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
// Cannot be cast when it has already been cast
if(!caster.isPotionActive(WizardryPotions.fireskin)){
if(!world.isRemote){
caster.addPotionEffect(new PotionEffect(WizardryPotions.fireskin,
(int)(600 * modifiers.get(WizardryItems.duration_upgrade)), 0));
}
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_BLAZE_SHOOT, 1, 1);
return true;
}
return false;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
// Cannot be cast when it has already been cast
if(!caster.isPotionActive(WizardryPotions.fireskin)){
if(!world.isRemote){
caster.addPotionEffect(new PotionEffect(WizardryPotions.fireskin,
(int)(600 * modifiers.get(WizardryItems.duration_upgrade)), 0));
}
caster.playSound(SoundEvents.ENTITY_BLAZE_SHOOT, 1, 1);
return true;
}
return false;
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
}
}
@@ -1,6 +1,5 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
@@ -8,83 +7,103 @@ import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.World;
public class Firestorm extends Spell {
public class Firestorm extends SpellRay {
private static final float BASE_DAMAGE = 6;
/** The base duration for which entities are set on fire by this spell. */
private static final int BASE_DURATION = 10;
public Firestorm(){
super(Tier.MASTER, 15, Element.FIRE, "firestorm", SpellType.ATTACK, 0, EnumAction.NONE, true);
super("firestorm", Tier.MASTER, Element.FIRE, SpellType.ATTACK, 15, 0, true, 10, null);
this.particleVelocity(1);
this.particleDither(0.3);
this.particleSpacing(0.25);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
// Temporary solution until I implement a better continuous sound system
boolean flag = super.cast(world, caster, hand, ticksInUse, modifiers);
if(flag){
if(ticksInUse % 16 == 0){
if(ticksInUse == 0) WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_BLAZE_SHOOT, 1, 1);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LOOP_FIRE, 0.5f, 1.0f);
}
}
return flag;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){
boolean flag = super.cast(world, caster, hand, ticksInUse, target, modifiers);
if(flag){
if(ticksInUse % 16 == 0){
if(ticksInUse == 0) caster.playSound(SoundEvents.ENTITY_BLAZE_SHOOT, 1, 1);
caster.playSound(WizardrySounds.SPELL_LOOP_FIRE, 0.5f, 1.0f);
}
}
return flag;
}
Vec3d look = caster.getLookVec();
@Override
protected boolean onEntityHit(World world, Entity target, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
// Fire can damage armour stands
if(target instanceof EntityLivingBase){
RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster,
10 * modifiers.get(WizardryItems.range_upgrade));
// Fire can damage armour stands.
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY && rayTrace.entityHit instanceof EntityLivingBase){
EntityLivingBase target = (EntityLivingBase)rayTrace.entityHit;
if(!MagicDamage.isEntityImmune(DamageType.FIRE, target)){
target.setFire(10);
WizardryUtilities.attackEntityWithoutKnockback(target,
MagicDamage.causeDirectMagicDamage(caster, DamageType.FIRE),
6.0f * modifiers.get(SpellModifiers.DAMAGE));
}else{
if(MagicDamage.isEntityImmune(DamageType.FIRE, target)){
if(!world.isRemote && ticksInUse == 1) caster.sendMessage(new TextComponentTranslation("spell.resist",
target.getName(), this.getNameForTranslationFormatted()));
}else{
target.setFire((int)(BASE_DURATION * modifiers.get(WizardryItems.duration_upgrade)));
WizardryUtilities.attackEntityWithoutKnockback(target,
MagicDamage.causeDirectMagicDamage(caster, DamageType.FIRE),
BASE_DAMAGE * modifiers.get(SpellModifiers.POTENCY));
}
}else if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){
BlockPos pos = rayTrace.getBlockPos().offset(rayTrace.sideHit);
if(world.isAirBlock(pos)){
if(!world.isRemote){
world.setBlockState(pos, Blocks.FIRE.getDefaultState());
}
}
return true;
}
return false;
}
if(world.isRemote){
for(int i = 0; i < 40; i++){
// I figured it out! when on client side, entityplayer.posY is at the eyes, not the feet!
double x1 = caster.posX + look.x * i / 2 + world.rand.nextFloat() * 0.6f - 0.3f;
double y1 = WizardryUtilities.getPlayerEyesPos(caster) - 0.4f + look.y * i / 2
+ world.rand.nextFloat() * 0.4f - 0.2f;
double z1 = caster.posZ + look.z * i / 2 + world.rand.nextFloat() * 0.6f - 0.3f;
Wizardry.proxy.spawnParticle(Type.MAGIC_FIRE, world, x1, y1, z1,
look.x * modifiers.get(WizardryItems.range_upgrade),
look.y * modifiers.get(WizardryItems.range_upgrade),
look.z * modifiers.get(WizardryItems.range_upgrade), 0, 3 + world.rand.nextFloat(), 0, 0);
Wizardry.proxy.spawnParticle(Type.MAGIC_FIRE, world, x1, y1, z1,
look.x * modifiers.get(WizardryItems.range_upgrade),
look.y * modifiers.get(WizardryItems.range_upgrade),
look.z * modifiers.get(WizardryItems.range_upgrade), 0, 3 + world.rand.nextFloat(), 0, 0);
}
}
if(ticksInUse % 16 == 0){
if(ticksInUse == 0) WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_BLAZE_SHOOT, 1, 1);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LOOP_FIRE, 0.5F, 1.0f);
@Override
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
pos = pos.offset(side);
if(world.isAirBlock(pos)){
if(!world.isRemote) world.setBlockState(pos, Blocks.FIRE.getDefaultState());
return true;
}
return false;
}
@Override
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return true;
}
@Override
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
ParticleBuilder.create(Type.MAGIC_FIRE).pos(x, y, z).vel(vx, vy, vz).scale(3 + world.rand.nextFloat()).spawn(world);
ParticleBuilder.create(Type.MAGIC_FIRE).pos(x, y, z).vel(vx, vy, vz).scale(3 + world.rand.nextFloat()).spawn(world);
}
}
@@ -1,6 +1,5 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
@@ -8,106 +7,71 @@ import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.World;
public class FlameRay extends Spell {
public class FlameRay extends SpellRay {
private static final float BASE_DAMAGE = 3;
/** The base duration for which entities are set on fire by this spell. */
private static final int BASE_DURATION = 10;
public FlameRay(){
super(Tier.APPRENTICE, 5, Element.FIRE, "flame_ray", SpellType.ATTACK, 0, EnumAction.NONE, true);
super("flame_ray", Tier.APPRENTICE, Element.FIRE, SpellType.ATTACK, 5, 0, true, 10, null);
this.particleVelocity(1);
this.particleSpacing(0.5);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
Vec3d look = caster.getLookVec();
RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster,
10 * modifiers.get(WizardryItems.range_upgrade));
// Fire can damage armour stands
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY && rayTrace.entityHit instanceof EntityLivingBase){
EntityLivingBase target = (EntityLivingBase)rayTrace.entityHit;
if(!MagicDamage.isEntityImmune(DamageType.FIRE, target)){
target.setFire(10);
WizardryUtilities.attackEntityWithoutKnockback(target,
MagicDamage.causeDirectMagicDamage(caster, DamageType.FIRE),
3.0f * modifiers.get(SpellModifiers.DAMAGE));
}else{
if(!world.isRemote && ticksInUse == 1) caster.sendMessage(new TextComponentTranslation("spell.resist",
target.getName(), this.getNameForTranslationFormatted()));
// TODO: Temporary solution until I implement a better continuous sound system
boolean flag = super.cast(world, caster, hand, ticksInUse, modifiers);
if(flag){
if(ticksInUse % 16 == 0){
if(ticksInUse == 0) WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_BLAZE_SHOOT, 1, 1);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LOOP_FIRE, 0.5f, 1.0f);
}
}
if(world.isRemote){
for(int i = 0; i < 20; i++){
// I figured it out! when on client side, entityplayer.posY is at the eyes, not the feet!
double x1 = caster.posX + look.x * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
double y1 = WizardryUtilities.getPlayerEyesPos(caster) - 0.4f + look.y * i / 2
+ world.rand.nextFloat() / 5 - 0.1f;
double z1 = caster.posZ + look.z * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
Wizardry.proxy.spawnParticle(Type.MAGIC_FIRE, world, x1, y1, z1,
look.x * modifiers.get(WizardryItems.range_upgrade),
look.y * modifiers.get(WizardryItems.range_upgrade),
look.z * modifiers.get(WizardryItems.range_upgrade), 0);
Wizardry.proxy.spawnParticle(Type.MAGIC_FIRE, world, x1, y1, z1,
look.x * modifiers.get(WizardryItems.range_upgrade),
look.y * modifiers.get(WizardryItems.range_upgrade),
look.z * modifiers.get(WizardryItems.range_upgrade), 0);
}
}
if(ticksInUse % 16 == 0){
if(ticksInUse == 0) WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_BLAZE_SHOOT, 1, 1);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LOOP_FIRE, 0.5F, 1.0f);
}
return true;
return flag;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
Vec3d vec = new Vec3d(target.posX - caster.posX, target.posY - caster.posY, target.posZ - caster.posZ).normalize();
target.setFire(10);
WizardryUtilities.attackEntityWithoutKnockback(target,
MagicDamage.causeDirectMagicDamage(caster, DamageType.FIRE),
3.0f * modifiers.get(SpellModifiers.DAMAGE));
if(world.isRemote){
for(int i = 0; i < 20; i++){
double x1 = caster.posX + vec.x * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
double y1 = caster.posY + caster.getEyeHeight() - 0.4f + vec.y * i / 2 + world.rand.nextFloat() / 5
- 0.1f;
double z1 = caster.posZ + vec.z * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
Wizardry.proxy.spawnParticle(Type.MAGIC_FIRE, world, x1, y1, z1,
vec.x * modifiers.get(WizardryItems.range_upgrade),
vec.y * modifiers.get(WizardryItems.range_upgrade),
vec.z * modifiers.get(WizardryItems.range_upgrade), 0);
Wizardry.proxy.spawnParticle(Type.MAGIC_FIRE, world, x1, y1, z1,
vec.x * modifiers.get(WizardryItems.range_upgrade),
vec.y * modifiers.get(WizardryItems.range_upgrade),
vec.z * modifiers.get(WizardryItems.range_upgrade), 0);
}
}
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){
boolean flag = super.cast(world, caster, hand, ticksInUse, target, modifiers);
if(flag){
if(ticksInUse % 16 == 0){
if(ticksInUse == 0) caster.playSound(SoundEvents.ENTITY_BLAZE_SHOOT, 1, 1);
caster.playSound(WizardrySounds.SPELL_LOOP_FIRE, 0.5F, 1.0f);
caster.playSound(WizardrySounds.SPELL_LOOP_FIRE, 0.5f, 1.0f);
}
}
return flag;
}
@Override
protected boolean onEntityHit(World world, Entity target, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
// Fire can damage armour stands
if(target instanceof EntityLivingBase){
if(MagicDamage.isEntityImmune(DamageType.FIRE, target)){
if(!world.isRemote && ticksInUse == 1) caster.sendMessage(new TextComponentTranslation("spell.resist",
target.getName(), this.getNameForTranslationFormatted()));
}else {
target.setFire((int)(BASE_DURATION * modifiers.get(WizardryItems.duration_upgrade)));
WizardryUtilities.attackEntityWithoutKnockback(target,
MagicDamage.causeDirectMagicDamage(caster, DamageType.FIRE),
BASE_DAMAGE * modifiers.get(SpellModifiers.POTENCY));
}
return true;
@@ -117,8 +81,19 @@ public class FlameRay extends Spell {
}
@Override
public boolean canBeCastByNPCs(){
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@Override
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return true;
}
@Override
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
ParticleBuilder.create(Type.MAGIC_FIRE).pos(x, y, z).vel(vx, vy, vz).spawn(world);
ParticleBuilder.create(Type.MAGIC_FIRE).pos(x, y, z).vel(vx, vy, vz).spawn(world);
}
}
@@ -3,48 +3,28 @@ package electroblob.wizardry.spell;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.item.IConjuredItem;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.EnumAction;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.world.World;
public class FlamingAxe extends Spell {
public class FlamingAxe extends SpellConjuration {
public FlamingAxe(){
super(Tier.ADVANCED, 45, Element.FIRE, "flaming_axe", SpellType.UTILITY, 50, EnumAction.BOW, false);
super("flaming_axe", Tier.ADVANCED, Element.FIRE, SpellType.UTILITY, 45, 50, WizardryItems.flaming_axe, SoundEvents.ENTITY_BLAZE_SHOOT);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
ItemStack flamingaxe = new ItemStack(WizardryItems.flaming_axe);
IConjuredItem.setDurationMultiplier(flamingaxe, modifiers.get(WizardryItems.duration_upgrade));
if(!WizardryUtilities.doesPlayerHaveItem(caster, WizardryItems.flaming_axe)
&& ConjureBow.conjureItemInInventory(caster, flamingaxe)){
if(world.isRemote){
for(int i = 0; i < 10; i++){
double x1 = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F
+ world.rand.nextFloat());
double z1 = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
world.spawnParticle(EnumParticleTypes.FLAME, x1, y1, z1, 0, 0, 0);
}
}
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_BLAZE_SHOOT, 1, 1);
return true;
protected void spawnParticles(World world, EntityLivingBase caster, SpellModifiers modifiers){
for(int i=0; i<10; i++){
double x = caster.posX + world.rand.nextDouble() * 2 - 1;
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
double z = caster.posZ + world.rand.nextDouble() * 2 - 1;
world.spawnParticle(EnumParticleTypes.FLAME, x, y, z, 0, 0, 0);
}
return false;
}
}
@@ -1,7 +1,6 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.WizardData;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Constants;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
@@ -9,8 +8,9 @@ import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardryEnchantments;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.player.EntityPlayer;
@@ -24,7 +24,7 @@ import net.minecraft.world.World;
public class FlamingWeapon extends Spell {
public FlamingWeapon(){
super(Tier.ADVANCED, 35, Element.FIRE, "flaming_weapon", SpellType.UTILITY, 70, EnumAction.BOW, false);
super("flaming_weapon", Tier.ADVANCED, Element.FIRE, SpellType.UTILITY, 35, 70, EnumAction.BOW, false);
}
@Override
@@ -41,21 +41,19 @@ public class FlamingWeapon extends Spell {
// The enchantment level as determined by the damage multiplier. The + 0.5f is so that
// weird float processing doesn't incorrectly round it down.
stack.addEnchantment(WizardryEnchantments.flaming_weapon,
modifiers.get(SpellModifiers.DAMAGE) == 1.0f ? 1
: (int)((modifiers.get(SpellModifiers.DAMAGE) - 1.0f)
modifiers.get(SpellModifiers.POTENCY) == 1.0f ? 1
: (int)((modifiers.get(SpellModifiers.POTENCY) - 1.0f)
/ Constants.DAMAGE_INCREASE_PER_TIER + 0.5f));
WizardData.get(caster).setImbuementDuration(WizardryEnchantments.flaming_weapon,
(int)(900 * modifiers.get(WizardryItems.duration_upgrade)));
if(world.isRemote){
for(int i = 0; i < 10; i++){
double x1 = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F
+ world.rand.nextFloat());
double z1 = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0,
48 + world.rand.nextInt(12), 0.9f, 0.7f, 1.0f);
for(int i=0; i<10; i++){
double x = caster.posX + world.rand.nextDouble() * 2 - 1;
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
double z = caster.posZ + world.rand.nextDouble() * 2 - 1;
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).colour(0.9f, 0.7f, 1).spawn(world);
}
}
@@ -1,11 +1,11 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
@@ -16,7 +16,7 @@ import net.minecraft.world.World;
public class Flight extends Spell {
public Flight(){
super(Tier.MASTER, 10, Element.EARTH, "flight", SpellType.UTILITY, 0, EnumAction.NONE, true);
super("flight", Tier.MASTER, Element.EARTH, SpellType.UTILITY, 10, 0, EnumAction.NONE, true);
}
@Override
@@ -36,19 +36,22 @@ public class Flight extends Spell {
}
caster.fallDistance = 0.0f;
}
if(world.isRemote){
Wizardry.proxy.spawnParticle(Type.SPARKLE, world,
caster.posX - 1 + world.rand.nextDouble() * 2,
WizardryUtilities.getPlayerEyesPos(caster) - 0.5f + world.rand.nextDouble(),
caster.posZ - 1 + world.rand.nextDouble() * 2, 0, -0.1F, 0, 15, 0.8f, 1.0f, 0.5f);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world,
caster.posX - 1 + world.rand.nextDouble() * 2,
WizardryUtilities.getPlayerEyesPos(caster) - 0.5f + world.rand.nextDouble(),
caster.posZ - 1 + world.rand.nextDouble() * 2, 0, -0.1F, 0, 15, 1.0f, 1.0f, 1.0f);
double x = caster.posX - 1 + world.rand.nextDouble() * 2;
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
double z = caster.posZ - 1 + world.rand.nextDouble() * 2;
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, -0.1, 0).lifetime(15).colour(0.8f, 1, 0.5f).spawn(world);
x = caster.posX - 1 + world.rand.nextDouble() * 2;
y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
z = caster.posZ - 1 + world.rand.nextDouble() * 2;
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, -0.1, 0).lifetime(15).colour(1, 1, 1).spawn(world);
}
if(ticksInUse % 24 == 0){
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_ENDERDRAGON_FLAP, 0.5F, 1.0f);
}
return true;
}
@@ -2,15 +2,15 @@ package electroblob.wizardry.spell;
import java.util.List;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardryPotions;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
@@ -21,7 +21,7 @@ import net.minecraft.world.World;
public class FontOfMana extends Spell {
public FontOfMana(){
super(Tier.MASTER, 100, Element.HEALING, "font_of_mana", SpellType.UTILITY, 250, EnumAction.BOW, false);
super("font_of_mana", Tier.MASTER, Element.HEALING, SpellType.UTILITY, 100, 250, EnumAction.BOW, false);
}
@Override
@@ -37,19 +37,23 @@ public class FontOfMana extends Spell {
// calculating this.
target.addPotionEffect(new PotionEffect(WizardryPotions.font_of_mana,
(int)(600 * modifiers.get(WizardryItems.duration_upgrade)),
modifiers.get(SpellModifiers.DAMAGE) > 1 ? 1 : 0));
modifiers.get(SpellModifiers.POTENCY) > 1 ? 1 : 0));
}
}
if(world.isRemote){
for(int i = 0; i < 100 * modifiers.get(WizardryItems.blast_upgrade); i++){
double radius = (1 + world.rand.nextDouble() * 4) * modifiers.get(WizardryItems.blast_upgrade);
double angle = world.rand.nextDouble() * Math.PI * 2;
float hue = world.rand.nextFloat() * 0.4f;
Wizardry.proxy.spawnParticle(Type.SPARKLE, world,
caster.posX + radius * Math.cos(angle), caster.getEntityBoundingBox().minY,
caster.posZ + radius * Math.sin(angle), 0, 0.03, 0, 50, 1, 1 - hue, 0.6f + hue);
double x = caster.posX + radius * Math.cos(angle);
double y = caster.getEntityBoundingBox().minY;
double z = caster.posZ + radius * Math.sin(angle);
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.03, 0).lifetime(50)
.colour(1, 1 - hue, 0.6f + hue).spawn(world);
}
}
@@ -1,57 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.MobEffects;
import net.minecraft.item.EnumAction;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class FontOfVitality extends Spell {
public FontOfVitality(){
super(Tier.MASTER, 75, Element.HEALING, "font_of_vitality", SpellType.DEFENCE, 300, EnumAction.BOW, false);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
caster.addPotionEffect(new PotionEffect(MobEffects.ABSORPTION,
(int)(1200 * modifiers.get(WizardryItems.duration_upgrade)), 1, false, false));
caster.addPotionEffect(new PotionEffect(MobEffects.REGENERATION,
(int)(300 * modifiers.get(WizardryItems.duration_upgrade)), 1, false, false));
if(world.isRemote){
for(int i = 0; i < 10; i++){
double x1 = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat());
double z1 = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0,
48 + world.rand.nextInt(12), 1.0f, 0.6f, 0.7f);
x1 = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat());
z1 = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0,
48 + world.rand.nextInt(12), 1.0f, 0.8f, 0.3f);
}
}
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F,
world.rand.nextFloat() * 0.4F + 1.0F);
return true;
}
}
@@ -1,69 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.projectile.EntityForceArrow;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class ForceArrow extends Spell {
public ForceArrow(){
super(Tier.APPRENTICE, 15, Element.SORCERY, "force_arrow", SpellType.ATTACK, 20, EnumAction.NONE, false);
}
@Override
public boolean doesSpellRequirePacket(){
return false;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
if(!world.isRemote){
EntityForceArrow forceArrow = new EntityForceArrow(world, caster,
1 * modifiers.get(WizardryItems.range_upgrade), modifiers.get(SpellModifiers.DAMAGE));
world.spawnEntity(forceArrow);
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_FORCE, 1.0f,
1.2f + world.rand.nextFloat() * 0.2f);
return true;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
if(!world.isRemote){
EntityForceArrow forceArrow = new EntityForceArrow(world, caster, target,
1 * modifiers.get(WizardryItems.range_upgrade), 2, modifiers.get(SpellModifiers.DAMAGE));
world.spawnEntity(forceArrow);
}
caster.swingArm(hand);
caster.playSound(WizardrySounds.SPELL_FORCE, 1.0f, 1.2f + world.rand.nextFloat() * 0.2f);
return true;
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
}
}
@@ -1,70 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.projectile.EntityForceOrb;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class ForceOrb extends Spell {
public ForceOrb(){
super(Tier.ADVANCED, 20, Element.SORCERY, "force_orb", SpellType.ATTACK, 20, EnumAction.NONE, false);
}
@Override
public boolean doesSpellRequirePacket(){
return false;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
if(!world.isRemote){
EntityForceOrb forceOrb = new EntityForceOrb(world, caster, modifiers.get(SpellModifiers.DAMAGE),
modifiers.get(WizardryItems.blast_upgrade));
world.spawnEntity(forceOrb);
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_SNOWBALL_THROW, 0.5F,
0.4F / (world.rand.nextFloat() * 0.4F + 0.8F));
return true;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
if(!world.isRemote){
EntityForceOrb forceOrb = new EntityForceOrb(world, caster, modifiers.get(SpellModifiers.DAMAGE),
modifiers.get(WizardryItems.blast_upgrade));
forceOrb.directTowards(target, 1.5f);
world.spawnEntity(forceOrb);
}
caster.swingArm(hand);
caster.playSound(SoundEvents.ENTITY_SNOWBALL_THROW, 0.5F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F));
return true;
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
}
}
@@ -1,73 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.construct.EntityForcefield;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class Forcefield extends Spell {
public Forcefield(){
super(Tier.ADVANCED, 45, Element.HEALING, "forcefield", SpellType.DEFENCE, 200, EnumAction.BOW, false);
}
@Override
public boolean doesSpellRequirePacket(){
return false;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
if(caster.onGround){
if(!world.isRemote){
EntityForcefield forcefield = new EntityForcefield(world, caster.posX, caster.posY, caster.posZ, caster,
(int)(600 * modifiers.get(WizardryItems.duration_upgrade)));
world.spawnEntity(forcefield);
}
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION_LARGE, 1.0f, 1.0f);
return true;
}
return false;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
// Wizards can no longer cast forcefield when they are inside one
if(caster.onGround
&& world.getEntitiesWithinAABB(EntityForcefield.class, caster.getEntityBoundingBox()).isEmpty()){
if(!world.isRemote){
EntityForcefield forcefield = new EntityForcefield(world, caster.posX, caster.posY, caster.posZ,
caster, (int)(600 * modifiers.get(WizardryItems.duration_upgrade)));
world.spawnEntity(forcefield);
}
caster.playSound(WizardrySounds.SPELL_CONJURATION_LARGE, 1.0f, 1.0f);
return true;
}
return false;
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
}
}
@@ -1,76 +1,62 @@
package electroblob.wizardry.spell;
import java.util.List;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.MobEffects;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.EnumAction;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class ForestsCurse extends Spell {
public class ForestsCurse extends SpellAreaEffect {
private static final int BASE_DAMAGE = 4;
private static final int BASE_DURATION = 140;
public ForestsCurse(){
super(Tier.MASTER, 75, Element.EARTH, "forests_curse", SpellType.ATTACK, 200, EnumAction.BOW, false);
super("forests_curse", Tier.MASTER, Element.EARTH, SpellType.ATTACK, 75, 200, EnumAction.BOW, 5, SoundEvents.ENTITY_WITHER_SPAWN);
this.soundValues(1, 1.1f, 0.2f);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
List<EntityLivingBase> targets = WizardryUtilities.getEntitiesWithinRadius(
5.0d * modifiers.get(WizardryItems.blast_upgrade), caster.posX, caster.posY, caster.posZ, world);
for(EntityLivingBase target : targets){
if(WizardryUtilities.isValidTarget(caster, target)
&& !MagicDamage.isEntityImmune(DamageType.POISON, target)){
target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.POISON),
4.0f * modifiers.get(SpellModifiers.DAMAGE));
target.addPotionEffect(new PotionEffect(MobEffects.POISON,
(int)(140 * modifiers.get(WizardryItems.duration_upgrade)), 2));
target.addPotionEffect(new PotionEffect(MobEffects.SLOWNESS,
(int)(140 * modifiers.get(WizardryItems.duration_upgrade)), 2));
target.addPotionEffect(new PotionEffect(MobEffects.WEAKNESS,
(int)(140 * modifiers.get(WizardryItems.duration_upgrade)), 2));
}
protected void affectEntity(World world, EntityLivingBase caster, EntityLivingBase target, SpellModifiers modifiers){
if(!MagicDamage.isEntityImmune(DamageType.POISON, target) && WizardryUtilities.isLiving(target)){
target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.POISON),
BASE_DAMAGE * modifiers.get(SpellModifiers.POTENCY));
int duration = (int)(BASE_DURATION * modifiers.get(WizardryItems.duration_upgrade));
target.addPotionEffect(new PotionEffect(MobEffects.POISON, duration, 2));
target.addPotionEffect(new PotionEffect(MobEffects.SLOWNESS, duration, 2));
target.addPotionEffect(new PotionEffect(MobEffects.WEAKNESS, duration, 2));
}
if(world.isRemote){
for(int i = 0; i < 50 * modifiers.get(WizardryItems.blast_upgrade); i++){
double radius = (1 + world.rand.nextDouble() * 4) * modifiers.get(WizardryItems.blast_upgrade);
double angle = world.rand.nextDouble() * Math.PI * 2;
float brightness = world.rand.nextFloat() / 4;
Wizardry.proxy.spawnParticle(Type.DARK_MAGIC, world,
caster.posX + radius * Math.cos(angle), WizardryUtilities.getPlayerEyesPos(caster) + 0.5,
caster.posZ + radius * Math.sin(angle), 0, -0.2, 0, 0, 0.05f + brightness, 0.2f + brightness,
0.0f);
brightness = world.rand.nextFloat() / 4;
Wizardry.proxy.spawnParticle(Type.SPARKLE, world,
caster.posX + radius * Math.cos(angle), WizardryUtilities.getPlayerEyesPos(caster) + 0.5,
caster.posZ + radius * Math.sin(angle), 0, -0.05, 0, 50, 0.1f + brightness, 0.2f + brightness,
0.0f);
Wizardry.proxy.spawnParticle(Type.LEAF, world, caster.posX + radius * Math.cos(angle),
WizardryUtilities.getPlayerEyesPos(caster) + 0.5, caster.posZ + radius * Math.sin(angle), 0,
-0.01, 0, 40 + world.rand.nextInt(12));
}
}
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_WITHER_SPAWN, 1.0F,
world.rand.nextFloat() * 0.2F + 1.0F);
return true;
}
@Override
protected void spawnParticle(World world, double x, double y, double z){
y += 2; // Moves the particles up to the caster's head level
float brightness = world.rand.nextFloat() / 4;
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).vel(0, -0.2, 0)
.colour(0.05f + brightness, 0.2f + brightness, 0).spawn(world);
brightness = world.rand.nextFloat() / 4;
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, -0.05, 0).lifetime(50)
.colour(0.1f + brightness, 0.2f + brightness, 0).spawn(world);
ParticleBuilder.create(Type.LEAF).pos(x, y, z).vel(0, -0.01, 0).lifetime(40 + world.rand.nextInt(12)).spawn(world);
}
}
@@ -1,6 +1,5 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
@@ -10,189 +9,87 @@ import electroblob.wizardry.registry.WizardryPotions;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.monster.EntityBlaze;
import net.minecraft.entity.monster.EntityMagmaCube;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.EnumAction;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.World;
public class Freeze extends Spell {
public class Freeze extends SpellRay {
/** The base duration of the frostbite effect appled by this spell. */
private static final int BASE_DURATION = 200;
/** The base damage dealt to entities vulnerable to frost. */
private static final float BASE_DAMAGE = 3;
public Freeze(){
super(Tier.BASIC, 5, Element.ICE, "freeze", SpellType.ATTACK, 10, EnumAction.NONE, false);
super("freeze", Tier.BASIC, Element.ICE, SpellType.ATTACK, 5, 10, false, 10, WizardrySounds.SPELL_ICE);
this.soundValues(1, 1.4f, 0.4f);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
protected boolean onEntityHit(World world, Entity target, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
if(WizardryUtilities.isLiving(target)){
// Entity ray trace is done first because block ray trace passes through entities; if it was the other
// way round, entities would only be hit when there were no blocks in range behind them.
RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster,
10 * modifiers.get(WizardryItems.range_upgrade));
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY && WizardryUtilities.isLiving(rayTrace.entityHit)){
EntityLivingBase target = (EntityLivingBase)rayTrace.entityHit;
if(target instanceof EntityBlaze || target instanceof EntityMagmaCube
|| target instanceof EntityBlazeMinion){
if(target instanceof EntityBlaze || target instanceof EntityMagmaCube || target instanceof EntityBlazeMinion){
target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.FROST),
3.0f * modifiers.get(SpellModifiers.DAMAGE));
BASE_DAMAGE * modifiers.get(SpellModifiers.POTENCY));
}
if(MagicDamage.isEntityImmune(DamageType.FROST, target)){
if(!world.isRemote) caster.sendMessage(new TextComponentTranslation("spell.resist", target.getName(),
this.getNameForTranslationFormatted()));
}else{
target.addPotionEffect(new PotionEffect(WizardryPotions.frost,
(int)(200 * modifiers.get(WizardryItems.duration_upgrade)), 1));
((EntityLivingBase)target).addPotionEffect(new PotionEffect(WizardryPotions.frost,
(int)(BASE_DURATION * modifiers.get(WizardryItems.duration_upgrade)), 1));
}
if(target.isBurning()){
target.extinguish();
}
if(world.isRemote){
double dx = target.posX - caster.posX;
double dy = (target.getEntityBoundingBox().minY + target.height / 2)
- WizardryUtilities.getPlayerEyesPos(caster);
double dz = target.posZ - caster.posZ;
for(int i = 1; i < 5; i++){
float brightness = 0.5f + (world.rand.nextFloat() / 2);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world,
caster.posX + (i * (dx / 5)) + world.rand.nextFloat() / 5,
WizardryUtilities.getPlayerEyesPos(caster) + (i * (dy / 5)) + world.rand.nextFloat() / 5,
caster.posZ + (i * (dz / 5)) + world.rand.nextFloat() / 5, 0.0d, 0.0d, 0.0d,
12 + world.rand.nextInt(8), brightness, brightness + 0.1f, 1.0f);
Wizardry.proxy.spawnParticle(Type.SNOW, world,
caster.posX + (i * (dx / 5)) + world.rand.nextFloat() / 5,
WizardryUtilities.getPlayerEyesPos(caster) + (i * (dy / 5)) + world.rand.nextFloat() / 5,
caster.posZ + (i * (dz / 5)) + world.rand.nextFloat() / 5, 0, -0.02, 0,
40 + world.rand.nextInt(10));
}
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 1.0F,
world.rand.nextFloat() * 0.4F + 1.2F);
if(target.isBurning()) target.extinguish();
return true;
}else{
rayTrace = WizardryUtilities.rayTrace(10 * modifiers.get(WizardryItems.range_upgrade), world, caster, true);
// Gets block the player is looking at and sets to ice or covers with snow as necessary
// Note how the block is set on the server side only (kinda obvious really) but the particles are
// spawned on the client side only.
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){
BlockPos pos = rayTrace.getBlockPos();
if(world.getBlockState(pos).getBlock() == Blocks.WATER && !world.isRemote){
world.setBlockState(pos, Blocks.ICE.getDefaultState());
}else if(world.getBlockState(pos).getBlock() == Blocks.LAVA && !world.isRemote){
world.setBlockState(pos, Blocks.OBSIDIAN.getDefaultState());
}else if(world.getBlockState(pos).getBlock() == Blocks.FLOWING_LAVA && !world.isRemote){
world.setBlockState(pos, Blocks.COBBLESTONE.getDefaultState());
}else if(rayTrace.sideHit == EnumFacing.UP && !world.isRemote && world.isSideSolid(pos, EnumFacing.UP)
&& WizardryUtilities.canBlockBeReplaced(world, pos.up())){
world.setBlockState(pos.up(), Blocks.SNOW_LAYER.getDefaultState());
}
if(world.isRemote){
double dx = pos.getX() + 0.5 - caster.posX;
double dy = pos.getY() + 0.5 - WizardryUtilities.getPlayerEyesPos(caster);
double dz = pos.getZ() + 0.5 - caster.posZ;
for(int i = 1; i < 5; i++){
float brightness = 0.5f + (world.rand.nextFloat() / 2);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world,
caster.posX + (i * (dx / 5)) + world.rand.nextFloat() / 5,
WizardryUtilities.getPlayerEyesPos(caster) + (i * (dy / 5))
+ world.rand.nextFloat() / 5,
caster.posZ + (i * (dz / 5)) + world.rand.nextFloat() / 5, 0.0d, 0.0d, 0.0d,
20 + world.rand.nextInt(8), brightness, brightness + 0.1f, 1.0f);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world,
caster.posX + (i * (dx / 5)) + world.rand.nextFloat() / 5,
WizardryUtilities.getPlayerEyesPos(caster) + (i * (dy / 5))
+ world.rand.nextFloat() / 5,
caster.posZ + (i * (dz / 5)) + world.rand.nextFloat() / 5, 0, 0, 0,
20 + world.rand.nextInt(8), 1.0f, 1.0f, 1.0f);
}
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 1.0F,
world.rand.nextFloat() * 0.4F + 1.2F);
return true;
}
}
return false;
return false; // If the spell hit a non-living entity
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
if(target instanceof EntityBlaze || target instanceof EntityMagmaCube
|| target instanceof EntityBlazeMinion){
target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.FROST),
3.0f * modifiers.get(SpellModifiers.DAMAGE));
}
if(!world.isRemote && !MagicDamage.isEntityImmune(DamageType.FROST, target)){
target.addPotionEffect(new PotionEffect(WizardryPotions.frost,
(int)(200 * modifiers.get(WizardryItems.duration_upgrade)), 1));
}
if(target.isBurning()){
target.extinguish();
}
if(world.isRemote){
double dx = target.posX - caster.posX;
double dy = (target.getEntityBoundingBox().minY + target.height / 2)
- (caster.posY + caster.getEyeHeight());
double dz = target.posZ - caster.posZ;
for(int i = 1; i < 5; i++){
float brightness = 0.5f + (world.rand.nextFloat() / 2);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world,
caster.posX + (i * (dx / 5)) + world.rand.nextFloat() / 5,
caster.posY + caster.getEyeHeight() + (i * (dy / 5)) + world.rand.nextFloat() / 5,
caster.posZ + (i * (dz / 5)) + world.rand.nextFloat() / 5, 0.0d, 0.0d, 0.0d,
12 + world.rand.nextInt(8), brightness, brightness + 0.1f, 1.0f);
Wizardry.proxy.spawnParticle(Type.SNOW, world,
caster.posX + (i * (dx / 5)) + world.rand.nextFloat() / 5,
caster.posY + caster.getEyeHeight() + (i * (dy / 5)) + world.rand.nextFloat() / 5,
caster.posZ + (i * (dz / 5)) + world.rand.nextFloat() / 5, 0, -0.02, 0,
40 + world.rand.nextInt(10));
}
}
caster.swingArm(hand);
caster.playSound(WizardrySounds.SPELL_ICE, 1.0F, world.rand.nextFloat() * 0.4F + 1.2F);
return true;
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
if(world.getBlockState(pos).getBlock() == Blocks.WATER && !world.isRemote){
world.setBlockState(pos, Blocks.ICE.getDefaultState());
}else if(world.getBlockState(pos).getBlock() == Blocks.LAVA && !world.isRemote){
world.setBlockState(pos, Blocks.OBSIDIAN.getDefaultState());
}else if(world.getBlockState(pos).getBlock() == Blocks.FLOWING_LAVA && !world.isRemote){
world.setBlockState(pos, Blocks.COBBLESTONE.getDefaultState());
}else if(side == EnumFacing.UP && !world.isRemote && world.isSideSolid(pos, EnumFacing.UP)
&& WizardryUtilities.canBlockBeReplaced(world, pos.up())){
world.setBlockState(pos.up(), Blocks.SNOW_LAYER.getDefaultState());
}
return false;
return true; // Always succeeds if it hits a block
}
@Override
public boolean canBeCastByNPCs(){
return true;
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@Override
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
float brightness = 0.5f + (world.rand.nextFloat() / 2);
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).lifetime(12 + world.rand.nextInt(8))
.colour(brightness, brightness + 0.1f, 1).spawn(world);
ParticleBuilder.create(Type.SNOW).pos(x, y, z).spawn(world);
}
}
@@ -1,7 +1,6 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.WizardData;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Constants;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
@@ -9,8 +8,9 @@ import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardryEnchantments;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.player.EntityPlayer;
@@ -30,7 +30,7 @@ public class FreezingWeapon extends Spell {
public static final String FREEZING_ARROW_NBT_KEY = "frostLevel";
public FreezingWeapon(){
super(Tier.ADVANCED, 35, Element.ICE, "freezing_weapon", SpellType.UTILITY, 70, EnumAction.BOW, false);
super("freezing_weapon", Tier.ADVANCED, Element.ICE, SpellType.UTILITY, 35, 70, EnumAction.BOW, false);
}
@Override
@@ -47,25 +47,23 @@ public class FreezingWeapon extends Spell {
// The enchantment level as determined by the damage multiplier. The + 0.5f is so that
// weird float processing doesn't incorrectly round it down.
stack.addEnchantment(WizardryEnchantments.freezing_weapon,
modifiers.get(SpellModifiers.DAMAGE) == 1.0f ? 1
: (int)((modifiers.get(SpellModifiers.DAMAGE) - 1.0f)
modifiers.get(SpellModifiers.POTENCY) == 1.0f ? 1
: (int)((modifiers.get(SpellModifiers.POTENCY) - 1.0f)
/ Constants.DAMAGE_INCREASE_PER_TIER + 0.5f));
WizardData.get(caster).setImbuementDuration(WizardryEnchantments.freezing_weapon,
(int)(900 * modifiers.get(WizardryItems.duration_upgrade)));
if(world.isRemote){
for(int i = 0; i < 10; i++){
double x1 = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F
+ world.rand.nextFloat());
double z1 = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0,
48 + world.rand.nextInt(12), 0.9f, 0.7f, 1.0f);
for(int i=0; i<10; i++){
double x = caster.posX + world.rand.nextDouble() * 2 - 1;
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
double z = caster.posZ + world.rand.nextDouble() * 2 - 1;
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).colour(0.9f, 0.7f, 1).spawn(world);
}
}
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1.0f, 1.0f);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1, 1);
return true;
}
@@ -1,52 +1,31 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.item.IConjuredItem;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand;
import electroblob.wizardry.util.SpellModifiers;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.world.World;
public class FrostAxe extends Spell {
public class FrostAxe extends SpellConjuration {
public FrostAxe(){
super(Tier.ADVANCED, 45, Element.ICE, "frost_axe", SpellType.UTILITY, 50, EnumAction.BOW, false);
super("frost_axe", Tier.ADVANCED, Element.ICE, SpellType.UTILITY, 45, 50, WizardryItems.frost_axe, WizardrySounds.SPELL_ICE);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
ItemStack frostaxe = new ItemStack(WizardryItems.frost_axe);
IConjuredItem.setDurationMultiplier(frostaxe, modifiers.get(WizardryItems.duration_upgrade));
if(!WizardryUtilities.doesPlayerHaveItem(caster, WizardryItems.frost_axe)
&& ConjureBow.conjureItemInInventory(caster, frostaxe)){
if(world.isRemote){
for(int i = 0; i < 10; i++){
double x1 = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F
+ world.rand.nextFloat());
double z1 = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SNOW, world, x1, y1, z1, 0, -0.02d, 0,
40 + world.rand.nextInt(10));
}
}
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 1.0f, 1.0f);
return true;
protected void spawnParticles(World world, EntityLivingBase caster, SpellModifiers modifiers){
for(int i=0; i<10; i++){
double x = caster.posX + world.rand.nextDouble() * 2 - 1;
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
double z = caster.posZ + world.rand.nextDouble() * 2 - 1;
ParticleBuilder.create(Type.SNOW).pos(x, y, z).spawn(world);
}
return false;
}
}
@@ -1,6 +1,5 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
@@ -9,154 +8,105 @@ import electroblob.wizardry.registry.WizardryPotions;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.monster.EntityBlaze;
import net.minecraft.entity.monster.EntityMagmaCube;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.World;
public class FrostRay extends Spell {
public class FrostRay extends SpellRay {
private static final float BASE_DAMAGE = 3;
/** The base duration of the forstbite effect applied by this spell. */
private static final int BASE_DURATION = 200;
public FrostRay(){
super(Tier.APPRENTICE, 5, Element.ICE, "frost_ray", SpellType.ATTACK, 0, EnumAction.NONE, true);
super("frost_ray", Tier.APPRENTICE, Element.ICE, SpellType.ATTACK, 5, 0, true, 10, null);
this.particleVelocity(1);
this.particleSpacing(0.5);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
// TODO: Temporary solution until I implement a better continuous sound system
boolean flag = super.cast(world, caster, hand, ticksInUse, modifiers);
if(flag){
if(ticksInUse % 12 == 0){
if(ticksInUse == 0) WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 0.5f, 1);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LOOP_ICE, 0.5f, 1);
}
}
return flag;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
Vec3d look = caster.getLookVec();
RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster,
10 * modifiers.get(WizardryItems.range_upgrade));
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY && WizardryUtilities.isLiving(rayTrace.entityHit)){
EntityLivingBase target = (EntityLivingBase)rayTrace.entityHit;
if(target.isBurning()){
target.extinguish();
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){
boolean flag = super.cast(world, caster, hand, ticksInUse, target, modifiers);
if(flag){
if(ticksInUse % 12 == 0){
if(ticksInUse == 0) caster.playSound(WizardrySounds.SPELL_ICE, 0.5f, 1);
caster.playSound(WizardrySounds.SPELL_LOOP_ICE, 0.5f, 1);
}
}
return flag;
}
@Override
protected boolean onEntityHit(World world, Entity target, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
if(WizardryUtilities.isLiving(target)){
if(target.isBurning()) target.extinguish();
if(MagicDamage.isEntityImmune(DamageType.FROST, target)){
if(!world.isRemote && ticksInUse == 1) caster.sendMessage(new TextComponentTranslation("spell.resist",
target.getName(), this.getNameForTranslationFormatted()));
}else{
// For frost ray the entity can move slightly, unlike freeze.
target.addPotionEffect(new PotionEffect(WizardryPotions.frost,
(int)(200 * modifiers.get(WizardryItems.duration_upgrade)), 0));
// For frost ray the entity can move slightly, unlike freeze
((EntityLivingBase)target).addPotionEffect(new PotionEffect(WizardryPotions.frost,
(int)(BASE_DURATION * modifiers.get(WizardryItems.duration_upgrade)), 0));
float baseDamage = target instanceof EntityBlaze || target instanceof EntityMagmaCube ? 6.0f : 3.0f;
WizardryUtilities.attackEntityWithoutKnockback(target,
MagicDamage.causeDirectMagicDamage(caster, DamageType.FROST),
baseDamage * modifiers.get(SpellModifiers.DAMAGE));
float damage = BASE_DAMAGE * modifiers.get(SpellModifiers.POTENCY);
if(target instanceof EntityBlaze || target instanceof EntityMagmaCube) damage *= 2;
WizardryUtilities.attackEntityWithoutKnockback(target, MagicDamage.causeDirectMagicDamage(caster,
DamageType.FROST), damage);
}
}
if(world.isRemote){
for(int i = 0; i < 20; i++){
double x1 = caster.posX + look.x * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
double y1 = WizardryUtilities.getPlayerEyesPos(caster) - 0.4f + look.y * i / 2
+ world.rand.nextFloat() / 5 - 0.1f;
double z1 = caster.posZ + look.z * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1,
look.x * modifiers.get(WizardryItems.range_upgrade),
look.y * modifiers.get(WizardryItems.range_upgrade),
look.z * modifiers.get(WizardryItems.range_upgrade), 8 + world.rand.nextInt(12), 0.4f,
0.6f, 1.0f);
x1 = caster.posX + look.x * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
y1 = WizardryUtilities.getPlayerEyesPos(caster) - 0.4f + look.y * i / 2
+ world.rand.nextFloat() / 5 - 0.1f;
z1 = caster.posZ + look.z * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1,
look.x * modifiers.get(WizardryItems.range_upgrade),
look.y * modifiers.get(WizardryItems.range_upgrade),
look.z * modifiers.get(WizardryItems.range_upgrade), 8 + world.rand.nextInt(12), 1.0f,
1.0f, 1.0f);
}
}
if(ticksInUse % 12 == 0){
if(ticksInUse == 0) WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 0.5F, 1.0f);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LOOP_ICE, 0.5F, 1.0f);
}
return true;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
Vec3d vec = new Vec3d(target.posX - caster.posX, target.posY - caster.posY, target.posZ - caster.posZ)
.normalize();
if(target.isBurning()){
target.extinguish();
}
if(!MagicDamage.isEntityImmune(DamageType.FROST, target)){
// For frost ray the entity can move slightly, unlike freeze.
target.addPotionEffect(new PotionEffect(WizardryPotions.frost,
(int)(200 * modifiers.get(WizardryItems.duration_upgrade)), 0));
float baseDamage = target instanceof EntityBlaze || target instanceof EntityMagmaCube ? 6.0f : 3.0f;
WizardryUtilities.attackEntityWithoutKnockback(target,
MagicDamage.causeDirectMagicDamage(caster, DamageType.FROST),
baseDamage * modifiers.get(SpellModifiers.DAMAGE));
}
if(world.isRemote){
for(int i = 0; i < 20; i++){
double x1 = caster.posX + vec.x * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
double y1 = caster.posY + caster.getEyeHeight() - 0.4f + vec.y * i / 2
+ world.rand.nextFloat() / 5 - 0.1f;
double z1 = caster.posZ + vec.z * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1,
vec.x * modifiers.get(WizardryItems.range_upgrade),
vec.y * modifiers.get(WizardryItems.range_upgrade),
vec.z * modifiers.get(WizardryItems.range_upgrade), 8 + world.rand.nextInt(12), 0.4f,
0.6f, 1.0f);
x1 = caster.posX + vec.x * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
y1 = caster.posY + caster.getEyeHeight() - 0.4f + vec.y * i / 2 + world.rand.nextFloat() / 5
- 0.1f;
z1 = caster.posZ + vec.z * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1,
vec.x * modifiers.get(WizardryItems.range_upgrade),
vec.y * modifiers.get(WizardryItems.range_upgrade),
vec.z * modifiers.get(WizardryItems.range_upgrade), 8 + world.rand.nextInt(12), 1.0f,
1.0f, 1.0f);
}
}
if(ticksInUse % 12 == 0){
if(ticksInUse == 0) caster.playSound(WizardrySounds.SPELL_ICE, 0.5F, 1.0f);
caster.playSound(WizardrySounds.SPELL_LOOP_ICE, 0.5F, 1.0f);
}
return true;
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@Override
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return true;
}
@Override
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
float brightness = world.rand.nextFloat();
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(vx, vy, vz).lifetime(8 + world.rand.nextInt(12))
.colour(0.4f + 0.6f * brightness, 0.6f + 0.4f*brightness, 1).spawn(world);
ParticleBuilder.create(Type.SNOW).pos(x, y, z).vel(vx, vy, vz).lifetime(8 + world.rand.nextInt(12)).spawn(world);
}
}
@@ -1,51 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.construct.EntityFrostSigil;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World;
public class FrostSigil extends Spell {
public FrostSigil(){
super(Tier.APPRENTICE, 10, Element.ICE, "frost_sigil", SpellType.ATTACK, 20, EnumAction.NONE, false);
}
@Override
public boolean doesSpellRequirePacket(){
return false;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
RayTraceResult rayTrace = WizardryUtilities.rayTrace(10 * modifiers.get(WizardryItems.range_upgrade), world,
caster, false);
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK && rayTrace.sideHit == EnumFacing.UP){
if(!world.isRemote){
double x = rayTrace.hitVec.x;
double y = rayTrace.hitVec.y;
double z = rayTrace.hitVec.z;
EntityFrostSigil frostsigil = new EntityFrostSigil(world, x, y, z, caster,
modifiers.get(SpellModifiers.DAMAGE));
world.spawnEntity(frostsigil);
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 1.0F, 1.0F);
return true;
}
return false;
}
}
@@ -1,11 +1,11 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
@@ -16,7 +16,7 @@ import net.minecraft.world.World;
public class Glide extends Spell {
public Glide(){
super(Tier.ADVANCED, 5, Element.EARTH, "glide", SpellType.UTILITY, 0, EnumAction.NONE, true);
super("glide", Tier.ADVANCED, Element.EARTH, SpellType.UTILITY, 5, 0, EnumAction.NONE, true);
}
@Override
@@ -32,19 +32,20 @@ public class Glide extends Spell {
}
if(world.isRemote){
Wizardry.proxy.spawnParticle(Type.SPARKLE, world,
caster.posX - 0.25d + world.rand.nextDouble() / 2,
WizardryUtilities.getPlayerEyesPos(caster) - 1.5f + world.rand.nextDouble(),
caster.posZ - 0.25d + world.rand.nextDouble() / 2, 0, -0.1F, 0, 15, 1.0f, 1.0f, 1.0f);
Wizardry.proxy.spawnParticle(Type.LEAF, world,
caster.posX - 0.25d + world.rand.nextDouble() / 2,
WizardryUtilities.getPlayerEyesPos(caster) - 1.5f + world.rand.nextDouble(),
caster.posZ - 0.25d + world.rand.nextDouble() / 2, 0, -0.03, 0, 20);
double x = caster.posX - 0.25 + world.rand.nextDouble() / 2;
double y = caster.getEntityBoundingBox().minY + world.rand.nextDouble();
double z = caster.posZ - 0.25 + world.rand.nextDouble() / 2;
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, -0.1, 0).lifetime(15).colour(1, 1, 1).spawn(world);
x = caster.posX - 0.25 + world.rand.nextDouble() / 2;
y = caster.getEntityBoundingBox().minY + world.rand.nextDouble();
z = caster.posZ - 0.25 + world.rand.nextDouble() / 2;
ParticleBuilder.create(Type.LEAF).pos(x, y, z).lifetime(20).spawn(world);
}
if(ticksInUse % 24 == 0){
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ITEM_ELYTRA_FLYING, 0.5F, 1.0f);
}
return true;
}
@@ -18,7 +18,7 @@ import net.minecraft.world.World;
public class GreaterFireball extends Spell {
public GreaterFireball(){
super(Tier.ADVANCED, 20, Element.FIRE, "greater_fireball", SpellType.ATTACK, 30, EnumAction.NONE, false);
super("greater_fireball", Tier.ADVANCED, Element.FIRE, SpellType.ATTACK, 20, 30, EnumAction.NONE, false);
}
@Override
@@ -1,68 +1,28 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class GreaterHeal extends Spell {
public class GreaterHeal extends SpellBuff {
public GreaterHeal(){
super(Tier.ADVANCED, 15, Element.HEALING, "greater_heal", SpellType.DEFENCE, 40, EnumAction.BOW, false);
super("greater_heal", Tier.ADVANCED, Element.HEALING, SpellType.DEFENCE, 15, 40, WizardrySounds.SPELL_HEAL, 1, 1, 0.3f);
this.soundValues(0.7f, 1.2f, 0.4f);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
if(caster.shouldHeal()){
caster.heal((int)(8 * modifiers.get(SpellModifiers.DAMAGE)));
if(world.isRemote){
for(int i = 0; i < 10; i++){
double dx = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
double dy = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F
+ world.rand.nextFloat());
double dz = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, dx, dy, dz, 0, 0.1F, 0,
48 + world.rand.nextInt(12), 1.0f, 1.0f, 0.3f);
}
}
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F,
world.rand.nextFloat() * 0.4F + 1.0F);
protected boolean applyEffects(EntityLivingBase caster, SpellModifiers modifiers){
if(caster.getHealth() < caster.getMaxHealth() && caster.getHealth() > 0){
caster.heal(8 * modifiers.get(SpellModifiers.POTENCY));
return true;
}
return false;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(caster.getHealth() < caster.getMaxHealth()){
caster.heal((int)(8 * modifiers.get(SpellModifiers.DAMAGE)));
if(world.isRemote){
for(int i = 0; i < 10; i++){
double dx = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
double dy = (double)((float)caster.posY + caster.getEyeHeight() - 0.5F + world.rand.nextFloat());
double dz = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, dx, dy, dz, 0, 0.1F, 0,
48 + world.rand.nextInt(12), 1.0f, 1.0f, 0.3f);
}
}
caster.playSound(WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F);
return true;
}
return false;
return false;
}
}
@@ -9,8 +9,9 @@ import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.living.ISummonedCreature;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
@@ -21,7 +22,7 @@ import net.minecraft.world.World;
public class GroupHeal extends Spell {
public GroupHeal(){
super(Tier.ADVANCED, 35, Element.HEALING, "group_heal", SpellType.DEFENCE, 150, EnumAction.BOW, false);
super("group_heal", Tier.ADVANCED, Element.HEALING, SpellType.DEFENCE, 35, 150, EnumAction.BOW, false);
}
@Override
@@ -40,17 +41,18 @@ public class GroupHeal extends Spell {
if(((EntityPlayer)target).shouldHeal()){
target.heal((int)(6 * modifiers.get(SpellModifiers.DAMAGE)));
target.heal(6 * modifiers.get(SpellModifiers.POTENCY));
if(world.isRemote){
for(int i = 0; i < 10; i++){
double d0 = (double)((float)target.posX + world.rand.nextFloat() * 2 - 1.0F);
double d1 = (double)((float)WizardryUtilities.getPlayerEyesPos((EntityPlayer)target)
- 0.5F + world.rand.nextFloat());
double d2 = (double)((float)target.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, d0, d1, d2, 0, 0.1F,
0, 48 + world.rand.nextInt(12), 1.0f, 1.0f, 0.3f);
double x = caster.posX + world.rand.nextDouble() * 2 - 1;
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
double z = caster.posZ + world.rand.nextDouble() * 2 - 1;
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).colour(1, 1, 0.3f).spawn(world);
}
Wizardry.proxy.spawnEntityParticle(world, caster, 15, 1, 1, 0.3f);
}
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F,
@@ -59,7 +61,7 @@ public class GroupHeal extends Spell {
}
}
// Now also works on summoned creatures
// Now also works on summoned creatures
}else if(target instanceof ISummonedCreature){
EntityLivingBase summoner = ((ISummonedCreature)target).getCaster();
@@ -67,19 +69,19 @@ public class GroupHeal extends Spell {
if(summoner == caster || (summoner instanceof EntityPlayer
&& WizardryUtilities.isPlayerAlly(caster, (EntityPlayer)summoner))){
if(target.getHealth() < target.getMaxHealth()){
if(target.getHealth() < target.getMaxHealth() && target.getHealth() > 0){
target.heal((int)(6 * modifiers.get(SpellModifiers.DAMAGE)));
target.heal(6 * modifiers.get(SpellModifiers.POTENCY));
if(world.isRemote){
for(int i = 0; i < 10; i++){
double d0 = (double)((float)target.posX + world.rand.nextFloat() * 2 - 1.0F);
double d1 = (double)((float)WizardryUtilities.getPlayerEyesPos((EntityPlayer)target)
- 0.5F + world.rand.nextFloat());
double d2 = (double)((float)target.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, d0, d1, d2, 0, 0.1F,
0, 48 + world.rand.nextInt(12), 1.0f, 1.0f, 0.3f);
double x = caster.posX + world.rand.nextDouble() * 2 - 1;
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
double z = caster.posZ + world.rand.nextDouble() * 2 - 1;
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).colour(1, 1, 0.3f).spawn(world);
}
Wizardry.proxy.spawnEntityParticle(world, caster, 15, 1, 1, 0.3f);
}
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F,
@@ -18,7 +18,7 @@ import net.minecraft.world.World;
public class GrowthAura extends Spell {
public GrowthAura(){
super(Tier.APPRENTICE, 20, Element.EARTH, "growth_aura", SpellType.UTILITY, 50, EnumAction.NONE, false);
super("growth_aura", Tier.APPRENTICE, Element.EARTH, SpellType.UTILITY, 20, 50, EnumAction.NONE, false);
}
@Override
@@ -4,58 +4,38 @@ import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.construct.EntityHailstorm;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.world.World;
public class Hailstorm extends Spell {
public class Hailstorm extends SpellConstructRanged<EntityHailstorm> {
public Hailstorm(){
super(Tier.MASTER, 75, Element.ICE, "hailstorm", SpellType.ATTACK, 300, EnumAction.NONE, false);
super("hailstorm", Tier.MASTER, Element.ICE, SpellType.ATTACK, 75, 300, EntityHailstorm::new, 120, 20, WizardrySounds.SPELL_ICE);
this.floor(true);
}
@Override
public boolean doesSpellRequirePacket(){
return false;
protected boolean spawnConstruct(World world, double x, double y, double z, EntityLivingBase caster, SpellModifiers modifiers){
// Moves the entity back towards the caster a bit, so the area of effect is better centred on the position.
// 3 is the distance to move the entity back towards the caster.
double dx = caster.posX - x;
double dz = caster.posZ - z;
double distRatio = 3 / Math.sqrt(dx * dx + dz * dz);
x += dx * distRatio;
z += dz * distRatio;
// Moves the entity up 5 blocks so that it is above mobs' heads.
y += 5;
return super.spawnConstruct(world, x, y, z, caster, modifiers);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
RayTraceResult rayTrace = WizardryUtilities.rayTrace(20 * modifiers.get(WizardryItems.range_upgrade), world,
caster, false);
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){
if(!world.isRemote){
double x = rayTrace.hitVec.x;
double y = rayTrace.hitVec.y;
double z = rayTrace.hitVec.z;
// Moves the entity back towards the caster a bit, so the area of effect is better centred on the
// position.
// 3.0d is the distance to move the entity back towards the caster.
double dx = caster.posX - x;
double dz = caster.posZ - z;
double distRatio = 3.0d / Math.sqrt(dx * dx + dz * dz);
x += dx * distRatio;
z += dz * distRatio;
EntityHailstorm hailstorm = new EntityHailstorm(world, x, y + 5, z, caster,
(int)(120 * modifiers.get(WizardryItems.duration_upgrade)),
modifiers.get(SpellModifiers.DAMAGE));
hailstorm.rotationYaw = caster.rotationYawHead;
world.spawnEntity(hailstorm);
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 1.0F, 1.0F);
return true;
}
return false;
protected void addConstructExtras(EntityHailstorm construct, EntityLivingBase caster, SpellModifiers modifiers){
// Makes the arrows shoot in the direction the caster was looking when they cast the spell.
construct.rotationYaw = caster.rotationYawHead;
}
}
@@ -1,72 +1,27 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class Heal extends Spell {
public class Heal extends SpellBuff {
public Heal(){
super(Tier.BASIC, 5, Element.HEALING, "heal", SpellType.DEFENCE, 20, EnumAction.BOW, false);
super("heal", Tier.BASIC, Element.HEALING, SpellType.DEFENCE, 5, 20, WizardrySounds.SPELL_HEAL, 1, 1, 0.3f);
this.soundValues(0.7f, 1.2f, 0.4f);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
if(caster.shouldHeal()){
caster.heal((int)(4 * modifiers.get(SpellModifiers.DAMAGE)));
if(world.isRemote){
for(int i = 0; i < 10; i++){
double d0 = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
// Apparently the client side spawns the particles 1 block higher than it should... hence the -0.5F.
double d1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F
+ world.rand.nextFloat());
double d2 = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, d0, d1, d2, 0, 0.1F, 0,
48 + world.rand.nextInt(12), 1.0f, 1.0f, 0.3f);
}
Wizardry.proxy.spawnEntityParticle(world, caster, 15, 1.0f, 1.0f, 0.3f);
}
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F,
world.rand.nextFloat() * 0.4F + 1.0F);
protected boolean applyEffects(EntityLivingBase caster, SpellModifiers modifiers){
if(caster.getHealth() < caster.getMaxHealth() && caster.getHealth() > 0){
caster.heal(4 * modifiers.get(SpellModifiers.POTENCY));
return true;
}
return false;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(caster.getHealth() < caster.getMaxHealth()){
caster.heal((int)(4 * modifiers.get(SpellModifiers.DAMAGE)));
if(world.isRemote){
for(int i = 0; i < 10; i++){
double dx = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
double dy = (double)((float)caster.posY + caster.getEyeHeight() - 0.5F + world.rand.nextFloat());
double dz = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, dx, dy, dz, 0, 0.1F, 0,
48 + world.rand.nextInt(12), 1.0f, 1.0f, 0.3f);
}
}
caster.playSound(WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F);
return true;
}
return false;
}
@@ -4,53 +4,63 @@ import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class HealAlly extends Spell {
public class HealAlly extends SpellRay {
public HealAlly(){
super(Tier.APPRENTICE, 10, Element.HEALING, "heal_ally", SpellType.DEFENCE, 20, EnumAction.NONE, false);
super("heal_ally", Tier.APPRENTICE, Element.HEALING, SpellType.DEFENCE, 10, 20, false, 10, WizardrySounds.SPELL_HEAL);
this.soundValues(0.7f, 1.2f, 0.4f);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster,
10 * modifiers.get(WizardryItems.range_upgrade), 8.0f);
if(rayTrace != null && rayTrace.entityHit != null && WizardryUtilities.isLiving(rayTrace.entityHit)){
EntityLivingBase target = (EntityLivingBase)rayTrace.entityHit;
if(target.getHealth() < target.getMaxHealth()){
target.heal((int)(5 * modifiers.get(SpellModifiers.DAMAGE)));
protected boolean onEntityHit(World world, Entity target, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
if(WizardryUtilities.isLiving(target)){
EntityLivingBase entity = (EntityLivingBase)target;
if(entity.getHealth() < entity.getMaxHealth() && entity.getHealth() > 0){
entity.heal((int)(5 * modifiers.get(SpellModifiers.POTENCY)));
if(world.isRemote){
float r = 1; float g = 1; float b = 0.3f;
for(int i = 0; i < 10; i++){
double d0 = (double)((float)target.posX + world.rand.nextFloat() * 2 - 1.0F);
// Apparently the client side spawns the particles 1 block higher than it should... hence the -
// 0.5F.
double d1 = (double)((float)target.getEntityBoundingBox().minY + target.height - 0.5f
+ world.rand.nextFloat());
double d2 = (double)((float)target.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, d0, d1, d2, 0, 0.1F, 0,
48 + world.rand.nextInt(12), 1.0f, 1.0f, 0.3f);
double x1 = (double)((float)entity.posX + world.rand.nextFloat() * 2 - 1.0f);
double y1 = (double)((float)entity.getEntityBoundingBox().minY + entity.getEyeHeight() - 0.5f + world.rand.nextFloat());
double z1 = (double)((float)entity.posZ + world.rand.nextFloat() * 2 - 1.0f);
ParticleBuilder.create(Type.SPARKLE).pos(x1, y1, z1).vel(0, 0.1F, 0).colour(r, g, b).spawn(world);
}
Wizardry.proxy.spawnEntityParticle(world, entity, 15, r, g, b);
}
caster.swingArm(hand);
target.playSound(WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F);
return true;
}
return true;
}
return false;
}
@Override
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@Override
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@@ -1,68 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.construct.EntityHealAura;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.util.SpellModifiers;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class HealingAura extends Spell {
public HealingAura(){
super(Tier.ADVANCED, 35, Element.HEALING, "healing_aura", SpellType.DEFENCE, 150, EnumAction.BOW, false);
}
@Override
public boolean doesSpellRequirePacket(){
return false;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
if(caster.onGround){
if(!world.isRemote){
EntityHealAura healaura = new EntityHealAura(world, caster.posX, caster.posY, caster.posZ, caster,
(int)(600 * modifiers.get(WizardryItems.duration_upgrade)),
modifiers.get(SpellModifiers.DAMAGE));
world.spawnEntity(healaura);
}
return true;
}
return false;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
if(caster.onGround
&& world.getEntitiesWithinAABB(EntityHealAura.class, caster.getEntityBoundingBox()).isEmpty()){
if(!world.isRemote){
EntityHealAura healaura = new EntityHealAura(world, caster.posX, caster.posY, caster.posZ, caster,
(int)(600 * modifiers.get(WizardryItems.duration_upgrade)),
modifiers.get(SpellModifiers.DAMAGE));
world.spawnEntity(healaura);
}
return true;
}
return false;
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
}
}
@@ -1,65 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.projectile.EntitySpark;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class HomingSpark extends Spell {
public HomingSpark(){
super(Tier.APPRENTICE, 10, Element.LIGHTNING, "homing_spark", SpellType.ATTACK, 20, EnumAction.NONE, false);
}
@Override
public boolean doesSpellRequirePacket(){
return false;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
if(!world.isRemote){
EntitySpark spark = new EntitySpark(world, caster, modifiers.get(SpellModifiers.DAMAGE));
world.spawnEntity(spark);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1.0F,
0.4F / (world.rand.nextFloat() * 0.4F + 0.8F));
}
caster.swingArm(hand);
return true;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
if(!world.isRemote){
EntitySpark spark = new EntitySpark(world, caster, modifiers.get(SpellModifiers.DAMAGE));
spark.directTowards(target, 0.5f);
world.spawnEntity(spark);
caster.playSound(WizardrySounds.SPELL_CONJURATION, 1.0F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F));
}
caster.swingArm(hand);
return true;
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
}
}
@@ -28,7 +28,7 @@ public class IceAge extends Spell {
private static final int baseDuration = 1200;
public IceAge(){
super(Tier.MASTER, 70, Element.ICE, "ice_age", SpellType.ATTACK, 250, EnumAction.BOW, false);
super("ice_age", Tier.MASTER, Element.ICE, SpellType.ATTACK, 70, 250, EnumAction.BOW, false);
}
@Override
@@ -1,70 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.projectile.EntityIceCharge;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class IceCharge extends Spell {
public IceCharge(){
super(Tier.ADVANCED, 20, Element.ICE, "ice_charge", SpellType.ATTACK, 30, EnumAction.NONE, false);
}
@Override
public boolean doesSpellRequirePacket(){
return false;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
if(!world.isRemote){
EntityIceCharge icecharge = new EntityIceCharge(world, caster, modifiers.get(SpellModifiers.DAMAGE),
modifiers.get(WizardryItems.blast_upgrade));
world.spawnEntity(icecharge);
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 1.0F,
world.rand.nextFloat() * 0.4F + 1.4F);
return true;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
if(!world.isRemote){
EntityIceCharge icecharge = new EntityIceCharge(world, caster, modifiers.get(SpellModifiers.DAMAGE),
modifiers.get(WizardryItems.blast_upgrade));
icecharge.directTowards(target, 1.5f);
world.spawnEntity(icecharge);
}
caster.swingArm(hand);
caster.playSound(WizardrySounds.SPELL_ICE, 1.0F, world.rand.nextFloat() * 0.4F + 1.4F);
return true;
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
}
}
@@ -1,67 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.projectile.EntityIceLance;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class IceLance extends Spell {
public IceLance(){
super(Tier.ADVANCED, 20, Element.ICE, "ice_lance", SpellType.ATTACK, 20, EnumAction.NONE, false);
}
@Override
public boolean doesSpellRequirePacket(){
return false;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
if(!world.isRemote){
EntityIceLance iceLance = new EntityIceLance(world, caster, 2 * modifiers.get(WizardryItems.range_upgrade),
modifiers.get(SpellModifiers.DAMAGE));
world.spawnEntity(iceLance);
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 1.0F,
world.rand.nextFloat() * 0.4F + 0.8F);
return true;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
if(!world.isRemote){
EntityIceLance iceLance = new EntityIceLance(world, caster, target,
2 * modifiers.get(WizardryItems.range_upgrade), 4, modifiers.get(SpellModifiers.DAMAGE));
world.spawnEntity(iceLance);
}
caster.swingArm(hand);
caster.playSound(WizardrySounds.SPELL_ICE, 1.0F, world.rand.nextFloat() * 0.4F + 0.8F);
return true;
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
}
}
@@ -1,67 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.projectile.EntityIceShard;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class IceShard extends Spell {
public IceShard(){
super(Tier.APPRENTICE, 10, Element.ICE, "ice_shard", SpellType.ATTACK, 10, EnumAction.NONE, false);
}
@Override
public boolean doesSpellRequirePacket(){
return false;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
if(!world.isRemote){
EntityIceShard iceShard = new EntityIceShard(world, caster, 2 * modifiers.get(WizardryItems.range_upgrade),
modifiers.get(SpellModifiers.DAMAGE));
world.spawnEntity(iceShard);
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 1.0F,
world.rand.nextFloat() * 0.4F + 1.4F);
return true;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
if(!world.isRemote){
EntityIceShard iceShard = new EntityIceShard(world, caster, target,
2 * modifiers.get(WizardryItems.range_upgrade), 4, modifiers.get(SpellModifiers.DAMAGE));
world.spawnEntity(iceShard);
}
caster.swingArm(hand);
caster.playSound(WizardrySounds.SPELL_ICE, 1.0F, world.rand.nextFloat() * 0.4F + 1.4F);
return true;
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
}
}
@@ -1,71 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardryPotions;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class IceShroud extends Spell {
public IceShroud(){
super(Tier.ADVANCED, 40, Element.ICE, "ice_shroud", SpellType.DEFENCE, 250, EnumAction.BOW, false);
}
@Override
public boolean doesSpellRequirePacket(){
return false;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
// Cannot be cast when it has already been cast
if(!caster.isPotionActive(WizardryPotions.ice_shroud)){
if(!world.isRemote){
caster.addPotionEffect(new PotionEffect(WizardryPotions.ice_shroud,
(int)(600 * modifiers.get(WizardryItems.duration_upgrade)), 0));
}
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 1.0F,
world.rand.nextFloat() * 0.4F + 1.4F);
return true;
}
return false;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
// Cannot be cast when it has already been cast
if(!caster.isPotionActive(WizardryPotions.ice_shroud)){
if(!world.isRemote){
caster.addPotionEffect(new PotionEffect(WizardryPotions.ice_shroud,
(int)(600 * modifiers.get(WizardryItems.duration_upgrade)), 0));
}
caster.playSound(WizardrySounds.SPELL_ICE, 1.0F, world.rand.nextFloat() * 0.4F + 1.4F);
return true;
}
return false;
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
}
}
@@ -8,107 +8,52 @@ import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World;
public class IceSpikes extends Spell {
public class IceSpikes extends SpellConstructRanged<EntityIceSpike> {
private static final int BASE_SPAWN_COUNT = 17; // Was 18, reduced to 17 to account for the extra one in the middle.
public IceSpikes(){
super(Tier.ADVANCED, 30, Element.ICE, "ice_spikes", SpellType.ATTACK, 75, EnumAction.NONE, false);
// Base duration is set to -1 so that the superclass doesn't waste time retrieving the duration multiplier
super("ice_spikes", Tier.ADVANCED, Element.ICE, SpellType.ATTACK, 30, 75, EntityIceSpike::new, -1, 20, WizardrySounds.SPELL_ICE);
}
@Override
public boolean doesSpellRequirePacket(){
return false;
}
protected boolean spawnConstruct(World world, double x, double y, double z, EntityLivingBase caster, SpellModifiers modifiers){
if(world.getBlockState(new BlockPos(x, y, z)).isNormalCube()) return false;
// Now always spawns a spike exactly at the position aimed at
super.spawnConstruct(world, x, y-1, z, caster, modifiers);
int quantity = (int)(BASE_SPAWN_COUNT * modifiers.get(WizardryItems.blast_upgrade));
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
for(int i=0; i<quantity; i++){
float angle = (float)(world.rand.nextFloat() * Math.PI * 2);
double radius = 0.5 + world.rand.nextDouble() * 2 * modifiers.get(WizardryItems.blast_upgrade);
RayTraceResult rayTrace = WizardryUtilities.rayTrace(20 * modifiers.get(WizardryItems.range_upgrade), world,
caster, false);
double x1 = x + radius * MathHelper.sin(angle);
double z1 = z + radius * MathHelper.cos(angle);
double y1 = WizardryUtilities.getNearestFloorLevel(world,
new BlockPos(MathHelper.floor(x1), (int)y, MathHelper.floor(z1)), 2) - 1;
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK && rayTrace.sideHit == EnumFacing.UP){
if(!world.isRemote){
double x = rayTrace.hitVec.x;
double y = rayTrace.hitVec.y;
double z = rayTrace.hitVec.z;
for(int i = 0; i < (int)(18 * modifiers.get(WizardryItems.blast_upgrade)); i++){
float angle = (float)(world.rand.nextFloat() * Math.PI * 2);
double radius = 0.5 + world.rand.nextDouble() * 2 * modifiers.get(WizardryItems.blast_upgrade);
double x1 = x + radius * MathHelper.sin(angle);
double z1 = z + radius * MathHelper.cos(angle);
double y1 = WizardryUtilities.getNearestFloorLevel(world,
new BlockPos(MathHelper.floor(x1), (int)y, MathHelper.floor(z1)), 2) - 1;
if(y1 > -1){
EntityIceSpike icespike = new EntityIceSpike(world, x1, y1, z1, caster,
30 + world.rand.nextInt(15), modifiers.get(SpellModifiers.DAMAGE));
world.spawnEntity(icespike);
}
}
if(y1 > -1){
super.spawnConstruct(world, x1, y1, z1, caster, modifiers);
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 1.0F, 1.0F);
return true;
}
return false;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
if(!world.isRemote){
double x = target.posX;
double y = target.posY;
double z = target.posZ;
for(int i = 0; i < (int)(18 * modifiers.get(WizardryItems.blast_upgrade)); i++){
float angle = (float)(world.rand.nextFloat() * Math.PI * 2);
double radius = 0.5 + world.rand.nextDouble() * 2 * modifiers.get(WizardryItems.blast_upgrade);
double x1 = x + radius * MathHelper.sin(angle);
double z1 = z + radius * MathHelper.cos(angle);
double y1 = WizardryUtilities.getNearestFloorLevel(world,
new BlockPos(MathHelper.floor(x1), (int)y, MathHelper.floor(z1)), 2) - 1;
if(y1 > -1){
EntityIceSpike icespike = new EntityIceSpike(world, x1, y1, z1, caster,
30 + world.rand.nextInt(15), modifiers.get(SpellModifiers.DAMAGE));
world.spawnEntity(icespike);
}
}
}
caster.swingArm(hand);
caster.playSound(WizardrySounds.SPELL_ICE, 1.0F, 1.0F);
return true;
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
}
@Override
protected void addConstructExtras(EntityIceSpike construct, EntityLivingBase caster, SpellModifiers modifiers){
// In this particular case, lifetime is implemented as a delay instead so is treated differently.
construct.lifetime = 30 + construct.world.rand.nextInt(15);
}
}
@@ -1,131 +1,63 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.block.BlockStatue;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardryAdvancementTriggers;
import electroblob.wizardry.registry.WizardryBlocks;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.tileentity.TileEntityStatue;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.WizardryUtilities;
import electroblob.wizardry.util.SpellModifiers;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.monster.EntityBlaze;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
public class IceStatue extends Spell {
public class IceStatue extends SpellRay {
private static final int baseDuration = 400;
private static final int BASE_DURATION = 400;
public IceStatue(){
super(Tier.APPRENTICE, 15, Element.ICE, "ice_statue", SpellType.ATTACK, 40, EnumAction.NONE, false);
super("ice_statue", Tier.APPRENTICE, Element.ICE, SpellType.ATTACK, 15, 40, false, 10, WizardrySounds.SPELL_ICE);
this.soundValues(1, 1.4f, 0.4f);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
Vec3d look = caster.getLookVec();
RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster,
10 * modifiers.get(WizardryItems.range_upgrade));
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY
&& rayTrace.entityHit instanceof EntityLiving && !world.isRemote){
EntityLiving target = (EntityLiving)rayTrace.entityHit;
BlockPos pos = new BlockPos(target);
if(target.isBurning()){
target.extinguish();
}
// Stops the entity looking red while frozen and the resulting z-fighting
target.hurtTime = 0;
if(target instanceof EntityBlaze) WizardryAdvancementTriggers.freeze_blaze.triggerFor(caster);
// Short mobs such as spiders and pigs
if((target.height < 1.2 || target.isChild()) && WizardryUtilities.canBlockBeReplaced(world, pos)){
world.setBlockState(pos, WizardryBlocks.ice_statue.getDefaultState());
if(world.getTileEntity(pos) instanceof TileEntityStatue){
((TileEntityStatue)world.getTileEntity(pos)).setCreatureAndPart(target, 1, 1);
((TileEntityStatue)world.getTileEntity(pos))
.setLifetime((int)(baseDuration * modifiers.get(WizardryItems.duration_upgrade)));
}
target.setDead();
target.playSound(WizardrySounds.SPELL_FREEZE, 1.0F, world.rand.nextFloat() * 0.4F + 0.8F);
}
// Normal sized mobs like zombies and skeletons
else if(target.height < 2.5 && WizardryUtilities.canBlockBeReplaced(world, pos)
&& WizardryUtilities.canBlockBeReplaced(world, pos.up())){
world.setBlockState(pos, WizardryBlocks.ice_statue.getDefaultState());
if(world.getTileEntity(pos) instanceof TileEntityStatue){
((TileEntityStatue)world.getTileEntity(pos)).setCreatureAndPart(target, 1, 2);
((TileEntityStatue)world.getTileEntity(pos))
.setLifetime((int)(baseDuration * modifiers.get(WizardryItems.duration_upgrade)));
}
world.setBlockState(pos.up(), WizardryBlocks.ice_statue.getDefaultState());
if(world.getTileEntity(pos.up()) instanceof TileEntityStatue){
((TileEntityStatue)world.getTileEntity(pos.up())).setCreatureAndPart(target, 2, 2);
}
target.setDead();
target.playSound(WizardrySounds.SPELL_FREEZE, 1.0F, world.rand.nextFloat() * 0.4F + 0.8F);
}
// Tall mobs like endermen and iron golems
else if(WizardryUtilities.canBlockBeReplaced(world, pos)
&& WizardryUtilities.canBlockBeReplaced(world, pos.up())
&& WizardryUtilities.canBlockBeReplaced(world, pos.up(2))){
world.setBlockState(pos, WizardryBlocks.ice_statue.getDefaultState());
if(world.getTileEntity(pos) instanceof TileEntityStatue){
((TileEntityStatue)world.getTileEntity(pos)).setCreatureAndPart(target, 1, 3);
((TileEntityStatue)world.getTileEntity(pos))
.setLifetime((int)(baseDuration * modifiers.get(WizardryItems.duration_upgrade)));
}
world.setBlockState(pos.up(), WizardryBlocks.ice_statue.getDefaultState());
if(world.getTileEntity(pos.up()) instanceof TileEntityStatue){
((TileEntityStatue)world.getTileEntity(pos.up())).setCreatureAndPart(target, 2, 3);
}
world.setBlockState(pos.up(2), WizardryBlocks.ice_statue.getDefaultState());
if(world.getTileEntity(pos.up(2)) instanceof TileEntityStatue){
((TileEntityStatue)world.getTileEntity(pos.up(2))).setCreatureAndPart(target, 3, 3);
}
target.setDead();
protected boolean onEntityHit(World world, Entity target, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
if(target instanceof EntityLiving && !world.isRemote){
// Unchecked cast is fine because the block is a static final field
if(((BlockStatue)WizardryBlocks.ice_statue).convertToStatue((EntityLiving)target,
(int)(BASE_DURATION * modifiers.get(WizardryItems.duration_upgrade)))){
target.playSound(WizardrySounds.SPELL_FREEZE, 1.0F, world.rand.nextFloat() * 0.4F + 0.8F);
return true;
}
}
if(world.isRemote){
for(int i = 1; i < (int)(25 * modifiers.get(WizardryItems.range_upgrade)); i += 2){
float brightness = 0.5f + (world.rand.nextFloat() / 2);
return false;
}
double x1 = caster.posX + look.x * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
double y1 = WizardryUtilities.getPlayerEyesPos(caster) - 0.4f + look.y * i / 2
+ world.rand.nextFloat() / 5 - 0.1f;
double z1 = caster.posZ + look.z * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
@Override
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d,
12 + world.rand.nextInt(8), brightness, brightness + 0.1f, 1.0f);
Wizardry.proxy.spawnParticle(Type.SNOW, world, x1, y1, z1, 0.0d, -0.02d, 0.0d,
20 + world.rand.nextInt(10));
}
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 1.0F,
world.rand.nextFloat() * 0.4F + 1.2F);
@Override
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return true;
}
@Override
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
float brightness = 0.5f + world.rand.nextFloat() * 0.5f;
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).lifetime(12 + world.rand.nextInt(8))
.colour(brightness, brightness + 0.1f, 1.0f).spawn(world);
ParticleBuilder.create(Type.SNOW).pos(x, y, z).lifetime(20 + world.rand.nextInt(10)).spawn(world);
}
}
@@ -7,168 +7,69 @@ import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.World;
public class Ignite extends Spell {
public class Ignite extends SpellRay {
/** The base duration for which entities are set on fire by this spell. */
private static final int BASE_DURATION = 10;
public Ignite(){
super(Tier.BASIC, 5, Element.FIRE, "ignite", SpellType.ATTACK, 10, EnumAction.NONE, false);
super("ignite", Tier.BASIC, Element.FIRE, SpellType.ATTACK, 5, 10, false, 10, SoundEvents.ITEM_FLINTANDSTEEL_USE);
this.soundValues(1, 1, 0.4f);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
// Entity ray trace is done first because block ray trace passes through entities; if it was the other
// way round, entities would only be hit when there were no blocks in range behind them.
RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster,
10 * modifiers.get(WizardryItems.range_upgrade));
// Fire can damage armour stands
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY && rayTrace.entityHit instanceof EntityLivingBase){
EntityLivingBase target = (EntityLivingBase)rayTrace.entityHit;
protected boolean onEntityHit(World world, Entity target, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
// Fire can damage armour stands, so this includes them
if(target instanceof EntityLivingBase) {
if(MagicDamage.isEntityImmune(DamageType.FIRE, target)){
if(!world.isRemote) caster.sendMessage(new TextComponentTranslation("spell.resist", target.getName(),
this.getNameForTranslationFormatted()));
}else{
target.setFire((int)(10 * modifiers.get(WizardryItems.duration_upgrade)));
target.setFire((int)(BASE_DURATION * modifiers.get(WizardryItems.duration_upgrade)));
}
if(world.isRemote){
double dx = target.posX - caster.posX;
double dy = (target.getEntityBoundingBox().minY + target.height / 2)
- WizardryUtilities.getPlayerEyesPos(caster);
double dz = target.posZ - caster.posZ;
// i starts at 1 so that particles are not spawned in the player's head.
for(int i = 1; i < 5; i++){
// WizardryUtilities.spawnParticleAndNotify(world, EnumParticleTypes.FLAME, caster.posX + (i*(dx/5))
// + world.rand.nextFloat()/5, caster.posY + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ +
// (i*(dz/5)) + world.rand.nextFloat()/5, 0, 0, 0, 0, 0, 0, 0);
// WizardryUtilities.spawnParticleAndNotify(world, EnumParticleTypes.FLAME, caster.posX + (i*(dx/5))
// + world.rand.nextFloat()/5, caster.posY + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ +
// (i*(dz/5)) + world.rand.nextFloat()/5, 0, 0, 0, 0, 0, 0, 0);
world.spawnParticle(EnumParticleTypes.FLAME,
caster.posX + (i * (dx / 5)) + world.rand.nextFloat() / 5,
WizardryUtilities.getPlayerEyesPos(caster) + (i * (dy / 5)) + world.rand.nextFloat() / 5,
caster.posZ + (i * (dz / 5)) + world.rand.nextFloat() / 5, 0, 0, 0);
world.spawnParticle(EnumParticleTypes.FLAME,
caster.posX + (i * (dx / 5)) + world.rand.nextFloat() / 5,
WizardryUtilities.getPlayerEyesPos(caster) + (i * (dy / 5)) + world.rand.nextFloat() / 5,
caster.posZ + (i * (dz / 5)) + world.rand.nextFloat() / 5, 0, 0, 0);
}
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ITEM_FLINTANDSTEEL_USE, 1.0F,
world.rand.nextFloat() * 0.4F + 0.8F);
return true;
}else{
rayTrace = WizardryUtilities.rayTrace(10 * modifiers.get(WizardryItems.range_upgrade), world, caster,
false);
// Gets block the player is looking at and sets the appropriate surrounding air block to fire.
// Note how the block is set on the server side only (kinda obvious really) but the particles are
// spawned on the client side only.
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){
BlockPos pos = rayTrace.getBlockPos().offset(rayTrace.sideHit);
if(world.isAirBlock(pos)){
if(!world.isRemote){
world.setBlockState(pos, Blocks.FIRE.getDefaultState());
}
if(world.isRemote){
double dx = pos.getX() + 0.5 - caster.posX;
double dy = pos.getY() + 0.5 - WizardryUtilities.getPlayerEyesPos(caster);
double dz = pos.getZ() + 0.5 - caster.posZ;
for(int i = 1; i < 5; i++){
world.spawnParticle(EnumParticleTypes.FLAME,
caster.posX + (i * (dx / 5)) + world.rand.nextFloat() / 5,
WizardryUtilities.getPlayerEyesPos(caster) + (i * (dy / 5))
+ world.rand.nextFloat() / 5,
caster.posZ + (i * (dz / 5)) + world.rand.nextFloat() / 5, 0, 0, 0);
world.spawnParticle(EnumParticleTypes.FLAME,
caster.posX + (i * (dx / 5)) + world.rand.nextFloat() / 5,
WizardryUtilities.getPlayerEyesPos(caster) + (i * (dy / 5))
+ world.rand.nextFloat() / 5,
caster.posZ + (i * (dz / 5)) + world.rand.nextFloat() / 5, 0, 0, 0);
}
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ITEM_FLINTANDSTEEL_USE, 1.0F,
world.rand.nextFloat() * 0.4F + 0.8F);
return true;
}
}
}
return false;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
if(!MagicDamage.isEntityImmune(DamageType.FIRE, target))
target.setFire((int)(10 * modifiers.get(WizardryItems.duration_upgrade)));
if(world.isRemote){
double dx = target.posX - caster.posX;
double dy = (target.getEntityBoundingBox().minY + target.height / 2)
- (caster.posY + caster.getEyeHeight());
double dz = target.posZ - caster.posZ;
// i starts at 1 so that particles are not spawned in the player's head.
for(int i = 1; i < 5; i++){
// WizardryUtilities.spawnParticleAndNotify(world, EnumParticleTypes.FLAME, caster.posX + (i*(dx/5))
// + world.rand.nextFloat()/5, caster.posY + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ +
// (i*(dz/5)) + world.rand.nextFloat()/5, 0, 0, 0, 0, 0, 0, 0);
// WizardryUtilities.spawnParticleAndNotify(world, EnumParticleTypes.FLAME, caster.posX + (i*(dx/5))
// + world.rand.nextFloat()/5, caster.posY + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ +
// (i*(dz/5)) + world.rand.nextFloat()/5, 0, 0, 0, 0, 0, 0, 0);
world.spawnParticle(EnumParticleTypes.FLAME,
caster.posX + (i * (dx / 5)) + world.rand.nextFloat() / 5,
caster.posY + caster.getEyeHeight() + (i * (dy / 5)) + world.rand.nextFloat() / 5,
caster.posZ + (i * (dz / 5)) + world.rand.nextFloat() / 5, 0, 0, 0);
world.spawnParticle(EnumParticleTypes.FLAME,
caster.posX + (i * (dx / 5)) + world.rand.nextFloat() / 5,
caster.posY + caster.getEyeHeight() + (i * (dy / 5)) + world.rand.nextFloat() / 5,
caster.posZ + (i * (dz / 5)) + world.rand.nextFloat() / 5, 0, 0, 0);
}
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
pos = pos.offset(side);
if(world.isAirBlock(pos)){
if(!world.isRemote){
world.setBlockState(pos, Blocks.FIRE.getDefaultState());
}
caster.swingArm(hand);
caster.playSound(SoundEvents.ITEM_FLINTANDSTEEL_USE, 1.0F, world.rand.nextFloat() * 0.4F + 0.8F);
return true;
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@Override
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
world.spawnParticle(EnumParticleTypes.FLAME, x, y, z, 0, 0, 0);
}
}
@@ -1,7 +1,6 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.WizardData;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Constants;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
@@ -9,8 +8,9 @@ import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardryEnchantments;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.player.EntityPlayer;
@@ -24,7 +24,7 @@ import net.minecraft.world.World;
public class ImbueWeapon extends Spell {
public ImbueWeapon(){
super(Tier.APPRENTICE, 20, Element.SORCERY, "imbue_weapon", SpellType.UTILITY, 50, EnumAction.BOW, false);
super("imbue_weapon", Tier.APPRENTICE, Element.SORCERY, SpellType.UTILITY, 20, 50, EnumAction.BOW, false);
}
@Override
@@ -40,9 +40,9 @@ public class ImbueWeapon extends Spell {
&& WizardData.get(caster).getImbuementDuration(WizardryEnchantments.magic_sword) <= 0){
// The enchantment level as determined by the damage multiplier. The + 0.5f is so that
// weird float processing doesn't incorrectly round it down.
stack.addEnchantment(WizardryEnchantments.magic_sword, modifiers.get(SpellModifiers.DAMAGE) == 1.0f
stack.addEnchantment(WizardryEnchantments.magic_sword, modifiers.get(SpellModifiers.POTENCY) == 1.0f
? 1
: (int)((modifiers.get(SpellModifiers.DAMAGE) - 1.0f) / Constants.DAMAGE_INCREASE_PER_TIER
: (int)((modifiers.get(SpellModifiers.POTENCY) - 1.0f) / Constants.DAMAGE_INCREASE_PER_TIER
+ 0.5f));
WizardData.get(caster).setImbuementDuration(WizardryEnchantments.magic_sword,
(int)(900 * modifiers.get(WizardryItems.duration_upgrade)));
@@ -52,9 +52,9 @@ public class ImbueWeapon extends Spell {
&& WizardData.get(caster).getImbuementDuration(WizardryEnchantments.magic_bow) <= 0){
// The enchantment level as determined by the damage multiplier. The + 0.5f is so that
// weird float processing doesn't incorrectly round it down.
stack.addEnchantment(WizardryEnchantments.magic_bow, modifiers.get(SpellModifiers.DAMAGE) == 1.0f
stack.addEnchantment(WizardryEnchantments.magic_bow, modifiers.get(SpellModifiers.POTENCY) == 1.0f
? 1
: (int)((modifiers.get(SpellModifiers.DAMAGE) - 1.0f) / Constants.DAMAGE_INCREASE_PER_TIER
: (int)((modifiers.get(SpellModifiers.POTENCY) - 1.0f) / Constants.DAMAGE_INCREASE_PER_TIER
+ 0.5f));
WizardData.get(caster).setImbuementDuration(WizardryEnchantments.magic_bow,
(int)(900 * modifiers.get(WizardryItems.duration_upgrade)));
@@ -64,17 +64,15 @@ public class ImbueWeapon extends Spell {
}
if(world.isRemote){
for(int i = 0; i < 10; i++){
double x1 = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F
+ world.rand.nextFloat());
double z1 = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0,
48 + world.rand.nextInt(12), 0.9f, 0.7f, 1.0f);
for(int i=0; i<10; i++){
double x = caster.posX + world.rand.nextDouble() * 2 - 1;
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
double z = caster.posZ + world.rand.nextDouble() * 2 - 1;
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).colour(0.9f, 0.7f, 1).spawn(world);
}
}
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1.0f, 1.0f);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1, 1);
return true;
}
}
@@ -2,14 +2,14 @@ package electroblob.wizardry.spell;
import java.util.List;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardryPotions;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityCreature;
@@ -34,9 +34,12 @@ public class Intimidate extends Spell {
/** The NBT tag name for storing the feared entity's UUID in the target's tag compound. */
public static final String NBT_KEY = "fearedEntity";
private static final double BASE_RANGE = 8;
private static final int BASE_DURATION = 600;
public Intimidate(){
super(Tier.APPRENTICE, 20, Element.NECROMANCY, "intimidate", SpellType.ATTACK, 100, EnumAction.BOW, false);
super("intimidate", Tier.APPRENTICE, Element.NECROMANCY, SpellType.ATTACK, 20, 100, EnumAction.BOW, false);
}
@Override
@@ -45,8 +48,8 @@ public class Intimidate extends Spell {
if(!world.isRemote){
List<EntityCreature> entities = WizardryUtilities.getEntitiesWithinRadius(
8 * modifiers.get(WizardryItems.range_upgrade), caster.posX, caster.posY, caster.posZ, world,
EntityCreature.class);
BASE_RANGE * modifiers.get(WizardryItems.range_upgrade), caster.posX, caster.posY, caster.posZ,
world, EntityCreature.class);
for(EntityCreature target : entities){
@@ -56,16 +59,16 @@ public class Intimidate extends Spell {
if(entityNBT != null) entityNBT.setUniqueId(NBT_KEY, caster.getUniqueID());
((EntityLiving)target).addPotionEffect(new PotionEffect(WizardryPotions.fear,
(int)(600 * modifiers.get(WizardryItems.duration_upgrade)), 0));
(int)(BASE_DURATION * modifiers.get(WizardryItems.duration_upgrade)), 0));
}
}else{
for(int i = 0; i < 30; i++){
Wizardry.proxy.spawnParticle(Type.DARK_MAGIC, world,
caster.posX - 1 + world.rand.nextDouble() * 2,
caster.getEntityBoundingBox().minY + 1.5 + world.rand.nextDouble() * 0.5,
caster.posZ - 1 + world.rand.nextDouble() * 2, 0, 0, 0, 0, 0.9f, 0.1f, 0.0f);
double x = caster.posX - 1 + world.rand.nextDouble() * 2;
double y = caster.getEntityBoundingBox().minY + 1.5 + world.rand.nextDouble() * 0.5;
double z = caster.posZ - 1 + world.rand.nextDouble() * 2;
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).colour(0.9f, 0.1f, 0).spawn(world);
}
}
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_ENDERDRAGON_GROWL, 1.0f, 1.0f);
@@ -2,14 +2,14 @@ package electroblob.wizardry.spell;
import java.util.List;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.MobEffects;
@@ -19,40 +19,46 @@ import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class InvigoratingPresence extends Spell {
private static final double BASE_RANGE = 5;
private static final int BASE_DURATION = 900;
public InvigoratingPresence(){
super(Tier.APPRENTICE, 30, Element.HEALING, "invigorating_presence", SpellType.UTILITY, 60, EnumAction.BOW,
false);
super("invigorating_presence", Tier.APPRENTICE, Element.HEALING, SpellType.UTILITY, 30, 60, EnumAction.BOW, false);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
List<EntityPlayer> targets = WizardryUtilities.getEntitiesWithinRadius(
5 * modifiers.get(WizardryItems.blast_upgrade), caster.posX, caster.posY, caster.posZ, world,
BASE_RANGE * modifiers.get(WizardryItems.blast_upgrade), caster.posX, caster.posY, caster.posZ, world,
EntityPlayer.class);
for(EntityPlayer target : targets){
if(WizardryUtilities.isPlayerAlly(caster, target) || target == caster){
// Strength 2 for 45 seconds.
target.addPotionEffect(new PotionEffect(MobEffects.STRENGTH,
(int)(900 * modifiers.get(WizardryItems.duration_upgrade)), 1, false, false));
(int)(BASE_DURATION * modifiers.get(WizardryItems.duration_upgrade)), 1, false, false));
}
}
if(world.isRemote){
for(int i = 0; i < 50 * modifiers.get(WizardryItems.blast_upgrade); i++){
double radius = (1 + world.rand.nextDouble() * 4) * modifiers.get(WizardryItems.blast_upgrade);
double angle = world.rand.nextDouble() * Math.PI * 2;
Wizardry.proxy.spawnParticle(Type.SPARKLE, world,
caster.posX + radius * Math.cos(angle), caster.getEntityBoundingBox().minY,
caster.posZ + radius * Math.sin(angle), 0, 0.03, 0, 50, 1, 0.2f, 0.2f);
double x = caster.posX + radius * Math.cos(angle);
double y = caster.getEntityBoundingBox().minY;
double z = caster.posZ + radius * Math.sin(angle);
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.03, 0).lifetime(50).colour(1, 0.2f, 0.2f).spawn(world);
}
}
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1.0F,
world.rand.nextFloat() * 0.2F + 1.0F);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1, 1 + 0.2f * world.rand.nextFloat());
return true;
}
@@ -1,78 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.MobEffects;
import net.minecraft.item.EnumAction;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class Invisibility extends Spell {
public Invisibility(){
super(Tier.ADVANCED, 35, Element.SORCERY, "invisibility", SpellType.UTILITY, 200, EnumAction.BOW, false);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
caster.addPotionEffect(new PotionEffect(MobEffects.INVISIBILITY,
(int)(600 * modifiers.get(WizardryItems.duration_upgrade)), 0, false, false));
if(world.isRemote){
for(int i = 0; i < 10; i++){
double x1 = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat());
double z1 = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0,
48 + world.rand.nextInt(12), 0.7f, 1.0f, 1.0f);
}
}
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F,
world.rand.nextFloat() * 0.4F + 1.0F);
return true;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(!caster.isPotionActive(MobEffects.INVISIBILITY)){
caster.addPotionEffect(new PotionEffect(MobEffects.INVISIBILITY,
(int)(600 * modifiers.get(WizardryItems.duration_upgrade)), 0, false, false));
if(world.isRemote){
for(int i = 0; i < 10; i++){
double x1 = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
double y1 = (double)((float)caster.posY + caster.getEyeHeight() - 0.5F + world.rand.nextFloat());
double z1 = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0,
48 + world.rand.nextInt(12), 0.7f, 1.0f, 1.0f);
}
}
caster.playSound(WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F);
return true;
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
}
}
@@ -2,12 +2,12 @@ package electroblob.wizardry.spell;
import java.util.Random;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
@@ -19,7 +19,7 @@ import net.minecraft.world.World;
public class InvokeWeather extends Spell {
public InvokeWeather(){
super(Tier.ADVANCED, 30, Element.LIGHTNING, "invoke_weather", SpellType.UTILITY, 100, EnumAction.BOW, false);
super("invoke_weather", Tier.ADVANCED, Element.LIGHTNING, SpellType.UTILITY, 30, 100, EnumAction.BOW, false);
}
@Override
@@ -28,8 +28,9 @@ public class InvokeWeather extends Spell {
if(caster.dimension == 0){
if(!world.isRemote){
// TODO: Backport these changes.
int standardWeatherTime = (300 + (new Random()).nextInt(600)) * 20;
if(world.isRaining()){
caster.sendMessage(new TextComponentTranslation("spell." + this.getUnlocalisedName() + ".sun"));
world.getWorldInfo().setCleanWeatherTime(standardWeatherTime);
@@ -50,18 +51,17 @@ public class InvokeWeather extends Spell {
if(world.isRemote){
for(int i = 0; i < 10; i++){
double x1 = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F
+ world.rand.nextFloat());
double z1 = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0,
48 + world.rand.nextInt(12), 0.5f, 0.7f, 1.0f);
double x = caster.posX + world.rand.nextDouble() * 2 - 1;
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
double z = caster.posZ + world.rand.nextDouble() * 2 - 1;
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).colour(0.5f, 0.7f, 1).spawn(world);
}
}
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_LIGHTNING_THUNDER, 0.5F, 1.0f);
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_LIGHTNING_THUNDER, 0.5f, 1.0f);
return true;
}
return false;
}
@@ -1,79 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.MobEffects;
import net.minecraft.item.EnumAction;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class Ironflesh extends Spell {
public Ironflesh(){
super(Tier.ADVANCED, 30, Element.HEALING, "ironflesh", SpellType.DEFENCE, 100, EnumAction.BOW, false);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
caster.addPotionEffect(new PotionEffect(MobEffects.RESISTANCE,
(int)(600 * modifiers.get(WizardryItems.duration_upgrade)), 2, false, false));
if(world.isRemote){
for(int i = 0; i < 10; i++){
double x1 = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat());
double z1 = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0,
48 + world.rand.nextInt(12), 0.4f, 0.5f, 0.6f);
}
}
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F,
world.rand.nextFloat() * 0.4F + 1.0F);
return true;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(!caster.isPotionActive(MobEffects.RESISTANCE)){
caster.addPotionEffect(new PotionEffect(MobEffects.RESISTANCE,
(int)(600 * modifiers.get(WizardryItems.duration_upgrade)), 2, false, false));
if(world.isRemote){
for(int i = 0; i < 10; i++){
double x1 = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
double y1 = (double)((float)caster.posY + caster.getEyeHeight() - 0.5F + world.rand.nextFloat());
double z1 = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0,
48 + world.rand.nextInt(12), 0.4f, 0.5f, 0.6f);
}
}
caster.playSound(WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F);
return true;
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
}
}
@@ -15,7 +15,7 @@ import net.minecraft.world.World;
public class Leap extends Spell {
public Leap(){
super(Tier.BASIC, 10, Element.EARTH, "leap", SpellType.UTILITY, 20, EnumAction.NONE, false);
super("leap", Tier.BASIC, Element.EARTH, SpellType.UTILITY, 10, 20, EnumAction.NONE, false);
}
@Override
@@ -23,7 +23,7 @@ public class Leap extends Spell {
if(caster.onGround){
caster.motionY = 0.65 * modifiers.get(SpellModifiers.DAMAGE);
caster.motionY = 0.65 * modifiers.get(SpellModifiers.POTENCY);
caster.addVelocity(caster.getLookVec().x * 0.3, 0, caster.getLookVec().z * 0.3);
if(world.isRemote){
@@ -5,9 +5,9 @@ import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.WizardryUtilities;
import electroblob.wizardry.util.SpellModifiers;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
@@ -16,7 +16,7 @@ import net.minecraft.world.World;
public class Levitation extends Spell {
public Levitation(){
super(Tier.ADVANCED, 10, Element.SORCERY, "levitation", SpellType.UTILITY, 0, EnumAction.BOW, true);
super("levitation", Tier.ADVANCED, Element.SORCERY, SpellType.UTILITY, 10, 0, EnumAction.BOW, true);
}
@Override
@@ -24,16 +24,16 @@ public class Levitation extends Spell {
caster.fallDistance = 0;
caster.motionY = caster.motionY < 0.5d ? caster.motionY + 0.1d : caster.motionY;
caster.motionY = caster.motionY < 0.5 ? caster.motionY + 0.1 : caster.motionY;
if(world.isRemote){
Wizardry.proxy.spawnParticle(Type.SPARKLE, world,
caster.posX - 0.25d + world.rand.nextDouble() / 2,
WizardryUtilities.getPlayerEyesPos(caster) - 1.5f,
caster.posZ - 0.25d + world.rand.nextDouble() / 2, 0, -0.1F, 0, 15, 0.5f, 1.0f, 0.7f);
double x = caster.posX - 0.25 + world.rand.nextDouble() * 0.5;
double y = caster.getEntityBoundingBox().minY;
double z = caster.posZ - 0.25 + world.rand.nextDouble() * 0.5;
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, -0.1, 0).lifetime(15).colour(0.5f, 1, 0.7f).spawn(world);
}
if(ticksInUse % 24 == 0 && world.isRemote){
Wizardry.proxy.playMovingSound(caster, WizardrySounds.SPELL_LOOP_SPARKLE, 0.5F, 1.0f, false);
Wizardry.proxy.playMovingSound(caster, WizardrySounds.SPELL_LOOP_SPARKLE, 0.5f, 1, false);
}
return true;
}
@@ -1,110 +1,76 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class LifeDrain extends Spell {
public class LifeDrain extends SpellRay {
private static final float BASE_DAMAGE = 2;
/** The fraction of the damage dealt that is transferred to the caster as healing. */
private static final float HEAL_FACTOR = 0.35f;
public LifeDrain(){
super(Tier.APPRENTICE, 10, Element.NECROMANCY, "life_drain", SpellType.ATTACK, 0, EnumAction.NONE, true);
super("life_drain", Tier.APPRENTICE, Element.NECROMANCY, SpellType.ATTACK, 10, 0, true, 10, null);
this.particleVelocity(-0.5);
this.particleSpacing(0.4);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
Vec3d look = caster.getLookVec();
RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster,
10 * modifiers.get(WizardryItems.range_upgrade));
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY && WizardryUtilities.isLiving(rayTrace.entityHit)){
EntityLivingBase target = (EntityLivingBase)rayTrace.entityHit;
if(ticksInUse % 12 == 0){
WizardryUtilities.attackEntityWithoutKnockback(target,
MagicDamage.causeDirectMagicDamage(caster, DamageType.MAGIC),
2.0f * modifiers.get(SpellModifiers.DAMAGE));
caster.heal(1);
// TODO: Temporary solution until I implement a better continuous sound system
boolean flag = super.cast(world, caster, hand, ticksInUse, modifiers);
if(flag){
if(ticksInUse % 18 == 0){
if(ticksInUse == 0) WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_SUMMONING, 1, 0.6f);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LOOP_CRACKLE, 2, 1);
}
}
if(world.isRemote){
for(int i = 5; i < (int)(25 * modifiers.get(WizardryItems.range_upgrade)); i += 2){
// I figured it out! when on client side, entityplayer.posY is at the eyes, not the feet!
double x1 = caster.posX + look.x * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
double y1 = WizardryUtilities.getPlayerEyesPos(caster) - 0.4f + look.y * i / 2
+ world.rand.nextFloat() / 5 - 0.1f;
double z1 = caster.posZ + look.z * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
// world.spawnParticle("mobSpell", x1, y1, z1, -1*look.xCoord, -1*look.yCoord, -1*look.zCoord);
if(i % 5 == 0){
Wizardry.proxy.spawnParticle(Type.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d,
0, 0.1f, 0.0f, 0.0f);
}
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, -0.05 * look.x * i,
-0.05 * look.y * i, -0.05 * look.z * i, 8 + world.rand.nextInt(6), 0.5f, 0.0f, 0.0f);
}
}
if(ticksInUse % 18 == 0){
if(ticksInUse == 0) WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_SUMMONING, 1.0F, 0.6f);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LOOP_CRACKLE, 2.0F, 1.0f);
}
return true;
return flag;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
Vec3d vec = new Vec3d(target.posX - caster.posX, target.posY - caster.posY, target.posZ - caster.posZ).normalize();
if(ticksInUse % 12 == 0){
WizardryUtilities.attackEntityWithoutKnockback(target,
MagicDamage.causeDirectMagicDamage(caster, DamageType.MAGIC),
2.0f * modifiers.get(SpellModifiers.DAMAGE));
caster.heal(1);
}
if(world.isRemote){
for(int i = 5; i < (int)(25 * modifiers.get(WizardryItems.range_upgrade)); i += 2){
// I figured it out! when on client side, entityplayer.posY is at the eyes, not the feet!
double x1 = caster.posX + vec.x * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
double y1 = caster.posY + caster.getEyeHeight() - 0.4f + vec.y * i / 2 + world.rand.nextFloat() / 5
- 0.1f;
double z1 = caster.posZ + vec.z * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
// world.spawnParticle("mobSpell", x1, y1, z1, -1*look.xCoord, -1*look.yCoord, -1*look.zCoord);
if(i % 5 == 0){
Wizardry.proxy.spawnParticle(Type.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d,
0, 0.1f, 0.0f, 0.0f);
}
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, -0.05 * vec.x * i,
-0.05 * vec.y * i, -0.05 * vec.z * i, 8 + world.rand.nextInt(6), 0.5f, 0.0f, 0.0f);
}
}
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){
boolean flag = super.cast(world, caster, hand, ticksInUse, target, modifiers);
if(flag){
if(ticksInUse % 18 == 0){
if(ticksInUse == 0) caster.playSound(WizardrySounds.SPELL_SUMMONING, 1.0F, 0.6f);
caster.playSound(WizardrySounds.SPELL_LOOP_CRACKLE, 2.0F, 1.0f);
if(ticksInUse == 0) caster.playSound(WizardrySounds.SPELL_SUMMONING, 1, 0.6f);
caster.playSound(WizardrySounds.SPELL_LOOP_CRACKLE, 2, 1);
}
}
return flag;
}
@Override
protected boolean onEntityHit(World world, Entity target, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
if(WizardryUtilities.isLiving(target)){
if(ticksInUse % 12 == 0){
float damage = BASE_DAMAGE * modifiers.get(SpellModifiers.POTENCY);
WizardryUtilities.attackEntityWithoutKnockback(target, MagicDamage.causeDirectMagicDamage(caster,
DamageType.MAGIC), damage);
caster.heal(damage * HEAL_FACTOR);
}
return true;
}
@@ -112,8 +78,21 @@ public class LifeDrain extends Spell {
}
@Override
public boolean canBeCastByNPCs(){
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@Override
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return true;
}
@Override
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
if(world.rand.nextInt(5) == 0) ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).colour(0.1f, 0, 0).spawn(world);
// This used to multiply the velocity by the distance from the caster
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(vx, vy, vz).lifetime(8 + world.rand.nextInt(6))
.colour(0.5f, 0, 0).spawn(world);
}
}
@@ -19,7 +19,7 @@ import net.minecraft.world.World;
public class Light extends Spell {
public Light(){
super(Tier.BASIC, 5, Element.SORCERY, "light", SpellType.UTILITY, 15, EnumAction.NONE, false);
super("light", Tier.BASIC, Element.SORCERY, SpellType.UTILITY, 5, 15, EnumAction.NONE, false);
}
@Override
@@ -30,7 +30,7 @@ public class Light extends Spell {
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
RayTraceResult rayTrace = WizardryUtilities.rayTrace(4, world, caster, false);
RayTraceResult rayTrace = WizardryUtilities.standardBlockRayTrace(world, caster, 4, false);
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){
@@ -1,69 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.projectile.EntityLightningArrow;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class LightningArrow extends Spell {
public LightningArrow(){
super(Tier.APPRENTICE, 15, Element.LIGHTNING, "lightning_arrow", SpellType.ATTACK, 20, EnumAction.NONE, false);
}
@Override
public boolean doesSpellRequirePacket(){
return false;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
if(!world.isRemote){
EntityLightningArrow lightningArrow = new EntityLightningArrow(world, caster,
2 * modifiers.get(WizardryItems.range_upgrade), modifiers.get(SpellModifiers.DAMAGE));
world.spawnEntity(lightningArrow);
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LIGHTNING, 1.0F,
world.rand.nextFloat() * 0.3F + 1.3F);
return true;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
if(!world.isRemote){
EntityLightningArrow lightningArrow = new EntityLightningArrow(world, caster, target,
2 * modifiers.get(WizardryItems.range_upgrade), 4, modifiers.get(SpellModifiers.DAMAGE));
world.spawnEntity(lightningArrow);
}
caster.swingArm(hand);
caster.playSound(WizardrySounds.SPELL_LIGHTNING, 1.0F, world.rand.nextFloat() * 0.3F + 1.3F);
return true;
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
}
}
@@ -6,100 +6,66 @@ import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardryAdvancementTriggers;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.effect.EntityLightningBolt;
import net.minecraft.entity.monster.EntityCreeper;
import net.minecraft.entity.passive.EntityPig;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumHand;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World;
import net.minecraftforge.event.entity.EntityStruckByLightningEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
@Mod.EventBusSubscriber
public class LightningBolt extends Spell {
public class LightningBolt extends SpellRay {
/** The NBT key used to store the UUID of the player that summoned the lightning bolt. Used for achievements. */
public static final String NBT_KEY = "summoningPlayer";
public LightningBolt(){
super(Tier.ADVANCED, 40, Element.LIGHTNING, "lightning_bolt", SpellType.ATTACK, 80, EnumAction.NONE, false);
super("lightning_bolt", Tier.ADVANCED, Element.LIGHTNING, SpellType.ATTACK, 40, 80, false, 200, null);
this.ignoreEntities(true);
}
@Override public boolean doesSpellRequirePacket(){ return false; }
@Override
public boolean doesSpellRequirePacket(){
protected boolean onEntityHit(World world, Entity target, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
if(world.canBlockSeeSky(pos.up())){
RayTraceResult rayTrace = WizardryUtilities.rayTrace(200, world, caster, false);
if(!world.isRemote){
EntityLightningBolt entitylightning = new EntityLightningBolt(world, pos.getX(), pos.getY(),
pos.getZ(), false);
world.addWeatherEffect(entitylightning);
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){
BlockPos pos = rayTrace.getBlockPos();
// Not sure why it is up 1 but it has to be for canBlockSeeSky to work properly.
// TODO: Remove this requirement?
if(world.canBlockSeeSky(pos.up())){
if(!world.isRemote){
EntityLightningBolt entitylightning = new EntityLightningBolt(world, pos.getX(), pos.getY(),
pos.getZ(), false);
world.addWeatherEffect(entitylightning);
// Code for eventhandler recognition; for achievements and such like. Left in for future use.
// Code for eventhandler recognition for achievements
if(caster instanceof EntityPlayer){
NBTTagCompound entityNBT = entitylightning.getEntityData();
entityNBT.setUniqueId(NBT_KEY, caster.getUniqueID());
}
caster.swingArm(hand);
return true;
}
}
return true;
}
return false;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
int x = (int)target.posX;
int y = (int)target.posY;
int z = (int)target.posZ;
// Not sure why it is up 1 but it has to be for canBlockSeeSky to work properly.
// TODO: Remove this requirement?
if(world.canBlockSeeSky(new BlockPos(x, y, z))){
if(!world.isRemote){
EntityLightningBolt entitylightning = new EntityLightningBolt(world, x, y, z, false);
world.addWeatherEffect(entitylightning);
}
caster.swingArm(hand);
return true;
}
}
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
}
@SubscribeEvent
public static void onEntityStruckByLightningEvent(EntityStruckByLightningEvent event){
@@ -116,6 +82,6 @@ public class LightningBolt extends Spell {
WizardryAdvancementTriggers.frankenstein.triggerFor(player);
}
}
}
}
@@ -1,69 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.projectile.EntityLightningDisc;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class LightningDisc extends Spell {
public LightningDisc(){
super(Tier.ADVANCED, 25, Element.LIGHTNING, "lightning_disc", SpellType.ATTACK, 60, EnumAction.NONE, false);
}
@Override
public boolean doesSpellRequirePacket(){
return false;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
if(!world.isRemote){
EntityLightningDisc lightningdisc = new EntityLightningDisc(world, caster,
modifiers.get(SpellModifiers.DAMAGE));
world.spawnEntity(lightningdisc);
}
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LIGHTNING, 1.0F,
world.rand.nextFloat() * 0.3F + 0.8F);
caster.swingArm(hand);
return true;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
if(!world.isRemote){
EntityLightningDisc lightningdisc = new EntityLightningDisc(world, caster,
modifiers.get(SpellModifiers.DAMAGE));
lightningdisc.directTowards(target, 1.2f);
world.spawnEntity(lightningdisc);
}
caster.playSound(WizardrySounds.SPELL_LIGHTNING, 1.0F, world.rand.nextFloat() * 0.3F + 0.8F);
caster.swingArm(hand);
return true;
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
}
}
@@ -4,60 +4,31 @@ import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.construct.EntityHammer;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World;
public class LightningHammer extends Spell {
public class LightningHammer extends SpellConstructRanged<EntityHammer> {
public LightningHammer(){
super(Tier.MASTER, 100, Element.LIGHTNING, "lightning_hammer", SpellType.ATTACK, 300, EnumAction.BOW, false);
super("lightning_hammer", Tier.MASTER, Element.LIGHTNING, SpellType.ATTACK, 100, 300, EntityHammer::new, 600, 40, WizardrySounds.SPELL_SUMMONING);
this.soundValues(3, 1, 0);
this.floor(true);
this.overlap(true);
}
@Override
public boolean doesSpellRequirePacket(){
return false;
protected boolean spawnConstruct(World world, double x, double y, double z, EntityLivingBase caster, SpellModifiers modifiers){
// TESTME: Does this need to be one block higher?
if(!world.canBlockSeeSky(new BlockPos(x, y, z))) return false;
return super.spawnConstruct(world, x, y + 50, z, caster, modifiers);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
RayTraceResult rayTrace = WizardryUtilities.rayTrace(40 * modifiers.get(WizardryItems.range_upgrade), world,
caster, false);
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){
BlockPos pos = rayTrace.getBlockPos();
// Not sure why it is +1 but it has to be to work properly.
if(world.canBlockSeeSky(pos.up())){
if(!world.isRemote){
EntityHammer hammer = new EntityHammer(world, pos.getX() + 0.5, pos.getY() + 50, pos.getZ() + 0.5,
caster, (int)(600 * modifiers.get(WizardryItems.duration_upgrade)),
modifiers.get(SpellModifiers.DAMAGE));
hammer.motionX = 0;
hammer.motionY = -2;
hammer.motionZ = 0;
world.spawnEntity(hammer);
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_SUMMONING, 3.0f, 1.0f);
return true;
}
}
return false;
protected void addConstructExtras(EntityHammer construct, EntityLivingBase caster, SpellModifiers modifiers){
construct.motionY = -2;
}
}
@@ -22,15 +22,20 @@ import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
public class LightningPulse extends Spell {
private static final double BASE_RADIUS = 3;
private static final float BASE_DAMAGE = 8;
public LightningPulse(){
super(Tier.ADVANCED, 25, Element.LIGHTNING, "lightning_pulse", SpellType.ATTACK, 75, EnumAction.NONE, false);
super("lightning_pulse", Tier.ADVANCED, Element.LIGHTNING, SpellType.ATTACK, 25, 75, EnumAction.NONE, false);
}
@Override
public boolean doesSpellRequirePacket(){
return false;
}
// TODO: NPC casting support
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
@@ -38,13 +43,13 @@ public class LightningPulse extends Spell {
if(caster.onGround){
List<EntityLivingBase> targets = WizardryUtilities.getEntitiesWithinRadius(
3.0d * modifiers.get(WizardryItems.blast_upgrade), caster.posX, caster.posY, caster.posZ, world);
BASE_RADIUS * modifiers.get(WizardryItems.blast_upgrade), caster.posX, caster.posY, caster.posZ, world);
for(EntityLivingBase target : targets){
if(WizardryUtilities.isValidTarget(caster, target)){
// Damage is 4 hearts no matter where the target is.
// Base damage is 4 hearts no matter where the target is.
target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK),
8 * modifiers.get(SpellModifiers.DAMAGE));
BASE_DAMAGE * modifiers.get(SpellModifiers.POTENCY));
if(!world.isRemote){
@@ -66,15 +71,20 @@ public class LightningPulse extends Spell {
}
}
}
if(!world.isRemote){
EntityLightningPulse lightningpulse = new EntityLightningPulse(world, caster.posX,
caster.getEntityBoundingBox().minY, caster.posZ, caster, 7,
modifiers.get(SpellModifiers.DAMAGE));
// Surely neither of the commented lines would have done anything?
EntityLightningPulse lightningpulse = new EntityLightningPulse(world);
lightningpulse.setPosition(caster.posX, caster.getEntityBoundingBox().minY, caster.posZ);
//lightningpulse.setCaster(caster);
lightningpulse.lifetime = 7;
//lightningpulse.damageMultiplier = modifiers.get(SpellModifiers.POTENCY);
world.spawnEntity(lightningpulse);
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LIGHTNING, 1.0f, 1.0f);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_SHOCKWAVE, 2.0f, 1.0f);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LIGHTNING, 1, 1);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_SHOCKWAVE, 2, 1);
return true;
}
return false;
@@ -1,158 +1,123 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.EntityArc;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.World;
public class LightningRay extends Spell {
public class LightningRay extends SpellRay {
private static final float BASE_DAMAGE = 3;
public LightningRay(){
super(Tier.APPRENTICE, 5, Element.LIGHTNING, "lightning_ray", SpellType.ATTACK, 0, EnumAction.NONE, true);
super("lightning_ray", Tier.APPRENTICE, Element.LIGHTNING, SpellType.ATTACK, 5, 0, true, 10, null);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster,
10 * modifiers.get(WizardryItems.range_upgrade), 2.0f);
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY && WizardryUtilities.isLiving(rayTrace.entityHit)){
Entity target = rayTrace.entityHit;
if(!world.isRemote){
// This statement means the arc only spawns every other tick.
if(ticksInUse % 2 == 0){
EntityArc arc = new EntityArc(world);
// The look vec stuff performs a translation on the start point to line it up with the wand.
// EDIT: removed due to 1st/3rd person render differences.
arc.setEndpointCoords(caster.posX, caster.posY + 1.2, caster.posZ, target.posX,
target.posY + target.height / 2, target.posZ);
arc.lifetime = 1;
world.spawnEntity(arc);
}
if(MagicDamage.isEntityImmune(DamageType.SHOCK, target)){
if(!world.isRemote && ticksInUse == 1)
caster.sendMessage(new TextComponentTranslation("spell.resist", target.getName(),
this.getNameForTranslationFormatted()));
}else{
WizardryUtilities.attackEntityWithoutKnockback(target,
MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK),
3.0f * modifiers.get(SpellModifiers.DAMAGE));
}
}else{
for(int i = 0; i < 5; i++){
Wizardry.proxy.spawnParticle(Type.SPARK, world,
target.posX + world.rand.nextFloat() - 0.5,
target.getEntityBoundingBox().minY + target.height / 2 + world.rand.nextFloat() * 2 - 1,
target.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3);
}
}
// TODO: Temporary solution until I implement a better continuous sound system
boolean flag = super.cast(world, caster, hand, ticksInUse, modifiers);
if(flag){
if(ticksInUse == 1){
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LIGHTNING, 1.0F, 1.0f);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LIGHTNING, 1, 1);
}else if(ticksInUse > 0 && ticksInUse % 20 == 0){
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LOOP_LIGHTNING, 1.0F, 1.0f);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LOOP_LIGHTNING, 1, 1);
}
return true;
}else{
if(!world.isRemote){
// This statement means the arc only spawns every other tick.
if(ticksInUse % 2 == 0){
EntityArc arc = new EntityArc(world);
arc.setEndpointCoords(caster.posX, caster.posY + 1.2, caster.posZ,
caster.posX + caster.getLookVec().x * 8,
caster.posY + caster.eyeHeight + caster.getLookVec().y * 8,
caster.posZ + caster.getLookVec().z * 8);
arc.lifetime = 1;
world.spawnEntity(arc);
}
}
if(ticksInUse == 1){
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LIGHTNING, 1.0F, 1.0f);
}else if(ticksInUse > 0 && ticksInUse % 20 == 0){
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LOOP_LIGHTNING, 1.0F, 1.0f);
}
return true;
}
return flag;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){
boolean flag = super.cast(world, caster, hand, ticksInUse, target, modifiers);
if(flag){
if(ticksInUse == 1){
caster.playSound(WizardrySounds.SPELL_LIGHTNING, 1, 1);
}else if(ticksInUse > 0 && ticksInUse % 20 == 0){
caster.playSound(WizardrySounds.SPELL_LOOP_LIGHTNING, 1, 1);
}
}
return flag;
}
if(target != null){
@Override
protected boolean onEntityHit(World world, Entity target, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
if(WizardryUtilities.isLiving(target)){
if(MagicDamage.isEntityImmune(DamageType.SHOCK, target)){
if(!world.isRemote && ticksInUse == 1)
caster.sendMessage(new TextComponentTranslation("spell.resist", target.getName(),
this.getNameForTranslationFormatted()));
}else{
WizardryUtilities.attackEntityWithoutKnockback(target,
MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK),
BASE_DAMAGE * modifiers.get(SpellModifiers.POTENCY));
}
if(!world.isRemote){
// This statement means the arc only spawns every other tick.
if(ticksInUse % 2 == 0){
EntityArc arc = new EntityArc(world);
// The look vec stuff performs a translation on the start point to line it up with the wand.
// EDIT: removed due to 1st/3rd person render differences.
arc.setEndpointCoords(caster.posX, caster.posY + 1.2, caster.posZ, target.posX,
target.posY + target.height / 2, target.posZ);
arc.lifetime = 1;
world.spawnEntity(arc);
}
WizardryUtilities.attackEntityWithoutKnockback(target,
MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK),
3.0f * modifiers.get(SpellModifiers.DAMAGE));
}else{
for(int i = 0; i < 5; i++){
Wizardry.proxy.spawnParticle(Type.SPARK, world,
target.posX + world.rand.nextFloat() - 0.5,
target.getEntityBoundingBox().minY + target.height / 2 + world.rand.nextFloat() * 2 - 1,
target.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3);
// Particle effect
for(int i=0; i<5; i++){
ParticleBuilder.create(Type.SPARK, target);
}
}
if(ticksInUse == 1){
caster.playSound(WizardrySounds.SPELL_LIGHTNING, 1.0F, 1.0f);
}else if(ticksInUse > 0 && ticksInUse % 20 == 0){
caster.playSound(WizardrySounds.SPELL_LOOP_LIGHTNING, 1.0F, 1.0f);
}
return true;
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@Override
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
// This is a nice example of when onMiss is used for more than just returning a boolean
if(!world.isRemote){
if(ticksInUse % 2 == 0){
double freeRange = 0.8 * baseRange; // The arc does not reach full range when it has a free end
EntityArc arc = new EntityArc(world);
arc.setEndpointCoords(caster.posX, caster.posY + 1.2, caster.posZ,
caster.posX + caster.getLookVec().x * freeRange,
caster.posY + caster.getEyeHeight() + caster.getLookVec().y * freeRange,
caster.posZ + caster.getLookVec().z * freeRange);
arc.lifetime = 1;
world.spawnEntity(arc);
}
}
return true;
}
@@ -1,53 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.construct.EntityLightningSigil;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World;
public class LightningSigil extends Spell {
public LightningSigil(){
super(Tier.APPRENTICE, 10, Element.LIGHTNING, "lightning_sigil", SpellType.ATTACK, 20, EnumAction.NONE, false);
}
@Override
public boolean doesSpellRequirePacket(){
return false;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
RayTraceResult rayTrace = WizardryUtilities.rayTrace(10 * modifiers.get(WizardryItems.range_upgrade), world,
caster, false);
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK && rayTrace.sideHit == EnumFacing.UP){
if(!world.isRemote){
double x = rayTrace.hitVec.x;
double y = rayTrace.hitVec.y;
double z = rayTrace.hitVec.z;
EntityLightningSigil lightningsigil = new EntityLightningSigil(world, x, y, z, caster,
modifiers.get(SpellModifiers.DAMAGE));
world.spawnEntity(lightningsigil);
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1.0F, 0.3F);
return true;
}
return false;
}
}
@@ -2,219 +2,169 @@ package electroblob.wizardry.spell;
import java.util.List;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.EntityArc;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.World;
public class LightningWeb extends Spell {
public class LightningWeb extends SpellRay {
private static final float PRIMARY_DAMAGE = 5;
private static final float SECONDARY_DAMAGE = 4;
private static final float TERTIARY_DAMAGE = 3;
private static final double PRIMARY_RANGE = 10;
private static final double SECONDARY_RANGE = 5;
private static final double TERTIARY_RANGE = 5;
private static final int SECONDARY_MAX_TARGETS = 5;
private static final int TERTIARY_MAX_TARGETS = 2; // This is per secondary target, giving 10 in total
public LightningWeb(){
super(Tier.MASTER, 15, Element.LIGHTNING, "lightning_web", SpellType.ATTACK, 0, EnumAction.NONE, true);
super("lightning_web", Tier.MASTER, Element.LIGHTNING, SpellType.ATTACK, 15, 0, true, PRIMARY_RANGE, null);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
// TODO: Temporary solution until I implement a better continuous sound system
boolean flag = super.cast(world, caster, hand, ticksInUse, modifiers);
if(flag){
if(ticksInUse == 1){
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LIGHTNING, 1, 1);
}else if(ticksInUse > 0 && ticksInUse % 20 == 0){
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LOOP_LIGHTNING, 1, 1);
}
}
return flag;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster,
10 * modifiers.get(WizardryItems.range_upgrade), 2.0f);
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY && WizardryUtilities.isLiving(rayTrace.entityHit)){
Entity target = rayTrace.entityHit;
if(!world.isRemote){
// This statement means the arc only spawns every other tick.
if(ticksInUse % 2 == 0){
EntityArc arc = new EntityArc(world);
// The look vec stuff performs a translation on the start point to line it up with the wand.
// EDIT: removed due to 1st/3rd person render differences.
arc.setEndpointCoords(caster.posX, caster.posY + 1.2, caster.posZ, target.posX,
target.posY + target.height / 2, target.posZ);
arc.lifetime = 1;
world.spawnEntity(arc);
}
if(MagicDamage.isEntityImmune(DamageType.SHOCK, target)){
if(!world.isRemote && ticksInUse == 1)
caster.sendMessage(new TextComponentTranslation("spell.resist", target.getName(),
this.getNameForTranslationFormatted()));
}else{
// This motion stuff removes knockback, which is desirable for continuous spells.
double motionX = target.motionX;
double motionY = target.motionY;
double motionZ = target.motionZ;
target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK),
5.0f * modifiers.get(SpellModifiers.DAMAGE));
target.motionX = motionX;
target.motionY = motionY;
target.motionZ = motionZ;
}
}else{
for(int i = 0; i < 5; i++){
Wizardry.proxy.spawnParticle(Type.SPARK, world,
target.posX + world.rand.nextFloat() - 0.5,
target.getEntityBoundingBox().minY + target.height / 2 + world.rand.nextFloat() * 2 - 1,
target.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3);
}
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){
boolean flag = super.cast(world, caster, hand, ticksInUse, target, modifiers);
if(flag){
if(ticksInUse == 1){
caster.playSound(WizardrySounds.SPELL_LIGHTNING, 1, 1);
}else if(ticksInUse > 0 && ticksInUse % 20 == 0){
caster.playSound(WizardrySounds.SPELL_LOOP_LIGHTNING, 1, 1);
}
}
return flag;
}
@Override
protected boolean onEntityHit(World world, Entity target, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
if(WizardryUtilities.isLiving(target)){
electrocute(world, caster, caster, target, PRIMARY_DAMAGE * modifiers.get(SpellModifiers.POTENCY), ticksInUse);
// Secondary chaining effect
double seekerRange = 5.0d;
List<EntityLivingBase> secondaryTargets = WizardryUtilities.getEntitiesWithinRadius(seekerRange,
List<EntityLivingBase> secondaryTargets = WizardryUtilities.getEntitiesWithinRadius(SECONDARY_RANGE,
target.posX, target.posY + target.height / 2, target.posZ, world);
// This is a MUCH better way of filtering the secondary targets!
secondaryTargets.remove(target);
if(secondaryTargets.size() > 5) secondaryTargets = secondaryTargets.subList(0, 5);
secondaryTargets.removeIf(e -> !WizardryUtilities.isLiving(e));
secondaryTargets.removeIf(e -> !WizardryUtilities.isValidTarget(caster, e));
if(secondaryTargets.size() > SECONDARY_MAX_TARGETS) secondaryTargets = secondaryTargets.subList(0, SECONDARY_MAX_TARGETS);
for(EntityLivingBase secondaryTarget : secondaryTargets){
if(WizardryUtilities.isValidTarget(caster, secondaryTarget)){
electrocute(world, caster, target, secondaryTarget,
SECONDARY_DAMAGE * modifiers.get(SpellModifiers.POTENCY), ticksInUse);
if(!world.isRemote){
// This statement means the arc only spawns every other tick.
if(ticksInUse % 2 == 0){
EntityArc arc = new EntityArc(world);
arc.setEndpointCoords(target.posX, target.posY + 1.2, target.posZ, secondaryTarget.posX,
secondaryTarget.posY + secondaryTarget.height / 2, secondaryTarget.posZ);
arc.lifetime = 1;
world.spawnEntity(arc);
}
// Tertiary chaining effect
if(MagicDamage.isEntityImmune(DamageType.SHOCK, secondaryTarget)){
if(!world.isRemote && ticksInUse == 1)
caster.sendMessage(new TextComponentTranslation("spell.resist",
secondaryTarget.getName(), this.getNameForTranslationFormatted()));
}else{
// This motion stuff removes knockback, which is desirable for continuous spells.
double motionX = secondaryTarget.motionX;
double motionY = secondaryTarget.motionY;
double motionZ = secondaryTarget.motionZ;
List<EntityLivingBase> tertiaryTargets = WizardryUtilities.getEntitiesWithinRadius(TERTIARY_RANGE,
secondaryTarget.posX, secondaryTarget.posY + secondaryTarget.height / 2,
secondaryTarget.posZ, world);
tertiaryTargets.remove(target);
tertiaryTargets.removeAll(secondaryTargets);
tertiaryTargets.removeIf(e -> !WizardryUtilities.isLiving(e));
tertiaryTargets.removeIf(e -> !WizardryUtilities.isValidTarget(caster, e));
if(tertiaryTargets.size() > TERTIARY_MAX_TARGETS) tertiaryTargets = tertiaryTargets.subList(0, TERTIARY_MAX_TARGETS);
secondaryTarget.attackEntityFrom(
MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK),
4.0f * modifiers.get(SpellModifiers.DAMAGE));
secondaryTarget.motionX = motionX;
secondaryTarget.motionY = motionY;
secondaryTarget.motionZ = motionZ;
}
}else{
for(int i = 0; i < 5; i++){
Wizardry.proxy.spawnParticle(Type.SPARK, world,
secondaryTarget.posX + world.rand.nextFloat() - 0.5,
secondaryTarget.getEntityBoundingBox().minY + secondaryTarget.height / 2
+ world.rand.nextFloat() * 2 - 1,
secondaryTarget.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3);
}
}
// Tertiary chaining effect
List<EntityLivingBase> tertiaryTargets = WizardryUtilities.getEntitiesWithinRadius(seekerRange,
secondaryTarget.posX, secondaryTarget.posY + secondaryTarget.height / 2,
secondaryTarget.posZ, world);
tertiaryTargets.remove(target);
tertiaryTargets.removeAll(secondaryTargets);
if(tertiaryTargets.size() > 2) tertiaryTargets = tertiaryTargets.subList(0, 2);
for(EntityLivingBase tertiaryTarget : tertiaryTargets){
if(WizardryUtilities.isValidTarget(caster, tertiaryTarget)){
if(!world.isRemote){
// This statement means the arc only spawns every other tick.
if(ticksInUse % 2 == 0){
EntityArc arc = new EntityArc(world);
arc.setEndpointCoords(secondaryTarget.posX, secondaryTarget.posY + 1.2,
secondaryTarget.posZ, tertiaryTarget.posX,
tertiaryTarget.posY + tertiaryTarget.height / 2, tertiaryTarget.posZ);
arc.lifetime = 1;
world.spawnEntity(arc);
}
if(MagicDamage.isEntityImmune(DamageType.SHOCK, tertiaryTarget)){
if(!world.isRemote && ticksInUse == 1)
caster.sendMessage(new TextComponentTranslation("spell.resist",
tertiaryTarget.getName(), this.getNameForTranslationFormatted()));
}else{
// This motion stuff removes knockback, which is desirable for continuous spells.
double motionX = tertiaryTarget.motionX;
double motionY = tertiaryTarget.motionY;
double motionZ = tertiaryTarget.motionZ;
tertiaryTarget.attackEntityFrom(
MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK),
3.0f * modifiers.get(SpellModifiers.DAMAGE));
tertiaryTarget.motionX = motionX;
tertiaryTarget.motionY = motionY;
tertiaryTarget.motionZ = motionZ;
}
}else{
for(int i = 0; i < 5; i++){
Wizardry.proxy.spawnParticle(Type.SPARK, world,
tertiaryTarget.posX + world.rand.nextFloat() - 0.5,
tertiaryTarget.getEntityBoundingBox().minY + tertiaryTarget.height / 2
+ world.rand.nextFloat() * 2 - 1,
tertiaryTarget.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3);
}
}
}
}
for(EntityLivingBase tertiaryTarget : tertiaryTargets){
electrocute(world, caster, secondaryTarget, tertiaryTarget,
TERTIARY_DAMAGE * modifiers.get(SpellModifiers.POTENCY), ticksInUse);
}
}
}
return false;
}
if(ticksInUse == 1){
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LIGHTNING, 1.0F, 1.0f);
}else if(ticksInUse > 0 && ticksInUse % 20 == 0){
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LOOP_LIGHTNING, 1.0F, 1.0f);
@Override
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@Override
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
// This is a nice example of when onMiss is used for more than just returning a boolean
if(!world.isRemote){
if(ticksInUse % 2 == 0){
double freeRange = 0.8 * baseRange; // The arc does not reach full range when it has a free end
EntityArc arc = new EntityArc(world);
arc.setEndpointCoords(caster.posX, caster.posY + 1.2, caster.posZ,
caster.posX + caster.getLookVec().x * freeRange,
caster.posY + caster.getEyeHeight() + caster.getLookVec().y * freeRange,
caster.posZ + caster.getLookVec().z * freeRange);
arc.lifetime = 1;
world.spawnEntity(arc);
}
}
return true;
}
private void electrocute(World world, Entity caster, Entity origin, Entity target, float damage, int ticksInUse){
return true;
if(MagicDamage.isEntityImmune(DamageType.SHOCK, target)){
if(!world.isRemote && ticksInUse == 1)
caster.sendMessage(new TextComponentTranslation("spell.resist",
target.getName(), this.getNameForTranslationFormatted()));
}else{
if(!world.isRemote){
// This statement means the arc only spawns every other tick.
if(ticksInUse % 2 == 0){
EntityArc arc = new EntityArc(world);
arc.setEndpointCoords(caster.posX, caster.posY + 1.2, caster.posZ,
caster.posX + caster.getLookVec().x * 8,
caster.posY + caster.eyeHeight + caster.getLookVec().y * 8,
caster.posZ + caster.getLookVec().z * 8);
arc.lifetime = 1;
// arc.setOffset(entityplayer.getLookVec().zCoord * 0.5, entityplayer.getLookVec().xCoord * 0.5);
world.spawnEntity(arc);
}
WizardryUtilities.attackEntityWithoutKnockback(target,
MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), damage);
}
if(!world.isRemote){
// Arc entity spawning
if(ticksInUse % 2 == 0){
EntityArc arc = new EntityArc(world);
arc.setEndpointCoords(origin.posX, origin.posY + 1.2, origin.posZ, target.posX,
target.posY + target.height / 2, target.posZ);
arc.lifetime = 1;
world.spawnEntity(arc);
}
if(ticksInUse == 1){
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LIGHTNING, 1.0F, 1.0f);
}else if(ticksInUse > 0 && ticksInUse % 20 == 0){
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LOOP_LIGHTNING, 1.0F, 1.0f);
}else{
// Particle effect
for(int i=0; i<5; i++){
ParticleBuilder.create(Type.SPARK, target);
}
return true;
}
}
@@ -1,71 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.projectile.EntityMagicMissile;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class MagicMissile extends Spell {
public MagicMissile(){
super(Tier.BASIC, 5, Element.MAGIC, "magic_missile", SpellType.ATTACK, 10, EnumAction.NONE, false);
}
@Override
public boolean doesSpellRequirePacket(){
return false;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
if(!world.isRemote){
EntityMagicMissile magicMissile = new EntityMagicMissile(world, caster,
2 * modifiers.get(WizardryItems.range_upgrade), modifiers.get(SpellModifiers.DAMAGE));
world.spawnEntity(magicMissile);
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_MAGIC, 1.0F,
world.rand.nextFloat() * 0.4F + 1.2F);
return true;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
if(!world.isRemote){
EntityMagicMissile magicMissile = new EntityMagicMissile(world, caster, target,
2 * modifiers.get(WizardryItems.range_upgrade), 4, modifiers.get(SpellModifiers.DAMAGE));
world.spawnEntity(magicMissile);
}
caster.swingArm(hand);
caster.playSound(WizardrySounds.SPELL_MAGIC, 1.0F, world.rand.nextFloat() * 0.4F + 1.2F);
return true;
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
}
}
@@ -9,10 +9,10 @@ import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.living.EntitySkeletonMinion;
import electroblob.wizardry.entity.living.EntityWitherSkeletonMinion;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
@@ -31,21 +31,16 @@ import net.minecraft.entity.passive.EntityChicken;
import net.minecraft.entity.passive.EntityCow;
import net.minecraft.entity.passive.EntityMooshroom;
import net.minecraft.entity.passive.EntityPig;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class Metamorphosis extends Spell {
public class Metamorphosis extends SpellRay {
public static final BiMap<Class<? extends EntityLivingBase>, Class<? extends EntityLivingBase>> TRANSFORMATIONS = HashBiMap.create();
public Metamorphosis(){
super(Tier.APPRENTICE, 15, Element.NECROMANCY, "metamorphosis", SpellType.UTILITY, 30, EnumAction.NONE, false);
static {
addTransformation(EntityPig.class, EntityPigZombie.class);
addTransformation(EntityCow.class, EntityMooshroom.class);
addTransformation(EntityChicken.class, EntityBat.class);
@@ -66,25 +61,26 @@ public class Metamorphosis extends Spell {
previousEntity = entity;
}
}
public Metamorphosis(){
super("metamorphosis", Tier.APPRENTICE, Element.NECROMANCY, SpellType.UTILITY, 15, 30, false, 10, WizardrySounds.SPELL_DEFLECTION);
this.soundValues(0.5f, 0.8f, 0);
}
@Override public boolean canBeCastByNPCs() { return false; }
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
Vec3d look = caster.getLookVec();
RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster,
10 * modifiers.get(WizardryItems.range_upgrade));
if(rayTrace != null && rayTrace.entityHit != null && WizardryUtilities.isLiving(rayTrace.entityHit)){
Entity entityHit = rayTrace.entityHit;
double xPos = entityHit.posX;
double yPos = entityHit.posY;
double zPos = entityHit.posZ;
protected boolean onEntityHit(World world, Entity target, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
if(WizardryUtilities.isLiving(target)){
double xPos = target.posX;
double yPos = target.posY;
double zPos = target.posZ;
// Sneaking allows the entities to be cycled through in the other direction.
Class<? extends EntityLivingBase> newEntityClass = caster.isSneaking() ?
TRANSFORMATIONS.inverse().get(entityHit.getClass()) : TRANSFORMATIONS.get(entityHit.getClass());
TRANSFORMATIONS.inverse().get(target.getClass()) : TRANSFORMATIONS.get(target.getClass());
if(newEntityClass == null) return false;
@@ -93,7 +89,8 @@ public class Metamorphosis extends Spell {
try {
newEntity = newEntityClass.getConstructor(World.class).newInstance(world);
} catch (Exception e){
Wizardry.logger.error("Error while attempting to transform entity " + entityHit.getClass() + " to entity " + newEntityClass);
Wizardry.logger.error("Error while attempting to transform entity " + target.getClass() + " to entity "
+ newEntityClass);
e.printStackTrace();
}
@@ -101,39 +98,34 @@ public class Metamorphosis extends Spell {
if(!world.isRemote){
// Transfers attributes from the old entity to the new one.
newEntity.setHealth(((EntityLivingBase)entityHit).getHealth());
newEntity.setHealth(((EntityLivingBase)target).getHealth());
NBTTagCompound tag = new NBTTagCompound();
entityHit.writeToNBT(tag);
target.writeToNBT(tag);
// Remove the UUID because keeping it the same causes the entity to disappear
WizardryUtilities.removeUniqueId(tag, "UUID");
newEntity.readFromNBT(tag);
entityHit.setDead();
target.setDead();
newEntity.setPosition(xPos, yPos, zPos);
world.spawnEntity(newEntity);
}else{
for(int i = 1; i < (int)(25 * modifiers.get(WizardryItems.range_upgrade)); i += 2){
// I figured it out! when on client side, entityplayer.posY is at the eyes, not the feet!
double x1 = caster.posX + look.x * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
double y1 = WizardryUtilities.getPlayerEyesPos(caster) - 0.4f + look.y * i / 2
+ world.rand.nextFloat() / 5 - 0.1f;
double z1 = caster.posZ + look.z * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
// world.spawnParticle("mobSpell", x1, y1, z1, -1*look.xCoord, -1*look.yCoord, -1*look.zCoord);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d,
12 + world.rand.nextInt(8), 0.2f, 0.0f, 0.1f);
}
for(int i = 0; i < 5; i++){
Wizardry.proxy.spawnParticle(Type.DARK_MAGIC, world, xPos, yPos, zPos, 0.0d,
0.0d, 0.0d, 0, 0.1f, 0.0f, 0.0f);
for(int i=0; i<5; i++){
ParticleBuilder.create(Type.DARK_MAGIC).pos(xPos, yPos, zPos).colour(0.1f, 0, 0).spawn(world);
}
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_DEFLECTION, 0.5F, 0.8f);
return true;
}
return false;
}
@Override
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@Override
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@@ -7,49 +7,46 @@ import electroblob.wizardry.entity.EntityMeteor;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World;
public class Meteor extends Spell {
public class Meteor extends SpellRay {
public Meteor(){
super(Tier.MASTER, 100, Element.FIRE, "meteor", SpellType.ATTACK, 200, EnumAction.NONE, false);
super("meteor", Tier.MASTER, Element.FIRE, SpellType.ATTACK, 100, 200, false, 40, WizardrySounds.SPELL_SUMMONING);
this.soundValues(3, 1, 0);
this.ignoreEntities(true);
}
@Override public boolean doesSpellRequirePacket(){ return false; }
@Override
public boolean doesSpellRequirePacket(){
protected boolean onEntityHit(World world, Entity target, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
if(world.canBlockSeeSky(pos.up())){
RayTraceResult rayTrace = WizardryUtilities.rayTrace(40 * modifiers.get(WizardryItems.range_upgrade), world,
caster, false);
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){
BlockPos pos = rayTrace.getBlockPos();
// Not sure why it is +1 but it has to be to work properly.
if(world.canBlockSeeSky(pos.up())){
if(!world.isRemote){
EntityMeteor meteor = new EntityMeteor(world, pos.getX(), pos.getY() + 50, pos.getZ(),
modifiers.get(WizardryItems.blast_upgrade));
world.spawnEntity(meteor);
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_SUMMONING, 3.0f, 1.0f);
return true;
if(!world.isRemote){
EntityMeteor meteor = new EntityMeteor(world, pos.getX(), pos.getY() + 50, pos.getZ(),
modifiers.get(WizardryItems.blast_upgrade));
world.spawnEntity(meteor);
}
return true;
}
return false;
}
@Override
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@@ -11,8 +11,9 @@ import electroblob.wizardry.entity.living.EntityEvilWizard;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardryPotions;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityList;
@@ -21,12 +22,10 @@ import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.INpc;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.item.EntityArmorStand;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.World;
import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
@@ -35,115 +34,73 @@ import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
@Mod.EventBusSubscriber
public class MindControl extends Spell {
public class MindControl extends SpellRay {
/**
* The NBT tag name for storing the controlling entity's UUID in the target's tag compound. Defined here in case it
* changes.
*/
/** The NBT tag name for storing the controlling entity's UUID in the target's tag compound. */
public static final String NBT_KEY = "controllingEntity";
private static final int BASE_DURATION = 600;
public MindControl(){
super(Tier.ADVANCED, 40, Element.NECROMANCY, "mind_control", SpellType.ATTACK, 150, EnumAction.NONE, false);
super("mind_control", Tier.ADVANCED, Element.NECROMANCY, SpellType.ATTACK, 40, 150, false, 8, WizardrySounds.SPELL_SUMMONING);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster,
8 * modifiers.get(WizardryItems.range_upgrade));
if(rayTrace != null && rayTrace.entityHit != null && WizardryUtilities.isLiving(rayTrace.entityHit)){
EntityLivingBase target = (EntityLivingBase)rayTrace.entityHit;
protected boolean onEntityHit(World world, Entity target, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
if(WizardryUtilities.isLiving(target)){
if(!world.isRemote){
if(!canControl(target)){
// Adds a message saying that the player/boss entity/wizard resisted mind control
caster.sendMessage(new TextComponentTranslation("spell.resist", target.getName(),
this.getNameForTranslationFormatted()));
}else if(target instanceof EntityLiving){
if(!MindControl.findMindControlTarget((EntityLiving)target, caster, world)){
// If no valid target was found, this just acts like mind trick.
((EntityLiving)target).setAttackTarget(null);
}
NBTTagCompound entityNBT = target.getEntityData();
if(entityNBT != null) entityNBT.setUniqueId(NBT_KEY, caster.getUniqueID());
((EntityLiving)target).addPotionEffect(new PotionEffect(WizardryPotions.mind_control,
(int)(600 * modifiers.get(WizardryItems.duration_upgrade)), 0));
(int)(BASE_DURATION * modifiers.get(WizardryItems.duration_upgrade)), 0));
}
}else{
for(int i = 0; i < 10; i++){
Wizardry.proxy.spawnParticle(Type.DARK_MAGIC, world,
target.posX - 0.25 + world.rand.nextDouble() * 0.5,
target.getEntityBoundingBox().minY + target.getEyeHeight() - 0.25
+ world.rand.nextDouble() * 0.5,
target.posZ - 0.25 + world.rand.nextDouble() * 0.5, 0, 0, 0, 0, 0.8f, 0.2f, 1.0f);
Wizardry.proxy.spawnParticle(Type.DARK_MAGIC, world,
target.posX - 0.25 + world.rand.nextDouble() * 0.5,
target.getEntityBoundingBox().minY + target.getEyeHeight() - 0.25
+ world.rand.nextDouble() * 0.5,
target.posZ - 0.25 + world.rand.nextDouble() * 0.5, 0, 0, 0, 0, 0.2f, 0.04f, 0.25f);
for(int i=0; i<10; i++){
ParticleBuilder.create(Type.DARK_MAGIC, world.rand, target.posX,
target.getEntityBoundingBox().minY + target.getEyeHeight(), target.posZ, 0.25, false)
.colour(0.8f, 0.2f, 1.0f).spawn(world);
ParticleBuilder.create(Type.DARK_MAGIC, world.rand, target.posX,
target.getEntityBoundingBox().minY + target.getEyeHeight(), target.posZ, 0.25, false)
.colour(0.2f, 0.04f, 0.25f).spawn(world);
}
}
target.playSound(WizardrySounds.SPELL_SUMMONING, 1.0f, 1.0f);
caster.swingArm(hand);
return true;
}
return false;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
if(!world.isRemote){
if(canControl(target)){
if(!MindControl.findMindControlTarget((EntityLiving)target, caster, world)){
// If no valid target was found, this just acts like mind trick.
((EntityLiving)target).setAttackTarget(null);
}
NBTTagCompound entityNBT = target.getEntityData();
if(entityNBT != null) entityNBT.setUniqueId(NBT_KEY, caster.getUniqueID());
((EntityLiving)target).addPotionEffect(new PotionEffect(WizardryPotions.mind_control,
(int)(600 * modifiers.get(WizardryItems.duration_upgrade)), 0));
}
}else{
for(int i = 0; i < 10; i++){
Wizardry.proxy.spawnParticle(Type.DARK_MAGIC, world,
target.posX - 0.25 + world.rand.nextDouble() * 0.5,
target.getEntityBoundingBox().minY + target.getEyeHeight() - 0.25
+ world.rand.nextDouble() * 0.5,
target.posZ - 0.25 + world.rand.nextDouble() * 0.5, 0, 0, 0, 0, 0.8f, 0.2f, 1.0f);
Wizardry.proxy.spawnParticle(Type.DARK_MAGIC, world,
target.posX - 0.25 + world.rand.nextDouble() * 0.5,
target.getEntityBoundingBox().minY + target.getEyeHeight() - 0.25
+ world.rand.nextDouble() * 0.5,
target.posZ - 0.25 + world.rand.nextDouble() * 0.5, 0, 0, 0, 0, 0.2f, 0.04f, 0.25f);
}
}
target.playSound(WizardrySounds.SPELL_SUMMONING, 1.0f, 1.0f);
caster.swingArm(hand);
return true;
}
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
/** Returns true if the given entity can be mind controlled (i.e. is not a player, npc, evil wizard or boss). */
public static boolean canControl(EntityLivingBase target){
public static boolean canControl(Entity target){
return target instanceof EntityLiving && target.isNonBoss() && !(target instanceof INpc)
&& !(target instanceof EntityEvilWizard) && !Arrays.asList(Wizardry.settings.mindControlTargetsBlacklist)
.contains(EntityList.getKey(target.getClass()));
@@ -1,23 +1,23 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardryPotions;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.MobEffects;
import net.minecraft.item.EnumAction;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.event.entity.living.LivingAttackEvent;
import net.minecraftforge.event.entity.living.LivingSetAttackTargetEvent;
@@ -25,90 +25,56 @@ import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
@Mod.EventBusSubscriber
public class MindTrick extends Spell {
public class MindTrick extends SpellRay {
private static final int BASE_DURATION = 300;
public MindTrick(){
super(Tier.BASIC, 10, Element.NECROMANCY, "mind_trick", SpellType.ATTACK, 40, EnumAction.NONE, false);
super("mind_trick", Tier.BASIC, Element.NECROMANCY, SpellType.ATTACK, 10, 40, false, 8, WizardrySounds.SPELL_DEFLECTION);
this.soundValues(0.7f, 1, 0.4f);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster,
8 * modifiers.get(WizardryItems.range_upgrade));
if(rayTrace != null && rayTrace.entityHit != null && WizardryUtilities.isLiving(rayTrace.entityHit)){
EntityLivingBase target = (EntityLivingBase)rayTrace.entityHit;
protected boolean onEntityHit(World world, Entity target, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
if(WizardryUtilities.isLiving(target)){
if(!world.isRemote){
if(target instanceof EntityPlayer){
target.addPotionEffect(new PotionEffect(MobEffects.NAUSEA,
(int)(300 * modifiers.get(WizardryItems.duration_upgrade)), 0));
((EntityLivingBase)target).addPotionEffect(new PotionEffect(MobEffects.NAUSEA,
(int)(BASE_DURATION * modifiers.get(WizardryItems.duration_upgrade)), 0));
}else if(target instanceof EntityLiving){
((EntityLiving)target).setAttackTarget(null);
target.addPotionEffect(new PotionEffect(WizardryPotions.mind_trick,
(int)(300 * modifiers.get(WizardryItems.duration_upgrade)), 0));
((EntityLivingBase)target).addPotionEffect(new PotionEffect(WizardryPotions.mind_trick,
(int)(BASE_DURATION * modifiers.get(WizardryItems.duration_upgrade)), 0));
}
}else{
for(int i = 0; i < 10; i++){
Wizardry.proxy.spawnParticle(Type.DARK_MAGIC, world,
target.posX - 0.25 + world.rand.nextDouble() * 0.5,
target.getEntityBoundingBox().minY + target.getEyeHeight() - 0.25
+ world.rand.nextDouble() * 0.5,
target.posZ - 0.25 + world.rand.nextDouble() * 0.5, 0, 0, 0, 0, 0.8f, 0.2f, 1.0f);
for(int i=0; i<10; i++){
ParticleBuilder.create(Type.DARK_MAGIC, world.rand, target.posX,
target.getEntityBoundingBox().minY + target.getEyeHeight(), target.posZ, 0.25, false)
.colour(0.8f, 0.2f, 1.0f).spawn(world);
}
}
target.playSound(WizardrySounds.SPELL_DEFLECTION, 0.7F, world.rand.nextFloat() * 0.4F + 0.8F);
caster.swingArm(hand);
return true;
}
return false;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
if(!world.isRemote){
if(target instanceof EntityPlayer){
target.addPotionEffect(new PotionEffect(MobEffects.NAUSEA,
(int)(300 * modifiers.get(WizardryItems.duration_upgrade)), 0));
}else if(target instanceof EntityLiving){
((EntityLiving)target).setAttackTarget(null);
target.addPotionEffect(new PotionEffect(WizardryPotions.mind_trick,
(int)(300 * modifiers.get(WizardryItems.duration_upgrade)), 0));
}
}else{
for(int i = 0; i < 10; i++){
Wizardry.proxy.spawnParticle(Type.DARK_MAGIC, world,
target.posX - 0.25 + world.rand.nextDouble() * 0.5,
target.getEntityBoundingBox().minY + target.getEyeHeight() - 0.25
+ world.rand.nextDouble() * 0.5,
target.posZ - 0.25 + world.rand.nextDouble() * 0.5, 0, 0, 0, 0, 0.8f, 0.2f, 1.0f);
}
}
target.playSound(WizardrySounds.SPELL_DEFLECTION, 0.7F, world.rand.nextFloat() * 0.4F + 0.8F);
caster.swingArm(hand);
return true;
}
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@SubscribeEvent
@@ -12,12 +12,12 @@ import net.minecraft.world.World;
/**
* This class represents a blank spell used to fill empty slots on wands. It is unobtainable in-game, except via
* commands, and does nothing when the player attempts to cast it. Its instance can be referenced directly using
* {@link electroblob.wizardry.registry.Spells#none WizardryRegistry.none}
* {@link electroblob.wizardry.registry.Spells#none Spells.none}
*/
public class None extends Spell {
public None(){
super(Tier.BASIC, 0, Element.MAGIC, "none", SpellType.UTILITY, 0, EnumAction.NONE, false);
super("none", Tier.BASIC, Element.MAGIC, SpellType.UTILITY, 0, 0, EnumAction.NONE, false);
}
@Override
@@ -1,79 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.MobEffects;
import net.minecraft.item.EnumAction;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class Oakflesh extends Spell {
public Oakflesh(){
super(Tier.APPRENTICE, 20, Element.HEALING, "oakflesh", SpellType.DEFENCE, 50, EnumAction.BOW, false);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
caster.addPotionEffect(new PotionEffect(MobEffects.RESISTANCE,
(int)(600 * modifiers.get(WizardryItems.duration_upgrade)), 1, false, false));
if(world.isRemote){
for(int i = 0; i < 10; i++){
double x1 = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat());
double z1 = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0,
48 + world.rand.nextInt(12), 0.6f, 0.5f, 0.4f);
}
}
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F,
world.rand.nextFloat() * 0.4F + 1.0F);
return true;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(!caster.isPotionActive(MobEffects.RESISTANCE)){
caster.addPotionEffect(new PotionEffect(MobEffects.RESISTANCE,
(int)(600 * modifiers.get(WizardryItems.duration_upgrade)), 1, false, false));
if(world.isRemote){
for(int i = 0; i < 10; i++){
double x1 = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
double y1 = (double)((float)caster.posY + caster.getEyeHeight() - 0.5F + world.rand.nextFloat());
double z1 = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0,
48 + world.rand.nextInt(12), 0.6f, 0.5f, 0.4f);
}
}
caster.playSound(WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F);
return true;
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
}
}
@@ -1,126 +1,60 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.block.BlockStatue;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardryBlocks;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.tileentity.TileEntityStatue;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.WizardryUtilities;
import electroblob.wizardry.util.SpellModifiers;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
public class Petrify extends Spell {
public class Petrify extends SpellRay {
private static final int baseDuration = 900;
/**
* The NBT tag name for storing the petrified flag in the target's tag compound. Defined here in case it changes.
*/
public static final String NBT_KEY = "petrified";
private static final int BASE_DURATION = 900;
public Petrify(){
super(Tier.ADVANCED, 40, Element.SORCERY, "petrify", SpellType.ATTACK, 100, EnumAction.NONE, false);
super("petrify", Tier.ADVANCED, Element.SORCERY, SpellType.ATTACK, 40, 100, false, 10, SoundEvents.ENTITY_WITHER_SPAWN);
this.soundValues(1, 1.1f, 0.2f);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
Vec3d look = caster.getLookVec();
RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster,
10 * modifiers.get(WizardryItems.range_upgrade));
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY
&& rayTrace.entityHit instanceof EntityLiving && !world.isRemote){
EntityLiving target = (EntityLiving)rayTrace.entityHit;
if(target.deathTime > 0) return false;
BlockPos pos = new BlockPos(target);
target.extinguish();
// Short mobs such as spiders and pigs
if((target.height < 1.2 || target.isChild()) && WizardryUtilities.canBlockBeReplaced(world, pos)){
world.setBlockState(pos, WizardryBlocks.petrified_stone.getDefaultState());
if(world.getTileEntity(pos) instanceof TileEntityStatue){
((TileEntityStatue)world.getTileEntity(pos)).setCreatureAndPart(target, 1, 1);
((TileEntityStatue)world.getTileEntity(pos))
.setLifetime((int)(baseDuration * modifiers.get(WizardryItems.duration_upgrade)));
}
target.getEntityData().setBoolean(NBT_KEY, true);
target.setDead();
}
// Normal sized mobs like zombies and skeletons
else if(target.height < 2.5 && WizardryUtilities.canBlockBeReplaced(world, pos)
&& WizardryUtilities.canBlockBeReplaced(world, pos.up())){
world.setBlockState(pos, WizardryBlocks.petrified_stone.getDefaultState());
if(world.getTileEntity(pos) instanceof TileEntityStatue){
((TileEntityStatue)world.getTileEntity(pos)).setCreatureAndPart(target, 1, 2);
((TileEntityStatue)world.getTileEntity(pos))
.setLifetime((int)(baseDuration * modifiers.get(WizardryItems.duration_upgrade)));
}
world.setBlockState(pos.up(), WizardryBlocks.petrified_stone.getDefaultState());
if(world.getTileEntity(pos.up()) instanceof TileEntityStatue){
((TileEntityStatue)world.getTileEntity(pos.up())).setCreatureAndPart(target, 2, 2);
}
target.getEntityData().setBoolean(NBT_KEY, true);
target.setDead();
}
// Tall mobs like endermen
else if(WizardryUtilities.canBlockBeReplaced(world, pos)
&& WizardryUtilities.canBlockBeReplaced(world, pos.up())
&& WizardryUtilities.canBlockBeReplaced(world, pos.up(2))){
world.setBlockState(pos, WizardryBlocks.petrified_stone.getDefaultState());
if(world.getTileEntity(pos) instanceof TileEntityStatue){
((TileEntityStatue)world.getTileEntity(pos)).setCreatureAndPart(target, 1, 3);
((TileEntityStatue)world.getTileEntity(pos))
.setLifetime((int)(baseDuration * modifiers.get(WizardryItems.duration_upgrade)));
}
world.setBlockState(pos.up(), WizardryBlocks.petrified_stone.getDefaultState());
if(world.getTileEntity(pos.up()) instanceof TileEntityStatue){
((TileEntityStatue)world.getTileEntity(pos.up())).setCreatureAndPart(target, 2, 3);
}
world.setBlockState(pos.up(2), WizardryBlocks.petrified_stone.getDefaultState());
if(world.getTileEntity(pos.up(2)) instanceof TileEntityStatue){
((TileEntityStatue)world.getTileEntity(pos.up(2))).setCreatureAndPart(target, 3, 3);
}
target.getEntityData().setBoolean(NBT_KEY, true);
target.setDead();
protected boolean onEntityHit(World world, Entity target, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
if(target instanceof EntityLiving && !world.isRemote){
// Unchecked cast is fine because the block is a static final field
if(((BlockStatue)WizardryBlocks.petrified_stone).convertToStatue((EntityLiving)target,
(int)(BASE_DURATION * modifiers.get(WizardryItems.duration_upgrade)))){
return true;
}
}
if(world.isRemote){
for(int i = 1; i < (int)(25 * modifiers.get(WizardryItems.range_upgrade)); i += 2){
// I figured it out! when on client side, entityplayer.posY is at the eyes, not the feet!
double x1 = caster.posX + look.x * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
double y1 = WizardryUtilities.getPlayerEyesPos(caster) - 0.4f + look.y * i / 2
+ world.rand.nextFloat() / 5 - 0.1f;
double z1 = caster.posZ + look.z * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
// world.spawnParticle("mobSpell", x1, y1, z1, -1*look.xCoord, -1*look.yCoord, -1*look.zCoord);
Wizardry.proxy.spawnParticle(Type.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0,
0.1f, 0.1f, 0.1f);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d,
12 + world.rand.nextInt(8), 0.2f, 0.2f, 0.2f);
}
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_WITHER_SPAWN, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F);
return false;
}
@Override
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@Override
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return true;
}
@Override
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).lifetime(12 + world.rand.nextInt(8)).colour(0.2f, 0.2f, 0.2f).spawn(world);
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).colour(0.1f, 0.1f, 0.1f).spawn(world);
}
}
@@ -20,7 +20,7 @@ import net.minecraft.world.World;
public class PhaseStep extends Spell {
public PhaseStep(){
super(Tier.ADVANCED, 35, Element.SORCERY, "phase_step", SpellType.UTILITY, 40, EnumAction.NONE, false);
super("phase_step", Tier.ADVANCED, Element.SORCERY, SpellType.UTILITY, 35, 40, EnumAction.NONE, false);
}
@Override
@@ -28,7 +28,7 @@ public class PhaseStep extends Spell {
// Phase step does not gain range from range multiplier, instead it increases the thickness
// of the wall you can teleport through.
RayTraceResult rayTrace = WizardryUtilities.rayTrace(5, world, caster, false);
RayTraceResult rayTrace = WizardryUtilities.standardBlockRayTrace(world, caster, 5, false);
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){
@@ -71,7 +71,7 @@ public class PhaseStep extends Spell {
if(world.isRemote){
for(int i = 0; i < 10; i++){
double dx1 = caster.posX;
double dy1 = WizardryUtilities.getPlayerEyesPos(caster) - 1.5 + 2 * world.rand.nextFloat();
double dy1 = caster.getEntityBoundingBox().minY + 2 * world.rand.nextFloat();
double dz1 = caster.posZ;
world.spawnParticle(EnumParticleTypes.PORTAL, dx1, dy1, dz1, world.rand.nextDouble() - 0.5,
world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5);
@@ -2,15 +2,15 @@ package electroblob.wizardry.spell;
import java.util.List;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
@@ -25,42 +25,48 @@ import net.minecraft.util.EnumParticleTypes;
import net.minecraft.world.World;
public class PlagueOfDarkness extends Spell {
private static final double BASE_RADIUS = 5;
private static final float BASE_DAMAGE = 8;
private static final int BASE_DURATION = 140;
public PlagueOfDarkness(){
super(Tier.MASTER, 75, Element.NECROMANCY, "plague_of_darkness", SpellType.ATTACK, 200, EnumAction.BOW, false);
super("plague_of_darkness", Tier.MASTER, Element.NECROMANCY, SpellType.ATTACK, 75, 200, EnumAction.BOW, false);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
List<EntityLivingBase> targets = WizardryUtilities.getEntitiesWithinRadius(
5.0d * modifiers.get(WizardryItems.blast_upgrade), caster.posX, caster.posY, caster.posZ, world);
BASE_RADIUS * modifiers.get(WizardryItems.blast_upgrade), caster.posX, caster.posY, caster.posZ, world);
for(EntityLivingBase target : targets){
if(WizardryUtilities.isValidTarget(caster, target)
&& !MagicDamage.isEntityImmune(DamageType.WITHER, target)){
target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.WITHER),
8.0f * modifiers.get(SpellModifiers.DAMAGE));
BASE_DAMAGE * modifiers.get(SpellModifiers.POTENCY));
target.addPotionEffect(new PotionEffect(MobEffects.WITHER,
(int)(140 * modifiers.get(WizardryItems.duration_upgrade)), 2));
(int)(BASE_DURATION * modifiers.get(WizardryItems.duration_upgrade)), 2));
}
}
if(world.isRemote){
double particleX, particleZ;
for(int i = 0; i < 40 * modifiers.get(WizardryItems.blast_upgrade); i++){
particleX = caster.posX - 1.0d + 2 * world.rand.nextDouble();
particleZ = caster.posZ - 1.0d + 2 * world.rand.nextDouble();
Wizardry.proxy.spawnParticle(Type.DARK_MAGIC, world, particleX,
WizardryUtilities.getPlayerEyesPos(caster) - 1.5, particleZ, particleX - caster.posX, 0,
particleZ - caster.posZ, 0, 0.1f, 0.0f, 0.0f);
ParticleBuilder.create(Type.DARK_MAGIC).pos(particleX, caster.getEntityBoundingBox().minY, particleZ)
.vel(particleX - caster.posX, 0, particleZ - caster.posZ).colour(0.1f, 0, 0).spawn(world);
particleX = caster.posX - 1.0d + 2 * world.rand.nextDouble();
particleZ = caster.posZ - 1.0d + 2 * world.rand.nextDouble();
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, particleX,
WizardryUtilities.getPlayerEyesPos(caster) - 1.5, particleZ, particleX - caster.posX, 0,
particleZ - caster.posZ, 30, 0.1f, 0.0f, 0.05f);
ParticleBuilder.create(Type.SPARKLE).pos(particleX, caster.getEntityBoundingBox().minY, particleZ)
.vel(particleX - caster.posX, 0, particleZ - caster.posZ).lifetime(30).colour(0.1f, 0, 0.05f).spawn(world);
particleX = caster.posX - 1.0d + 2 * world.rand.nextDouble();
particleZ = caster.posZ - 1.0d + 2 * world.rand.nextDouble();
IBlockState block = WizardryUtilities.getBlockEntityIsStandingOn(caster);
if(block != null){
@@ -69,9 +75,9 @@ public class PlagueOfDarkness extends Spell {
}
}
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_WITHER_DEATH, 1.0F,
world.rand.nextFloat() * 0.2F + 1.0F);
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_WITHER_DEATH, 1, 1 + 0.2f * world.rand.nextFloat());
return true;
}
@@ -17,7 +17,7 @@ import net.minecraft.world.World;
public class PocketFurnace extends Spell {
public PocketFurnace(){
super(Tier.APPRENTICE, 30, Element.FIRE, "pocket_furnace", SpellType.UTILITY, 40, EnumAction.BOW, false);
super("pocket_furnace", Tier.APPRENTICE, Element.FIRE, SpellType.UTILITY, 30, 40, EnumAction.BOW, false);
}
@Override
@@ -60,7 +60,7 @@ public class PocketFurnace extends Spell {
if(world.isRemote){
for(int i = 0; i < 10; i++){
double x1 = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat());
double y1 = (double)((float)caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5F + world.rand.nextFloat());
double z1 = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
world.spawnParticle(EnumParticleTypes.FLAME, x1, y1, z1, 0, 0.01F, 0);
}
@@ -16,7 +16,7 @@ import net.minecraft.world.World;
public class PocketWorkbench extends Spell {
public PocketWorkbench(){
super(Tier.APPRENTICE, 30, Element.SORCERY, "pocket_workbench", SpellType.UTILITY, 40, EnumAction.BOW, false);
super("pocket_workbench", Tier.APPRENTICE, Element.SORCERY, SpellType.UTILITY, 30, 40, EnumAction.BOW, false);
}
@Override
@@ -1,6 +1,5 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
@@ -8,110 +7,26 @@ import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.MobEffects;
import net.minecraft.item.EnumAction;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.World;
public class Poison extends Spell {
public class Poison extends SpellRay {
private static final int BASE_DURATION = 200;
public Poison(){
super(Tier.APPRENTICE, 10, Element.EARTH, "poison", SpellType.ATTACK, 20, EnumAction.NONE, false);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
Vec3d look = caster.getLookVec();
RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster,
10 * modifiers.get(WizardryItems.range_upgrade));
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY && WizardryUtilities.isLiving(rayTrace.entityHit)){
EntityLivingBase target = (EntityLivingBase)rayTrace.entityHit;
// Has no effect on undead or spiders.
if(MagicDamage.isEntityImmune(DamageType.POISON, target)){
if(!world.isRemote) caster.sendMessage(new TextComponentTranslation("spell.resist", target.getName(),
this.getNameForTranslationFormatted()));
}else{
target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.POISON),
1.0f * modifiers.get(SpellModifiers.DAMAGE));
target.addPotionEffect(new PotionEffect(MobEffects.POISON,
(int)(200 * modifiers.get(WizardryItems.duration_upgrade)), 1));
}
}
if(world.isRemote){
for(int i = 1; i < (int)(25 * modifiers.get(WizardryItems.range_upgrade)); i += 2){
// I figured it out! when on client side, entityplayer.posY is at the eyes, not the feet!
double x1 = caster.posX + look.x * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
double y1 = WizardryUtilities.getPlayerEyesPos(caster) - 0.4f + look.y * i / 2
+ world.rand.nextFloat() / 5 - 0.1f;
double z1 = caster.posZ + look.z * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
// world.spawnParticle("mobSpell", x1, y1, z1, -1*look.xCoord, -1*look.yCoord, -1*look.zCoord);
Wizardry.proxy.spawnParticle(Type.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0,
0.3f, 0.7f, 0.0f);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d,
12 + world.rand.nextInt(8), 0.1f, 0.4f, 0.0f);
}
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 1.0F,
world.rand.nextFloat() * 0.2F + 1.0F);
return true;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
// Has no effect on undead or spiders.
if(!MagicDamage.isEntityImmune(DamageType.POISON, target) && !world.isRemote){
target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.POISON),
1.0f * modifiers.get(SpellModifiers.DAMAGE));
target.addPotionEffect(new PotionEffect(MobEffects.POISON,
(int)(200 * modifiers.get(WizardryItems.duration_upgrade)), 1));
}
if(world.isRemote){
double dx = (target.posX - caster.posX) / caster.getDistance(target);
double dy = (target.posY - caster.posY) / caster.getDistance(target);
double dz = (target.posZ - caster.posZ) / caster.getDistance(target);
for(int i = 1; i < (int)(25 * modifiers.get(WizardryItems.range_upgrade)); i += 2){
double x1 = caster.posX + dx * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
double y1 = caster.posY + caster.getEyeHeight() - 0.4f + dy * i / 2 + world.rand.nextFloat() / 5
- 0.1f;
double z1 = caster.posZ + dz * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
Wizardry.proxy.spawnParticle(Type.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d,
0, 0.3f, 0.7f, 0.0f);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d,
12 + world.rand.nextInt(8), 0.1f, 0.4f, 0.0f);
}
}
caster.swingArm(hand);
caster.playSound(WizardrySounds.SPELL_ICE, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F);
return true;
}
return false;
super("poison", Tier.APPRENTICE, Element.EARTH, SpellType.ATTACK, 10, 20, false, 10, WizardrySounds.SPELL_ICE);
this.soundValues(1, 1.1f, 0.2f);
}
@Override
@@ -119,4 +34,42 @@ public class Poison extends Spell {
return true;
}
@Override
protected boolean onEntityHit(World world, Entity target, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
if(WizardryUtilities.isLiving(target)){
// Has no effect on undead or spiders.
if(MagicDamage.isEntityImmune(DamageType.POISON, target)){
if(!world.isRemote) caster.sendMessage(new TextComponentTranslation("spell.resist", target.getName(),
this.getNameForTranslationFormatted()));
}else{
target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.POISON),
1 * modifiers.get(SpellModifiers.POTENCY));
((EntityLivingBase)target).addPotionEffect(new PotionEffect(MobEffects.POISON,
(int)(BASE_DURATION * modifiers.get(WizardryItems.duration_upgrade)), 1));
}
return true;
}
return false;
}
@Override
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return false;
}
@Override
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
return true;
}
@Override
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).colour(0.3f, 0.7f, 0).spawn(world);
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).lifetime(12 + world.rand.nextInt(8)).colour(0.1f, 0.4f, 0).spawn(world);
}
}
@@ -1,70 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.projectile.EntityPoisonBomb;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class PoisonBomb extends Spell {
public PoisonBomb(){
super(Tier.APPRENTICE, 15, Element.EARTH, "poison_bomb", SpellType.ATTACK, 25, EnumAction.NONE, false);
}
@Override
public boolean doesSpellRequirePacket(){
return false;
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
if(!world.isRemote){
EntityPoisonBomb poisonbomb = new EntityPoisonBomb(world, caster, modifiers.get(SpellModifiers.DAMAGE),
modifiers.get(WizardryItems.blast_upgrade));
world.spawnEntity(poisonbomb);
}
caster.swingArm(hand);
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_SNOWBALL_THROW, 0.5F,
0.4F / (world.rand.nextFloat() * 0.4F + 0.8F));
return true;
}
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
SpellModifiers modifiers){
if(target != null){
if(!world.isRemote){
EntityPoisonBomb poisonbomb = new EntityPoisonBomb(world, caster, modifiers.get(SpellModifiers.DAMAGE),
modifiers.get(WizardryItems.blast_upgrade));
poisonbomb.directTowards(target, 1.5f);
world.spawnEntity(poisonbomb);
}
caster.swingArm(hand);
caster.playSound(SoundEvents.ENTITY_SNOWBALL_THROW, 0.5F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F));
return true;
}
return false;
}
@Override
public boolean canBeCastByNPCs(){
return true;
}
}
@@ -1,45 +1,39 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class ReplenishHunger extends Spell {
public class ReplenishHunger extends SpellBuff {
public ReplenishHunger(){
super(Tier.APPRENTICE, 10, Element.HEALING, "replenish_hunger", SpellType.UTILITY, 30, EnumAction.BOW, false);
super("replenish_hunger", Tier.APPRENTICE, Element.HEALING, SpellType.BUFF, 10, 30, WizardrySounds.SPELL_HEAL, 1, 0.7f, 0.3f);
this.soundValues(0.7f, 1.2f, 0.4f);
}
@Override public boolean canBeCastByNPCs(){ return false; }
@Override
protected boolean applyEffects(EntityLivingBase caster, SpellModifiers modifiers){
return true; // In this case the best solution is to remove the functionality of this method and override cast.
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
if(caster.getFoodStats().needFood()){
int foodAmount = (int)(6 * modifiers.get(SpellModifiers.DAMAGE));
int foodAmount = (int)(4 * modifiers.get(SpellModifiers.POTENCY));
// Fixed issue #6: Changed to addStats, since setFoodLevel is client-side only
caster.getFoodStats().addStats(foodAmount, foodAmount * 0.1f);
if(world.isRemote){
for(int i = 0; i < 10; i++){
double x1 = (double)((float)caster.posX + world.rand.nextFloat() * 2 - 1.0F);
double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F
+ world.rand.nextFloat());
double z1 = (double)((float)caster.posZ + world.rand.nextFloat() * 2 - 1.0F);
Wizardry.proxy.spawnParticle(Type.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0,
48 + world.rand.nextInt(12), 1.0f, 0.7f, 0.3f);
}
}
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F,
world.rand.nextFloat() * 0.4F + 1.0F);
return true;
return super.cast(world, caster, hand, ticksInUse, modifiers);
}
return false;
}

Some files were not shown because too many files have changed in this diff Show More