Some bomb fixes, colored spell book overlay are now separate files
@@ -179,6 +179,8 @@ public class CommonProxy {
|
|||||||
|
|
||||||
public void handleConquerShrinePacket(PacketConquerShrine.Message message){}
|
public void handleConquerShrinePacket(PacketConquerShrine.Message message){}
|
||||||
|
|
||||||
|
public void handleBombExplosionPacket(PacketBombExplosion.Message message){}
|
||||||
|
|
||||||
// SECTION Misc
|
// SECTION Misc
|
||||||
// ===============================================================================================================
|
// ===============================================================================================================
|
||||||
|
|
||||||
|
|||||||
@@ -717,6 +717,65 @@ public class ClientProxy extends CommonProxy {
|
|||||||
}else Wizardry.logger.warn("Received a PacketConquerShrine, but there was no shrine core at the position sent");
|
}else Wizardry.logger.warn("Received a PacketConquerShrine, but there was no shrine core at the position sent");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleBombExplosionPacket(PacketBombExplosion.Message message){
|
||||||
|
|
||||||
|
net.minecraft.world.World world = Minecraft.getMinecraft().world;
|
||||||
|
double x = message.x, y = message.y, z = message.z;
|
||||||
|
float blastMultiplier = message.blastMultiplier;
|
||||||
|
|
||||||
|
switch(message.bombType){
|
||||||
|
|
||||||
|
case PacketBombExplosion.FIREBOMB:
|
||||||
|
ParticleBuilder.create(Type.FLASH).pos(x, y, z).scale(5 * blastMultiplier).clr(1, 0.6f, 0).spawn(world);
|
||||||
|
for(int i = 0; i < 60 * blastMultiplier; i++){
|
||||||
|
ParticleBuilder.create(Type.MAGIC_FIRE, world.rand, x, y, z, 2 * blastMultiplier, false)
|
||||||
|
.time(10 + world.rand.nextInt(4)).scale(2 + world.rand.nextFloat()).spawn(world);
|
||||||
|
ParticleBuilder.create(Type.DARK_MAGIC, world.rand, x, y, z, 2 * blastMultiplier, false)
|
||||||
|
.clr(1.0f, 0.2f + world.rand.nextFloat() * 0.4f, 0.0f).spawn(world);
|
||||||
|
}
|
||||||
|
world.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, x, y, z, 0, 0, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PacketBombExplosion.POISON_BOMB:
|
||||||
|
ParticleBuilder.create(Type.FLASH).pos(x, y, z).scale(5 * blastMultiplier)
|
||||||
|
.clr(0.2f + world.rand.nextFloat() * 0.3f, 0.6f, 0.0f).spawn(world);
|
||||||
|
for(int i = 0; i < 60 * blastMultiplier; i++){
|
||||||
|
ParticleBuilder.create(Type.SPARKLE, world.rand, x, y, z, 2 * blastMultiplier, false).time(35)
|
||||||
|
.scale(2).clr(0.2f + world.rand.nextFloat() * 0.3f, 0.6f, 0.0f).spawn(world);
|
||||||
|
ParticleBuilder.create(Type.DARK_MAGIC, world.rand, x, y, z, 2 * blastMultiplier, false)
|
||||||
|
.clr(0.2f + world.rand.nextFloat() * 0.2f, 0.8f, 0.0f).spawn(world);
|
||||||
|
}
|
||||||
|
world.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, x, y, z, 0, 0, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PacketBombExplosion.SMOKE_BOMB:
|
||||||
|
ParticleBuilder.create(Type.FLASH).pos(x, y, z).scale(5 * blastMultiplier).clr(0, 0, 0).spawn(world);
|
||||||
|
world.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, x, y, z, 0, 0, 0);
|
||||||
|
for(int i = 0; i < 60 * blastMultiplier; i++){
|
||||||
|
float brightness = world.rand.nextFloat() * 0.1f + 0.1f;
|
||||||
|
ParticleBuilder.create(Type.CLOUD, world.rand, x, y, z, 2 * blastMultiplier, false)
|
||||||
|
.clr(brightness, brightness, brightness).time(80 + world.rand.nextInt(12)).shaded(true).spawn(world);
|
||||||
|
brightness = world.rand.nextFloat() * 0.3f;
|
||||||
|
ParticleBuilder.create(Type.DARK_MAGIC, world.rand, x, y, z, 2 * blastMultiplier, false)
|
||||||
|
.clr(brightness, brightness, brightness).spawn(world);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PacketBombExplosion.SPARK_BOMB:
|
||||||
|
ParticleBuilder.spawnShockParticles(world, x, y, z);
|
||||||
|
for(int id : message.secondaryTargetIDs){
|
||||||
|
net.minecraft.entity.Entity target = world.getEntityByID(id);
|
||||||
|
if(target instanceof net.minecraft.entity.EntityLivingBase){
|
||||||
|
ParticleBuilder.create(Type.LIGHTNING).pos(x, y, z).target(target).spawn(world);
|
||||||
|
ParticleBuilder.spawnShockParticles(world, target.posX,
|
||||||
|
target.posY + target.height / 2, target.posZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Rendering
|
// Rendering
|
||||||
// ===============================================================================================================
|
// ===============================================================================================================
|
||||||
|
|
||||||
@@ -881,48 +940,13 @@ public class ClientProxy extends CommonProxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void registerItemColorHandlers() {
|
public void registerItemColorHandlers() {
|
||||||
Minecraft.getMinecraft().getItemColors().registerItemColorHandler((stack, tintIndex) -> {
|
// Spell book overlay textures are now per-element, so no runtime tinting is needed.
|
||||||
if (Wizardry.settings.spellBookColors && tintIndex == 1) { // layer 1 is the overlay
|
|
||||||
Spell spell = Spell.byMetadata(stack.getMetadata());
|
|
||||||
|
|
||||||
if (shouldDisplayDiscovered(spell, stack)) {
|
|
||||||
// Even if the spell is discovered, the charm might be required for colouration
|
|
||||||
if(Wizardry.settings.spellBookColorsRequireArchivistsEyeglass && !ItemArtefact.isArtefactActive(getThePlayer(), WizardryItems.charm_spell_discovery)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Element element = spell.getElement();
|
|
||||||
if (element != null) {
|
|
||||||
switch (element) {
|
|
||||||
case MAGIC:
|
|
||||||
return 0xAAAAAA; // GRAY
|
|
||||||
case FIRE:
|
|
||||||
return 0xAA0000; // DARK_RED
|
|
||||||
case ICE:
|
|
||||||
return 0x55FFFF; // AQUA
|
|
||||||
case LIGHTNING:
|
|
||||||
return 0x00AAAA; // DARK_AQUA
|
|
||||||
case NECROMANCY:
|
|
||||||
return 0xAA00AA; // DARK_PURPLE
|
|
||||||
case EARTH:
|
|
||||||
return 0x00AA00; // DARK_GREEN
|
|
||||||
case SORCERY:
|
|
||||||
return 0x55FF55; // GREEN
|
|
||||||
case HEALING:
|
|
||||||
return 0xFFFF55; // YELLOW
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}, WizardryItems.spell_book);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerModelProperties() {
|
public void registerModelProperties() {
|
||||||
Item spellBook = WizardryItems.spell_book;
|
Item spellBook = WizardryItems.spell_book;
|
||||||
ResourceLocation discoveredProperty = new ResourceLocation(Wizardry.MODID, "discovered");
|
|
||||||
|
|
||||||
spellBook.addPropertyOverride(discoveredProperty, (stack, world, entity) -> {
|
spellBook.addPropertyOverride(new ResourceLocation(Wizardry.MODID, "discovered"), (stack, world, entity) -> {
|
||||||
if (!Wizardry.settings.spellBookColors) return 0.0f;
|
if (!Wizardry.settings.spellBookColors) return 0.0f;
|
||||||
|
|
||||||
boolean discovered = shouldDisplayDiscovered(Spell.byMetadata(stack.getMetadata()), stack);
|
boolean discovered = shouldDisplayDiscovered(Spell.byMetadata(stack.getMetadata()), stack);
|
||||||
@@ -938,5 +962,27 @@ public class ClientProxy extends CommonProxy {
|
|||||||
|
|
||||||
return discovered ? 1.0f : 0.0f;
|
return discovered ? 1.0f : 0.0f;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Returns ordinal+1 for each element (1=MAGIC through 8=HEALING), or 0 if not yet discovered.
|
||||||
|
// Drives per-element bookmark texture selection via model overrides in spell_book.json.
|
||||||
|
spellBook.addPropertyOverride(new ResourceLocation(Wizardry.MODID, "element"), (stack, world, entity) -> {
|
||||||
|
if (!Wizardry.settings.spellBookColors) return 0.0f;
|
||||||
|
|
||||||
|
Spell spell = Spell.byMetadata(stack.getMetadata());
|
||||||
|
boolean discovered = shouldDisplayDiscovered(spell, stack);
|
||||||
|
|
||||||
|
if(!discovered) return 0.0f;
|
||||||
|
|
||||||
|
if(Wizardry.settings.spellBookColorsRequireArchivistsEyeglass){
|
||||||
|
if(entity instanceof EntityPlayer){
|
||||||
|
if(!ItemArtefact.isArtefactActive((EntityPlayer)entity, WizardryItems.charm_spell_discovery)) return 0.0f;
|
||||||
|
} else {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Element element = spell.getElement();
|
||||||
|
return element == null ? 0.0f : (float)(element.ordinal() + 1);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,18 +1,18 @@
|
|||||||
package electroblob.wizardry.entity.projectile;
|
package electroblob.wizardry.entity.projectile;
|
||||||
|
|
||||||
|
import electroblob.wizardry.packet.PacketBombExplosion;
|
||||||
|
import electroblob.wizardry.packet.WizardryPacketHandler;
|
||||||
import electroblob.wizardry.registry.Spells;
|
import electroblob.wizardry.registry.Spells;
|
||||||
import electroblob.wizardry.registry.WizardrySounds;
|
import electroblob.wizardry.registry.WizardrySounds;
|
||||||
import electroblob.wizardry.spell.Spell;
|
import electroblob.wizardry.spell.Spell;
|
||||||
import electroblob.wizardry.util.EntityUtils;
|
import electroblob.wizardry.util.EntityUtils;
|
||||||
import electroblob.wizardry.util.MagicDamage;
|
import electroblob.wizardry.util.MagicDamage;
|
||||||
import electroblob.wizardry.util.MagicDamage.DamageType;
|
import electroblob.wizardry.util.MagicDamage.DamageType;
|
||||||
import electroblob.wizardry.util.ParticleBuilder;
|
|
||||||
import electroblob.wizardry.util.ParticleBuilder.Type;
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.util.EnumParticleTypes;
|
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -29,41 +29,28 @@ public class EntityFirebomb extends EntityBomb {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onImpact(RayTraceResult rayTrace){
|
protected void onImpact(RayTraceResult rayTrace){
|
||||||
|
|
||||||
Entity entityHit = rayTrace.entityHit;
|
|
||||||
|
|
||||||
if(entityHit != null){
|
|
||||||
// This is if the firebomb gets a direct hit
|
|
||||||
float damage = Spells.firebomb.getProperty(Spell.DIRECT_DAMAGE).floatValue() * damageMultiplier;
|
|
||||||
|
|
||||||
entityHit.attackEntityFrom(
|
|
||||||
MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.FIRE).setProjectile(),
|
|
||||||
damage);
|
|
||||||
|
|
||||||
if(!MagicDamage.isEntityImmune(DamageType.FIRE, entityHit))
|
|
||||||
entityHit.setFire(Spells.firebomb.getProperty(Spell.BURN_DURATION).intValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Particle effect
|
|
||||||
if(world.isRemote){
|
|
||||||
|
|
||||||
ParticleBuilder.create(Type.FLASH).pos(this.getPositionVector()).scale(5 * blastMultiplier).clr(1, 0.6f, 0)
|
|
||||||
.spawn(world);
|
|
||||||
|
|
||||||
for(int i = 0; i < 60 * blastMultiplier; i++){
|
|
||||||
|
|
||||||
ParticleBuilder.create(Type.MAGIC_FIRE, rand, posX, posY, posZ, 2*blastMultiplier, false)
|
|
||||||
.time(10 + rand.nextInt(4)).scale(2 + rand.nextFloat()).spawn(world);
|
|
||||||
|
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC, rand, posX, posY, posZ, 2*blastMultiplier, false)
|
|
||||||
.clr(1.0f, 0.2f + rand.nextFloat() * 0.4f, 0.0f).spawn(world);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.world.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, this.posX, this.posY, this.posZ, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!this.world.isRemote){
|
if(!this.world.isRemote){
|
||||||
|
|
||||||
|
Entity entityHit = rayTrace.entityHit;
|
||||||
|
|
||||||
|
if(entityHit != null){
|
||||||
|
// This is if the firebomb gets a direct hit
|
||||||
|
float damage = Spells.firebomb.getProperty(Spell.DIRECT_DAMAGE).floatValue() * damageMultiplier;
|
||||||
|
|
||||||
|
entityHit.attackEntityFrom(
|
||||||
|
MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.FIRE).setProjectile(),
|
||||||
|
damage);
|
||||||
|
|
||||||
|
if(!MagicDamage.isEntityImmune(DamageType.FIRE, entityHit))
|
||||||
|
entityHit.setFire(Spells.firebomb.getProperty(Spell.BURN_DURATION).intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify clients to play the explosion effect
|
||||||
|
WizardryPacketHandler.net.sendToAllAround(
|
||||||
|
new PacketBombExplosion.Message(PacketBombExplosion.FIREBOMB, posX, posY, posZ, blastMultiplier),
|
||||||
|
new NetworkRegistry.TargetPoint(world.provider.getDimension(), posX, posY, posZ, 64));
|
||||||
|
|
||||||
this.playSound(WizardrySounds.ENTITY_FIREBOMB_SMASH, 1.5F, rand.nextFloat() * 0.4F + 0.6F);
|
this.playSound(WizardrySounds.ENTITY_FIREBOMB_SMASH, 1.5F, rand.nextFloat() * 0.4F + 0.6F);
|
||||||
this.playSound(WizardrySounds.ENTITY_FIREBOMB_FIRE, 1, 1);
|
this.playSound(WizardrySounds.ENTITY_FIREBOMB_FIRE, 1, 1);
|
||||||
|
|
||||||
@@ -82,9 +69,9 @@ public class EntityFirebomb extends EntityBomb {
|
|||||||
target.setFire(Spells.firebomb.getProperty(Spell.BURN_DURATION).intValue());
|
target.setFire(Spells.firebomb.getProperty(Spell.BURN_DURATION).intValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setDead();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.setDead();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
package electroblob.wizardry.entity.projectile;
|
package electroblob.wizardry.entity.projectile;
|
||||||
|
|
||||||
|
import electroblob.wizardry.packet.PacketBombExplosion;
|
||||||
|
import electroblob.wizardry.packet.WizardryPacketHandler;
|
||||||
import electroblob.wizardry.registry.Spells;
|
import electroblob.wizardry.registry.Spells;
|
||||||
import electroblob.wizardry.registry.WizardrySounds;
|
import electroblob.wizardry.registry.WizardrySounds;
|
||||||
import electroblob.wizardry.spell.Spell;
|
import electroblob.wizardry.spell.Spell;
|
||||||
import electroblob.wizardry.util.EntityUtils;
|
import electroblob.wizardry.util.EntityUtils;
|
||||||
import electroblob.wizardry.util.MagicDamage;
|
import electroblob.wizardry.util.MagicDamage;
|
||||||
import electroblob.wizardry.util.MagicDamage.DamageType;
|
import electroblob.wizardry.util.MagicDamage.DamageType;
|
||||||
import electroblob.wizardry.util.ParticleBuilder;
|
|
||||||
import electroblob.wizardry.util.ParticleBuilder.Type;
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.init.MobEffects;
|
import net.minecraft.init.MobEffects;
|
||||||
import net.minecraft.potion.PotionEffect;
|
import net.minecraft.potion.PotionEffect;
|
||||||
import net.minecraft.util.EnumParticleTypes;
|
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -31,44 +31,30 @@ public class EntityPoisonBomb extends EntityBomb {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onImpact(RayTraceResult rayTrace){
|
protected void onImpact(RayTraceResult rayTrace){
|
||||||
|
|
||||||
Entity entityHit = rayTrace.entityHit;
|
|
||||||
|
|
||||||
if(entityHit != null){
|
|
||||||
// This is if the poison bomb gets a direct hit
|
|
||||||
float damage = Spells.poison_bomb.getProperty(Spell.DIRECT_DAMAGE).floatValue() * damageMultiplier;
|
|
||||||
|
|
||||||
entityHit.attackEntityFrom(
|
|
||||||
MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.POISON).setProjectile(),
|
|
||||||
damage);
|
|
||||||
|
|
||||||
if(entityHit instanceof EntityLivingBase && !MagicDamage.isEntityImmune(DamageType.POISON, entityHit))
|
|
||||||
((EntityLivingBase)entityHit).addPotionEffect(new PotionEffect(MobEffects.POISON,
|
|
||||||
Spells.poison_bomb.getProperty(Spell.DIRECT_EFFECT_DURATION).intValue(),
|
|
||||||
Spells.poison_bomb.getProperty(Spell.DIRECT_EFFECT_STRENGTH).intValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Particle effect
|
|
||||||
if(world.isRemote){
|
|
||||||
|
|
||||||
ParticleBuilder.create(Type.FLASH).pos(this.getPositionVector()).scale(5 * blastMultiplier)
|
|
||||||
.clr(0.2f + rand.nextFloat() * 0.3f, 0.6f, 0.0f).spawn(world);
|
|
||||||
|
|
||||||
for(int i = 0; i < 60 * blastMultiplier; i++){
|
|
||||||
|
|
||||||
ParticleBuilder.create(Type.SPARKLE, rand, posX, posY, posZ, 2*blastMultiplier, false).time(35)
|
|
||||||
.scale(2).clr(0.2f + rand.nextFloat() * 0.3f, 0.6f, 0.0f).spawn(world);
|
|
||||||
|
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC, rand, posX, posY, posZ, 2*blastMultiplier, false)
|
|
||||||
.clr(0.2f + rand.nextFloat() * 0.2f, 0.8f, 0.0f).spawn(world);
|
|
||||||
}
|
|
||||||
// Spawning this after the other particles fixes the rendering colour bug. It's a bit of a cheat, but it
|
|
||||||
// works pretty well.
|
|
||||||
this.world.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, this.posX, this.posY, this.posZ, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!this.world.isRemote){
|
if(!this.world.isRemote){
|
||||||
|
|
||||||
|
Entity entityHit = rayTrace.entityHit;
|
||||||
|
|
||||||
|
if(entityHit != null){
|
||||||
|
// This is if the poison bomb gets a direct hit
|
||||||
|
float damage = Spells.poison_bomb.getProperty(Spell.DIRECT_DAMAGE).floatValue() * damageMultiplier;
|
||||||
|
|
||||||
|
entityHit.attackEntityFrom(
|
||||||
|
MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.POISON).setProjectile(),
|
||||||
|
damage);
|
||||||
|
|
||||||
|
if(entityHit instanceof EntityLivingBase && !MagicDamage.isEntityImmune(DamageType.POISON, entityHit))
|
||||||
|
((EntityLivingBase)entityHit).addPotionEffect(new PotionEffect(MobEffects.POISON,
|
||||||
|
Spells.poison_bomb.getProperty(Spell.DIRECT_EFFECT_DURATION).intValue(),
|
||||||
|
Spells.poison_bomb.getProperty(Spell.DIRECT_EFFECT_STRENGTH).intValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify clients to play the explosion effect
|
||||||
|
WizardryPacketHandler.net.sendToAllAround(
|
||||||
|
new PacketBombExplosion.Message(PacketBombExplosion.POISON_BOMB, posX, posY, posZ, blastMultiplier),
|
||||||
|
new NetworkRegistry.TargetPoint(world.provider.getDimension(), posX, posY, posZ, 64));
|
||||||
|
|
||||||
this.playSound(WizardrySounds.ENTITY_POISON_BOMB_SMASH, 1.5F, rand.nextFloat() * 0.4F + 0.6F);
|
this.playSound(WizardrySounds.ENTITY_POISON_BOMB_SMASH, 1.5F, rand.nextFloat() * 0.4F + 0.6F);
|
||||||
this.playSound(WizardrySounds.ENTITY_POISON_BOMB_POISON, 1.2F, 1.0f);
|
this.playSound(WizardrySounds.ENTITY_POISON_BOMB_POISON, 1.2F, 1.0f);
|
||||||
|
|
||||||
@@ -88,8 +74,8 @@ public class EntityPoisonBomb extends EntityBomb {
|
|||||||
Spells.poison_bomb.getProperty(Spell.SPLASH_EFFECT_STRENGTH).intValue()));
|
Spells.poison_bomb.getProperty(Spell.SPLASH_EFFECT_STRENGTH).intValue()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setDead();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.setDead();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
package electroblob.wizardry.entity.projectile;
|
package electroblob.wizardry.entity.projectile;
|
||||||
|
|
||||||
|
import electroblob.wizardry.packet.PacketBombExplosion;
|
||||||
|
import electroblob.wizardry.packet.WizardryPacketHandler;
|
||||||
import electroblob.wizardry.registry.Spells;
|
import electroblob.wizardry.registry.Spells;
|
||||||
import electroblob.wizardry.registry.WizardrySounds;
|
import electroblob.wizardry.registry.WizardrySounds;
|
||||||
import electroblob.wizardry.spell.Spell;
|
import electroblob.wizardry.spell.Spell;
|
||||||
import electroblob.wizardry.util.EntityUtils;
|
import electroblob.wizardry.util.EntityUtils;
|
||||||
import electroblob.wizardry.util.ParticleBuilder;
|
|
||||||
import electroblob.wizardry.util.ParticleBuilder.Type;
|
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.init.MobEffects;
|
import net.minecraft.init.MobEffects;
|
||||||
import net.minecraft.potion.PotionEffect;
|
import net.minecraft.potion.PotionEffect;
|
||||||
import net.minecraft.util.EnumParticleTypes;
|
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -29,27 +29,13 @@ public class EntitySmokeBomb extends EntityBomb {
|
|||||||
@Override
|
@Override
|
||||||
protected void onImpact(RayTraceResult rayTrace){
|
protected void onImpact(RayTraceResult rayTrace){
|
||||||
|
|
||||||
// Particle effect
|
|
||||||
if(world.isRemote){
|
|
||||||
|
|
||||||
ParticleBuilder.create(Type.FLASH).pos(this.getPositionVector()).scale(5 * blastMultiplier).clr(0, 0, 0).spawn(world);
|
|
||||||
|
|
||||||
this.world.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, this.posX, this.posY, this.posZ, 0, 0, 0);
|
|
||||||
|
|
||||||
for(int i = 0; i < 60 * blastMultiplier; i++){
|
|
||||||
|
|
||||||
float brightness = rand.nextFloat() * 0.1f + 0.1f;
|
|
||||||
ParticleBuilder.create(Type.CLOUD, rand, posX, posY, posZ, 2*blastMultiplier, false)
|
|
||||||
.clr(brightness, brightness, brightness).time(80 + this.rand.nextInt(12)).shaded(true).spawn(world);
|
|
||||||
|
|
||||||
brightness = rand.nextFloat() * 0.3f;
|
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC, rand, posX, posY, posZ, 2*blastMultiplier, false)
|
|
||||||
.clr(brightness, brightness, brightness).spawn(world);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!this.world.isRemote){
|
if(!this.world.isRemote){
|
||||||
|
|
||||||
|
// Notify clients to play the explosion effect
|
||||||
|
WizardryPacketHandler.net.sendToAllAround(
|
||||||
|
new PacketBombExplosion.Message(PacketBombExplosion.SMOKE_BOMB, posX, posY, posZ, blastMultiplier),
|
||||||
|
new NetworkRegistry.TargetPoint(world.provider.getDimension(), posX, posY, posZ, 64));
|
||||||
|
|
||||||
this.playSound(WizardrySounds.ENTITY_SMOKE_BOMB_SMASH, 1.5F, rand.nextFloat() * 0.4F + 0.6F);
|
this.playSound(WizardrySounds.ENTITY_SMOKE_BOMB_SMASH, 1.5F, rand.nextFloat() * 0.4F + 0.6F);
|
||||||
this.playSound(WizardrySounds.ENTITY_SMOKE_BOMB_SMOKE, 1.2F, 1.0f);
|
this.playSound(WizardrySounds.ENTITY_SMOKE_BOMB_SMOKE, 1.2F, 1.0f);
|
||||||
|
|
||||||
@@ -65,8 +51,8 @@ public class EntitySmokeBomb extends EntityBomb {
|
|||||||
target.addPotionEffect(new PotionEffect(MobEffects.BLINDNESS, duration, 0));
|
target.addPotionEffect(new PotionEffect(MobEffects.BLINDNESS, duration, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setDead();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.setDead();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package electroblob.wizardry.entity.projectile;
|
package electroblob.wizardry.entity.projectile;
|
||||||
|
|
||||||
|
import electroblob.wizardry.packet.PacketBombExplosion;
|
||||||
|
import electroblob.wizardry.packet.WizardryPacketHandler;
|
||||||
import electroblob.wizardry.registry.Spells;
|
import electroblob.wizardry.registry.Spells;
|
||||||
import electroblob.wizardry.registry.WizardrySounds;
|
import electroblob.wizardry.registry.WizardrySounds;
|
||||||
import electroblob.wizardry.spell.Spell;
|
import electroblob.wizardry.spell.Spell;
|
||||||
@@ -13,7 +15,9 @@ import net.minecraft.entity.EntityLivingBase;
|
|||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class EntitySparkBomb extends EntityBomb {
|
public class EntitySparkBomb extends EntityBomb {
|
||||||
@@ -31,47 +35,37 @@ public class EntitySparkBomb extends EntityBomb {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onImpact(RayTraceResult rayTrace){
|
protected void onImpact(RayTraceResult rayTrace){
|
||||||
|
|
||||||
this.playSound(WizardrySounds.ENTITY_SPARK_BOMB_HIT_BLOCK, 0.5f, 0.5f);
|
|
||||||
|
|
||||||
Entity entityHit = rayTrace.entityHit;
|
if(!this.world.isRemote){
|
||||||
|
|
||||||
if(entityHit != null){
|
Entity entityHit = rayTrace.entityHit;
|
||||||
// This is if the spark bomb gets a direct hit
|
|
||||||
float damage = Spells.spark_bomb.getProperty(Spell.DIRECT_DAMAGE).floatValue() * damageMultiplier;
|
|
||||||
|
|
||||||
this.playSound(WizardrySounds.ENTITY_SPARK_BOMB_HIT, 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F));
|
if(entityHit != null){
|
||||||
|
// This is if the spark bomb gets a direct hit
|
||||||
|
float damage = Spells.spark_bomb.getProperty(Spell.DIRECT_DAMAGE).floatValue() * damageMultiplier;
|
||||||
|
|
||||||
entityHit.attackEntityFrom(
|
this.playSound(WizardrySounds.ENTITY_SPARK_BOMB_HIT, 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F));
|
||||||
MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.SHOCK).setProjectile(),
|
|
||||||
damage);
|
|
||||||
|
|
||||||
}
|
entityHit.attackEntityFrom(
|
||||||
|
MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.SHOCK).setProjectile(),
|
||||||
|
damage);
|
||||||
|
}
|
||||||
|
|
||||||
// Particle effect
|
double seekerRange = Spells.spark_bomb.getProperty(Spell.EFFECT_RADIUS).doubleValue() * blastMultiplier;
|
||||||
if(world.isRemote){
|
|
||||||
ParticleBuilder.spawnShockParticles(world, posX, posY + height/2, posZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
double seekerRange = Spells.spark_bomb.getProperty(Spell.EFFECT_RADIUS).doubleValue() * blastMultiplier;
|
List<EntityLivingBase> targets = EntityUtils.getLivingWithinRadius(seekerRange, this.posX, this.posY,
|
||||||
|
this.posZ, this.world);
|
||||||
|
|
||||||
List<EntityLivingBase> targets = EntityUtils.getLivingWithinRadius(seekerRange, this.posX, this.posY,
|
List<Integer> secondaryTargetIDs = new ArrayList<>();
|
||||||
this.posZ, this.world);
|
|
||||||
|
|
||||||
for(int i = 0; i < Math.min(targets.size(), Spells.spark_bomb.getProperty(SECONDARY_MAX_TARGETS).intValue()); i++){
|
for(int i = 0; i < Math.min(targets.size(), Spells.spark_bomb.getProperty(SECONDARY_MAX_TARGETS).intValue()); i++){
|
||||||
|
|
||||||
boolean flag = targets.get(i) != entityHit && targets.get(i) != this.getThrower()
|
boolean flag = targets.get(i) != entityHit && targets.get(i) != this.getThrower()
|
||||||
&& !(targets.get(i) instanceof EntityPlayer
|
&& !(targets.get(i) instanceof EntityPlayer
|
||||||
&& ((EntityPlayer)targets.get(i)).isCreative());
|
&& ((EntityPlayer)targets.get(i)).isCreative());
|
||||||
|
|
||||||
// Detects (client side) if target is the thrower, to stop particles being spawned around them.
|
if(flag){
|
||||||
//if(flag && world.isRemote && targets.get(i).getEntityId() == this.playerID) flag = false;
|
EntityLivingBase target = targets.get(i);
|
||||||
|
|
||||||
if(flag){
|
|
||||||
|
|
||||||
EntityLivingBase target = targets.get(i);
|
|
||||||
|
|
||||||
if(!this.world.isRemote){
|
|
||||||
|
|
||||||
target.playSound(WizardrySounds.ENTITY_SPARK_BOMB_CHAIN, 1.0F, rand.nextFloat() * 0.4F + 1.5F);
|
target.playSound(WizardrySounds.ENTITY_SPARK_BOMB_CHAIN, 1.0F, rand.nextFloat() * 0.4F + 1.5F);
|
||||||
|
|
||||||
@@ -79,11 +73,18 @@ public class EntitySparkBomb extends EntityBomb {
|
|||||||
MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.SHOCK),
|
MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.SHOCK),
|
||||||
Spells.spark_bomb.getProperty(Spell.SPLASH_DAMAGE).floatValue() * damageMultiplier);
|
Spells.spark_bomb.getProperty(Spell.SPLASH_DAMAGE).floatValue() * damageMultiplier);
|
||||||
|
|
||||||
}else{
|
secondaryTargetIDs.add(target.getEntityId());
|
||||||
ParticleBuilder.create(Type.LIGHTNING).pos(this.getPositionVector()).target(target).spawn(world);
|
|
||||||
ParticleBuilder.spawnShockParticles(world, target.posX, target.posY + target.height/2, target.posZ);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Notify clients to play the explosion effect, including lightning arcs to secondary targets
|
||||||
|
int[] idArray = secondaryTargetIDs.stream().mapToInt(Integer::intValue).toArray();
|
||||||
|
WizardryPacketHandler.net.sendToAllAround(
|
||||||
|
new PacketBombExplosion.Message(PacketBombExplosion.SPARK_BOMB, posX, posY + height / 2, posZ,
|
||||||
|
blastMultiplier, idArray),
|
||||||
|
new NetworkRegistry.TargetPoint(world.provider.getDimension(), posX, posY, posZ, 64));
|
||||||
|
|
||||||
|
this.playSound(WizardrySounds.ENTITY_SPARK_BOMB_HIT_BLOCK, 0.5f, 0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setDead();
|
this.setDead();
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
package electroblob.wizardry.packet;
|
||||||
|
|
||||||
|
import electroblob.wizardry.Wizardry;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||||
|
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
|
||||||
|
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <b>[Server -> Client]</b> This packet is sent when a bomb entity impacts something. It is used to guarantee that the
|
||||||
|
* client always sees the explosion effect, even in singleplayer where the server may remove the entity before the
|
||||||
|
* client's own simulation can call {@code onImpact()}.
|
||||||
|
*/
|
||||||
|
public class PacketBombExplosion implements IMessageHandler<PacketBombExplosion.Message, IMessage> {
|
||||||
|
|
||||||
|
/** Bomb type constants, matching the order bombs are handled in {@link electroblob.wizardry.CommonProxy}. */
|
||||||
|
public static final int FIREBOMB = 0;
|
||||||
|
public static final int POISON_BOMB = 1;
|
||||||
|
public static final int SMOKE_BOMB = 2;
|
||||||
|
public static final int SPARK_BOMB = 3;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IMessage onMessage(Message message, MessageContext ctx){
|
||||||
|
if(ctx.side.isClient()){
|
||||||
|
net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(
|
||||||
|
() -> Wizardry.proxy.handleBombExplosionPacket(message));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Message implements IMessage {
|
||||||
|
|
||||||
|
/** One of the bomb type constants defined in {@link PacketBombExplosion}. */
|
||||||
|
public int bombType;
|
||||||
|
public double x, y, z;
|
||||||
|
public float blastMultiplier;
|
||||||
|
/** Entity IDs of secondary targets struck by the spark bomb chain. Empty for other bomb types. */
|
||||||
|
public int[] secondaryTargetIDs;
|
||||||
|
|
||||||
|
// Required no-arg constructor
|
||||||
|
public Message(){}
|
||||||
|
|
||||||
|
public Message(int bombType, double x, double y, double z, float blastMultiplier){
|
||||||
|
this(bombType, x, y, z, blastMultiplier, new int[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Message(int bombType, double x, double y, double z, float blastMultiplier, int[] secondaryTargetIDs){
|
||||||
|
this.bombType = bombType;
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
this.blastMultiplier = blastMultiplier;
|
||||||
|
this.secondaryTargetIDs = secondaryTargetIDs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fromBytes(ByteBuf buf){
|
||||||
|
bombType = buf.readInt();
|
||||||
|
x = buf.readDouble();
|
||||||
|
y = buf.readDouble();
|
||||||
|
z = buf.readDouble();
|
||||||
|
blastMultiplier = buf.readFloat();
|
||||||
|
int count = buf.readInt();
|
||||||
|
secondaryTargetIDs = new int[count];
|
||||||
|
for(int i = 0; i < count; i++) secondaryTargetIDs[i] = buf.readInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void toBytes(ByteBuf buf){
|
||||||
|
buf.writeInt(bombType);
|
||||||
|
buf.writeDouble(x);
|
||||||
|
buf.writeDouble(y);
|
||||||
|
buf.writeDouble(z);
|
||||||
|
buf.writeFloat(blastMultiplier);
|
||||||
|
buf.writeInt(secondaryTargetIDs.length);
|
||||||
|
for(int id : secondaryTargetIDs) buf.writeInt(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -35,6 +35,7 @@ public class WizardryPacketHandler {
|
|||||||
registerMessage(PacketSpellQuickAccess.class, PacketSpellQuickAccess.Message.class);
|
registerMessage(PacketSpellQuickAccess.class, PacketSpellQuickAccess.Message.class);
|
||||||
registerMessage(PacketRequestDonationPerks.class, PacketRequestDonationPerks.Message.class);
|
registerMessage(PacketRequestDonationPerks.class, PacketRequestDonationPerks.Message.class);
|
||||||
registerMessage(PacketSyncDonationPerks.class, PacketSyncDonationPerks.Message.class);
|
registerMessage(PacketSyncDonationPerks.class, PacketSyncDonationPerks.Message.class);
|
||||||
|
registerMessage(PacketBombExplosion.class, PacketBombExplosion.Message.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int nextPacketId = 0;
|
private static int nextPacketId = 0;
|
||||||
|
|||||||
@@ -1,17 +1,14 @@
|
|||||||
{
|
{
|
||||||
"parent": "ebwizardry:item/spell_book_undiscovered",
|
"parent": "ebwizardry:item/spell_book_undiscovered",
|
||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{"predicate": {"ebwizardry:element": 1}, "model": "ebwizardry:item/spell_book_discovered_magic"},
|
||||||
"predicate": {
|
{"predicate": {"ebwizardry:element": 2}, "model": "ebwizardry:item/spell_book_discovered_fire"},
|
||||||
"festive": 1
|
{"predicate": {"ebwizardry:element": 3}, "model": "ebwizardry:item/spell_book_discovered_ice"},
|
||||||
},
|
{"predicate": {"ebwizardry:element": 4}, "model": "ebwizardry:item/spell_book_discovered_lightning"},
|
||||||
"model": "ebwizardry:item/festive_spell_book"
|
{"predicate": {"ebwizardry:element": 5}, "model": "ebwizardry:item/spell_book_discovered_necromancy"},
|
||||||
},
|
{"predicate": {"ebwizardry:element": 6}, "model": "ebwizardry:item/spell_book_discovered_earth"},
|
||||||
{
|
{"predicate": {"ebwizardry:element": 7}, "model": "ebwizardry:item/spell_book_discovered_sorcery"},
|
||||||
"predicate": {
|
{"predicate": {"ebwizardry:element": 8}, "model": "ebwizardry:item/spell_book_discovered_healing"},
|
||||||
"ebwizardry:discovered": 1
|
{"predicate": {"festive": 1}, "model": "ebwizardry:item/festive_spell_book"}
|
||||||
},
|
|
||||||
"model": "ebwizardry:item/spell_book_discovered"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "ebwizardry:items/spell_book",
|
||||||
|
"layer1": "ebwizardry:items/spell_book_overlay_earth"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "ebwizardry:items/spell_book",
|
||||||
|
"layer1": "ebwizardry:items/spell_book_overlay_fire"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "ebwizardry:items/spell_book",
|
||||||
|
"layer1": "ebwizardry:items/spell_book_overlay_healing"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "ebwizardry:items/spell_book",
|
||||||
|
"layer1": "ebwizardry:items/spell_book_overlay_ice"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "ebwizardry:items/spell_book",
|
||||||
|
"layer1": "ebwizardry:items/spell_book_overlay_lightning"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "ebwizardry:items/spell_book",
|
||||||
|
"layer1": "ebwizardry:items/spell_book_overlay_magic"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "ebwizardry:items/spell_book",
|
||||||
|
"layer1": "ebwizardry:items/spell_book_overlay_necromancy"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "ebwizardry:items/spell_book",
|
||||||
|
"layer1": "ebwizardry:items/spell_book_overlay_sorcery"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 145 B |
|
After Width: | Height: | Size: 147 B |
|
After Width: | Height: | Size: 147 B |
|
After Width: | Height: | Size: 147 B |
|
After Width: | Height: | Size: 145 B |
|
After Width: | Height: | Size: 147 B |
|
After Width: | Height: | Size: 147 B |
|
After Width: | Height: | Size: 147 B |