Skip to content

Commit

Permalink
Flaming Strike Spell wip
Browse files Browse the repository at this point in the history
  • Loading branch information
iron431 committed Dec 14, 2023
1 parent b576ff3 commit e92a12c
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ public static AbstractSpell getSpell(ResourceLocation resourceLocation) {
public static final RegistryObject<AbstractSpell> MAGMA_BOMB_SPELL = registerSpell(new MagmaBombSpell());
public static final RegistryObject<AbstractSpell> WALL_OF_FIRE_SPELL = registerSpell(new WallOfFireSpell());
public static final RegistryObject<AbstractSpell> HEAT_SURGE_SPELL = registerSpell(new HeatSurgeSpell());
public static final RegistryObject<AbstractSpell> FLAMING_STRIKE = registerSpell(new FlamingStrikeSpell());

// HOLY
public static final RegistryObject<AbstractSpell> ANGEL_WINGS_SPELL = registerSpell(new AngelWingsSpell());
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/io/redspace/ironsspellbooks/api/util/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -604,4 +604,18 @@ public static void loadAllItems(CompoundTag pTag, NonNullList<ItemStack> pList,
}
}
}

public static float getWeaponDamage(LivingEntity entity, MobType entityForDamageBonus) {
if (entity != null) {
float weapon = (float) (entity.getAttributeValue(Attributes.ATTACK_DAMAGE));
float fist = (float) (entity.getAttributeBaseValue(Attributes.ATTACK_DAMAGE));
if (weapon == fist) {
//Remove fist damage if they are not using a melee weapon
weapon -= fist;
}
float enchant = EnchantmentHelper.getDamageBonus(entity.getMainHandItem(),entityForDamageBonus);
return weapon + enchant;
}
return 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,20 @@
import net.minecraft.world.level.Level;
import net.minecraftforge.network.NetworkHooks;

//TODO: well, this really could've been a particle. However, it already works.
public class FlameStrike extends AoeEntity {
public FlameStrike(EntityType<? extends Projectile> pEntityType, Level pLevel) {
super(pEntityType, pLevel);
}

LivingEntity target;

public FlameStrike(Level level, LivingEntity owner, LivingEntity target) {
public FlameStrike(Level level) {
this(EntityRegistry.FLAME_STRIKE.get(), level);
setOwner(owner);
this.target = target;
}

@Override
public void applyEffect(LivingEntity target) {
if (target == this.target) {
if (DamageSources.applyDamage(target, getDamage(), SpellRegistry.DEVOUR_SPELL.get().getDamageSource(this, getOwner())) && getOwner() instanceof LivingEntity livingOwner) {

}
}
}

public final int ticksPerFrame = 2;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public void render(FlameStrike entity, float yaw, float partialTicks, PoseStack
Pose pose = poseStack.last();
Matrix4f poseMatrix = pose.pose();
Matrix3f normalMatrix = pose.normal();
poseStack.mulPose(Vector3f.YP.rotationDegrees(Mth.lerp(partialTicks, entity.yRotO, entity.getYRot())));
poseStack.mulPose(Vector3f.YP.rotationDegrees(90 - Mth.lerp(partialTicks, entity.yRotO, entity.getYRot())));
poseStack.mulPose(Vector3f.XP.rotationDegrees(-Mth.lerp(partialTicks, entity.xRotO, entity.getXRot())));
// poseStack.mulPose(Vector3f.ZP.rotationDegrees(((entity.animationSeed % 30) - 15) * (float) Math.sin(entity.animationTime * .015)));

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
package io.redspace.ironsspellbooks.spells.fire;

import io.redspace.ironsspellbooks.IronsSpellbooks;
import io.redspace.ironsspellbooks.api.config.DefaultConfig;
import io.redspace.ironsspellbooks.api.magic.MagicData;
import io.redspace.ironsspellbooks.api.registry.SchoolRegistry;
import io.redspace.ironsspellbooks.api.spells.*;
import io.redspace.ironsspellbooks.api.util.AnimationHolder;
import io.redspace.ironsspellbooks.api.util.CameraShakeData;
import io.redspace.ironsspellbooks.api.util.CameraShakeManager;
import io.redspace.ironsspellbooks.api.util.Utils;
import io.redspace.ironsspellbooks.capabilities.magic.MagicManager;
import io.redspace.ironsspellbooks.damage.DamageSources;
import io.redspace.ironsspellbooks.damage.ISpellDamageSource;
import io.redspace.ironsspellbooks.entity.spells.flame_strike.FlameStrike;
import io.redspace.ironsspellbooks.particle.ShockwaveParticleOptions;
import io.redspace.ironsspellbooks.registries.SoundRegistry;
import io.redspace.ironsspellbooks.util.ParticleHelper;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.MobType;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.Nullable;

import java.util.List;
import java.util.Optional;

@AutoSpellConfig
public class FlamingStrikeSpell extends AbstractSpell {
private final ResourceLocation spellId = new ResourceLocation(IronsSpellbooks.MODID, "flaming_strike");

@Override
public List<MutableComponent> getUniqueInfo(int spellLevel, LivingEntity caster) {
return List.of(Component.translatable("ui.irons_spellbooks.damage", getDamageText(spellLevel, caster)));
}

private final DefaultConfig defaultConfig = new DefaultConfig()
.setMinRarity(SpellRarity.COMMON)
.setSchoolResource(SchoolRegistry.HOLY_RESOURCE)
.setMaxLevel(5)
.setCooldownSeconds(15)
.build();

public FlamingStrikeSpell() {
this.manaCostPerLevel = 15;
this.baseSpellPower = 5;
this.spellPowerPerLevel = 3;
this.castTime = 16;
this.baseManaCost = 30;
}

@Override
public boolean canBeInterrupted(Player player) {
return false;
}

@Override
public int getEffectiveCastTime(int spellLevel, @Nullable LivingEntity entity) {
//due to melee animation timing, we do not want cast time attribute to affect this spell
return getCastTime(spellLevel);
}

@Override
public CastType getCastType() {
return CastType.LONG;
}

@Override
public DefaultConfig getDefaultConfig() {
return defaultConfig;
}

@Override
public ResourceLocation getSpellResource() {
return spellId;
}

@Override
public Optional<SoundEvent> getCastStartSound() {
return Optional.of(SoundRegistry.DIVINE_SMITE_WINDUP.get());
}

@Override
public Optional<SoundEvent> getCastFinishSound() {
return Optional.of(SoundRegistry.DIVINE_SMITE_CAST.get());
}

@Override
public void onCast(Level level, int spellLevel, LivingEntity entity, MagicData playerMagicData) {
float radius = 2.5f;
Vec3 hitLocation = entity.position().add(0, entity.getBbHeight() * .4f, 0).add(entity.getForward().multiply(1.45f, 0, 1.45f));
var entities = level.getEntities(entity, AABB.ofSize(hitLocation, radius * 2, radius, radius * 2));
for (Entity targetEntity : entities) {
if (entity.distanceTo(targetEntity) < radius && Utils.hasLineOfSight(level, hitLocation, targetEntity.getBoundingBox().getCenter(), true)) {
if (DamageSources.applyDamage(targetEntity, getDamage(spellLevel, entity), this.getDamageSource(entity))) {
MagicManager.spawnParticles(level, ParticleHelper.EMBERS, targetEntity.getX(), targetEntity.getY() + targetEntity.getBbHeight() * .5f, targetEntity.getZ(), 50, targetEntity.getBbWidth() * .5f, targetEntity.getBbHeight() * .5f, targetEntity.getBbWidth() * .5f, .03, false);
}
}
}
FlameStrike flameStrike = new FlameStrike(level);
flameStrike.moveTo(hitLocation);
flameStrike.setYRot(entity.getYRot());
level.addFreshEntity(flameStrike);
super.onCast(level, spellLevel, entity, playerMagicData);
}

@Override
public DamageSource getDamageSource(@Nullable Entity projectile, Entity attacker) {
return ((ISpellDamageSource) super.getDamageSource(projectile, attacker)).setFireTime(3).get();
}

private float getDamage(int spellLevel, LivingEntity entity) {
return getSpellPower(spellLevel, entity) + Utils.getWeaponDamage(entity, MobType.UNDEFINED);
}


private String getDamageText(int spellLevel, LivingEntity entity) {
if (entity != null) {
float weaponDamage = Utils.getWeaponDamage(entity, MobType.UNDEFINED);
String plus = "";
if (weaponDamage > 0) {
plus = String.format(" (+%s)", Utils.stringTruncation(weaponDamage, 1));
}
String damage = Utils.stringTruncation(getDamage(spellLevel, entity), 1);
return damage + plus;
}
return "" + getSpellPower(spellLevel, entity);
}

@Override
public AnimationHolder getCastStartAnimation() {
return SpellAnimations.OVERHEAD_MELEE_SWING_ANIMATION;
}

@Override
public AnimationHolder getCastFinishAnimation() {
return AnimationHolder.pass();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public Optional<SoundEvent> getCastFinishSound() {
@Override
public void onCast(Level level, int spellLevel, LivingEntity entity, MagicData playerMagicData) {
float radius = 1.75f;
Vec3 smiteLocation = Utils.moveToRelativeGroundLevel(level, entity.getEyePosition().add(entity.getForward().multiply(1, 0, 1).normalize().scale(1.35f)), 2);
Vec3 smiteLocation = Utils.moveToRelativeGroundLevel(level, entity.getEyePosition().add(entity.getForward().multiply(1.35f, 0, 1.35f)), 1);
MagicManager.spawnParticles(level, new ShockwaveParticleOptions(SchoolRegistry.HOLY.get().getTargetingColor(), radius * 2, true), smiteLocation.x, smiteLocation.y + .15f, smiteLocation.z, 1, 0, 0, 0, 0, true);
MagicManager.spawnParticles(level, ParticleTypes.ELECTRIC_SPARK, smiteLocation.x, smiteLocation.y + .15f, smiteLocation.z, 50, 0, 0, 0, 1, false);
CameraShakeManager.addCameraShake(new CameraShakeData(10, smiteLocation, 10));
Expand All @@ -110,28 +110,14 @@ public void onCast(Level level, int spellLevel, LivingEntity entity, MagicData p
}

private float getDamage(int spellLevel, LivingEntity entity) {
//IronsSpellbooks.LOGGER.debug("SmitingStrikeSpell.getDamage {} + {} + {}", getSpellPower(spellLevel, entity), base, enchant);
return getSpellPower(spellLevel, entity) + getWeaponDamage(entity);
//Setting mob type to undead means the smite enchantment also adds to the spell's damage. Seems fitting.
return getSpellPower(spellLevel, entity) + Utils.getWeaponDamage(entity, MobType.UNDEAD);
}

private float getWeaponDamage(LivingEntity entity) {
if (entity != null) {
float weapon = (float) (entity.getAttributeValue(Attributes.ATTACK_DAMAGE));
float fist = (float) (entity.getAttributeBaseValue(Attributes.ATTACK_DAMAGE));
if (weapon == fist) {
//Remove fist damage if they are not using a melee weapon
weapon -= fist;
}
//Setting mob type to undead means the smite enchantment also adds to the spell's damage. Seems fitting.
float enchant = EnchantmentHelper.getDamageBonus(entity.getMainHandItem(), MobType.UNDEAD);
return weapon + enchant;
}
return 0;
}

private String getDamageText(int spellLevel, LivingEntity entity) {
if (entity != null) {
float weaponDamage = getWeaponDamage(entity);
float weaponDamage = Utils.getWeaponDamage(entity, MobType.UNDEAD);
String plus = "";
if (weaponDamage > 0) {
plus = String.format(" (+%s)", Utils.stringTruncation(weaponDamage, 1));
Expand Down

0 comments on commit e92a12c

Please sign in to comment.