Skip to content

Commit

Permalink
Merge branch 'devour-spell' into 1.19.2
Browse files Browse the repository at this point in the history
  • Loading branch information
iron431 committed Jun 26, 2023
2 parents 0c0783c + 41c0839 commit 316942a
Show file tree
Hide file tree
Showing 18 changed files with 319 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ public class ServerConfigs {
createSpellConfig(SpellType.WITHER_SKULL_SPELL, WitherSkullSpell.defaultConfig, true);
createSpellConfig(SpellType.BlOOD_NEEDLES_SPELL, BloodNeedlesSpell.defaultConfig, true);
createSpellConfig(SpellType.ACUPUNCTURE_SPELL, AcupunctureSpell.defaultConfig, true);
createSpellConfig(SpellType.DEVOUR_SPELL, DevourSpell.defaultConfig, true);
//Ender
BUILDER.comment("Ender Spells");
createSpellConfig(SpellType.EVASION_SPELL, EvasionSpell.defaultConfig, true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public void tick() {
protected void checkHits() {
if (level.isClientSide)
return;
List<LivingEntity> targets = this.level.getEntitiesOfClass(LivingEntity.class, this.getBoundingBox());
List<LivingEntity> targets = this.level.getEntitiesOfClass(LivingEntity.class, this.getBoundingBox().inflate(this.getInflation()));
boolean hit = false;
for (LivingEntity target : targets) {
if (canHitEntity(target) && (!isCircular() || target.distanceTo(this) < getRadius())) {
Expand All @@ -92,6 +92,10 @@ protected void checkHits() {
}
}

protected float getInflation() {
return 0;
}

@Override
protected boolean canHitEntity(Entity pTarget) {
return pTarget != getOwner() && super.canHitEntity(pTarget);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package io.redspace.ironsspellbooks.entity.spells.devour_jaw;

import io.redspace.ironsspellbooks.damage.DamageSources;
import io.redspace.ironsspellbooks.entity.spells.AoeEntity;
import io.redspace.ironsspellbooks.registries.EntityRegistry;
import io.redspace.ironsspellbooks.registries.MobEffectRegistry;
import io.redspace.ironsspellbooks.registries.SoundRegistry;
import io.redspace.ironsspellbooks.spells.SpellType;
import io.redspace.ironsspellbooks.util.ParticleHelper;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.network.protocol.Packet;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.projectile.Projectile;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.network.NetworkHooks;

public class DevourJaw extends AoeEntity {
public DevourJaw(EntityType<? extends Projectile> pEntityType, Level pLevel) {
super(pEntityType, pLevel);
}

LivingEntity target;

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

//dont need to serialize, dont need it only client either
public int vigorLevel;

@Override
public void applyEffect(LivingEntity target) {
if (target == this.target)
if (DamageSources.applyDamage(target, getDamage(), SpellType.DEVOUR_SPELL.getDamageSource(this, getOwner()), SpellType.DEVOUR_SPELL.getSchoolType()) && getOwner() instanceof LivingEntity livingOwner) {
livingOwner.heal(getDamage() * .15f);
if (target.isDeadOrDying()) {
var oldVigor = livingOwner.getEffect(MobEffectRegistry.VIGOR.get());
var addition = 0;
if (oldVigor != null)
addition = oldVigor.getAmplifier() + 1;
livingOwner.addEffect(new MobEffectInstance(MobEffectRegistry.VIGOR.get(), 20 * 60, vigorLevel + addition, false, false, true));
livingOwner.heal((vigorLevel + 1) * 2);
}
}

}

public final int waitTime = 5;
public final int warmupTime = waitTime + 8;
public final int deathTime = warmupTime + 8;

@Override
public void tick() {
if (tickCount < waitTime) {
if (this.target != null)
setPos(this.target.position());
} else if (tickCount == waitTime) {
this.playSound(SoundRegistry.DEVOUR_BITE.get(), 2, 1);
} else if (tickCount == warmupTime) {
if (level.isClientSide) {
float y = this.getYRot();
int countPerSide = 25;
//These particles were not at all what I intended. But they're cooler. no clue how it works
for (int i = -countPerSide; i < countPerSide; i++) {
Vec3 motion = new Vec3(0, Math.abs(countPerSide) - i, countPerSide * .5f).yRot(y).normalize().multiply(.4f, .8f, .4f);
level.addParticle(ParticleHelper.BLOOD, getX(), getY() + .5f, getZ(), motion.x, motion.y, motion.z);
}
} else {
checkHits();
}
} else if (tickCount > deathTime)
discard();
}

@Override
protected float getInflation() {
return 2f;
}

@Override
public boolean shouldBeSaved() {
return false;
}

@Override
public void refreshDimensions() {
return;
}

@Override
public void ambientParticles() {
return;
}

@Override
public float getParticleCount() {
return 0;
}

@Override
public ParticleOptions getParticle() {
return ParticleHelper.BLOOD;
}

@Override
public Packet<?> getAddEntityPacket() {
return NetworkHooks.getEntitySpawningPacket(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package io.redspace.ironsspellbooks.entity.spells.devour_jaw;

import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.math.Vector3f;
import io.redspace.ironsspellbooks.IronsSpellbooks;
import net.minecraft.client.model.EvokerFangsModel;
import net.minecraft.client.model.geom.ModelLayers;
import net.minecraft.client.model.geom.ModelPart;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.entity.EntityRenderer;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;

public class DevourJawRenderer extends EntityRenderer<DevourJaw> {

private final DevourJawModel model;

public DevourJawRenderer(EntityRendererProvider.Context pContext) {
super(pContext);
this.model = new DevourJawModel(pContext.bakeLayer(ModelLayers.EVOKER_FANGS));
}

public void render(DevourJaw entity, float yaw, float partialTicks, PoseStack poseStack, MultiBufferSource multiBufferSource, int light) {
if (entity.tickCount < entity.waitTime)
return;
float f = entity.tickCount + partialTicks;
poseStack.pushPose();
poseStack.mulPose(Vector3f.YP.rotationDegrees(-entity.getYRot()));
poseStack.scale(-1, -1, 1);
poseStack.scale(1.85f, 1.85f, 1.85f);
this.model.setupAnim(entity, f, 0.0F, 0.0F, entity.getYRot(), entity.getXRot());
VertexConsumer vertexconsumer = multiBufferSource.getBuffer(RenderType.entityCutoutNoCull(getTextureLocation(entity)));
this.model.renderToBuffer(poseStack, vertexconsumer, light, OverlayTexture.NO_OVERLAY, 1.0F, 1.0F, 1.0F, 1.0F);
poseStack.popPose();
super.render(entity, yaw, partialTicks, poseStack, multiBufferSource, light);
}

@Override
public ResourceLocation getTextureLocation(DevourJaw pEntity) {
return IronsSpellbooks.id("textures/entity/devour_jaw.png");
}

static class DevourJawModel extends EvokerFangsModel<DevourJaw> {
private final ModelPart root;
private final ModelPart base;
private final ModelPart upperJaw;
private final ModelPart lowerJaw;

public DevourJawModel(ModelPart pRoot) {
super(pRoot);
this.root = pRoot;
this.base = pRoot.getChild("base");
this.upperJaw = pRoot.getChild("upper_jaw");
this.lowerJaw = pRoot.getChild("lower_jaw");
}

@Override
public void setupAnim(DevourJaw entity, float time, float pLimbSwingAmount, float pAgeInTicks, float pNetHeadYaw, float pHeadPitch) {
time -= entity.waitTime;
float interval = entity.warmupTime - entity.waitTime;

float f = Mth.clamp(time / interval, 0, 1);
f = 1 - f * f * f * f;
this.upperJaw.zRot = (float) Math.PI - f * 0.35F * (float) Math.PI;
this.lowerJaw.zRot = (float) Math.PI + f * 0.35F * (float) Math.PI;

float f2 = (time / interval);
f2 = .5f * Mth.cos(.5f * Mth.PI * (f2 - 1)) + .5f;
f2 *= f2;
this.upperJaw.y = -18F * f2 + 16f;
this.lowerJaw.y = this.upperJaw.y;
this.base.y = this.upperJaw.y;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import io.redspace.ironsspellbooks.entity.mobs.wizards.pyromancer.PyromancerEntity;
import io.redspace.ironsspellbooks.entity.spells.ChainLightning;
import io.redspace.ironsspellbooks.entity.spells.ExtendedWitherSkull;
import io.redspace.ironsspellbooks.entity.spells.devour_jaw.DevourJaw;
import io.redspace.ironsspellbooks.entity.spells.gust.GustCollider;
import io.redspace.ironsspellbooks.entity.spells.HealingAoe;
import io.redspace.ironsspellbooks.entity.spells.acid_orb.AcidOrb;
Expand Down Expand Up @@ -403,4 +404,10 @@ public static void register(IEventBus eventBus) {
.sized(1f, 1f)
.clientTrackingRange(64)
.build(new ResourceLocation(IronsSpellbooks.MODID, "chain_lightning").toString()));

public static final RegistryObject<EntityType<DevourJaw>> DEVOUR_JAW =
ENTITIES.register("devour_jaw", () -> EntityType.Builder.<DevourJaw>of(DevourJaw::new, MobCategory.MISC)
.sized(2f, 2f)
.clientTrackingRange(64)
.build(new ResourceLocation(IronsSpellbooks.MODID, "devour_jaw").toString()));
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public static void register(IEventBus eventBus) {
public static final RegistryObject<MobEffect> BLIGHT = MOB_EFFECT_DEFERRED_REGISTER.register("blight", () -> new BlightEffect(MobEffectCategory.HARMFUL, 0xdfff2b));
public static final RegistryObject<MobEffect> GUIDING_BOLT = MOB_EFFECT_DEFERRED_REGISTER.register("guided", () -> new GuidingBoltEffect(MobEffectCategory.HARMFUL, 16239960));
public static final RegistryObject<MobEffect> AIRBORNE = MOB_EFFECT_DEFERRED_REGISTER.register("airborne", () -> new AirborneEffect(MobEffectCategory.HARMFUL, 0xFFFFFF));
public static final RegistryObject<MobEffect> VIGOR = MOB_EFFECT_DEFERRED_REGISTER.register("vigor", () -> new MobEffect(MobEffectCategory.BENEFICIAL, 0x850d0d) {}.addAttributeModifier(Attributes.MAX_HEALTH, "d2b7228b-3ded-412e-940b-8f9f1e2cf882", 2, AttributeModifier.Operation.ADDITION));
//public static final RegistryObject<MobEffect> ROOT = MOB_EFFECT_DEFERRED_REGISTER.register("root", () -> new RootEffect(MobEffectCategory.HARMFUL, 0x604730));
//public static final RegistryObject<MobEffect> ENCHANTED_WARD = MOB_EFFECT_DEFERRED_REGISTER.register("enchanted_ward", () -> new EnchantedWardEffect(MobEffectCategory.HARMFUL, 3311322));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public static void register(IEventBus eventBus) {
public static RegistryObject<SoundEvent> GUIDING_BOLT_IMPACT = registerSoundEvent("entity.guiding_bolt.impact");
public static RegistryObject<SoundEvent> GUIDING_BOLT_CAST = registerSoundEvent("spell.guiding_bolt.cast");
public static RegistryObject<SoundEvent> CHAIN_LIGHTNING_CHAIN = registerSoundEvent("entity.chain_lightning.lightning_chain");
public static RegistryObject<SoundEvent> DEVOUR_BITE = registerSoundEvent("entity.devour_jaw.bite");

public static RegistryObject<SoundEvent> DEAD_KING_SWING = registerSoundEvent("entity.dead_king.attack_swing");
public static RegistryObject<SoundEvent> DEAD_KING_SLAM = registerSoundEvent("entity.dead_king.attack_slam");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import io.redspace.ironsspellbooks.entity.spells.comet.CometRenderer;
import io.redspace.ironsspellbooks.entity.spells.cone_of_cold.ConeOfColdRenderer;
import io.redspace.ironsspellbooks.entity.spells.creeper_head.CreeperHeadRenderer;
import io.redspace.ironsspellbooks.entity.spells.devour_jaw.DevourJawRenderer;
import io.redspace.ironsspellbooks.entity.spells.electrocute.ElectrocuteRenderer;
import io.redspace.ironsspellbooks.entity.spells.fireball.FireballRenderer;
import io.redspace.ironsspellbooks.entity.spells.firebolt.FireboltRenderer;
Expand Down Expand Up @@ -237,6 +238,7 @@ public static void rendererRegister(EntityRenderersEvent.RegisterRenderers event
event.registerEntityRenderer(EntityRegistry.GUIDING_BOLT.get(), GuidingBoltRenderer::new);
event.registerEntityRenderer(EntityRegistry.GUST_COLLIDER.get(), GustRenderer::new);
event.registerEntityRenderer(EntityRegistry.CHAIN_LIGHTNING.get(), NoopRenderer::new);
event.registerEntityRenderer(EntityRegistry.DEVOUR_JAW.get(), DevourJawRenderer::new);

event.registerBlockEntityRenderer(BlockRegistry.SCROLL_FORGE_TILE.get(), ScrollForgeRenderer::new);
event.registerBlockEntityRenderer(BlockRegistry.PEDESTAL_TILE.get(), PedestalRenderer::new);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,9 @@ public enum SpellType {
GUIDING_BOLT_SPELL(62, GuidingBoltSpell::new),
SUNBEAM_SPELL(63, SunbeamSpell::new),
GUST_SPELL(64, GustSpell::new),
CHAIN_LIGHTNING_SPELL(65, ChainLightningSpell::new);
CHAIN_LIGHTNING_SPELL(65, ChainLightningSpell::new),
DEVOUR_SPELL(66, DevourSpell::new),
;

private final int value;
private final int maxRarity;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package io.redspace.ironsspellbooks.spells.blood;

import io.redspace.ironsspellbooks.capabilities.magic.CastTargetingData;
import io.redspace.ironsspellbooks.capabilities.magic.PlayerMagicData;
import io.redspace.ironsspellbooks.entity.spells.devour_jaw.DevourJaw;
import io.redspace.ironsspellbooks.spells.*;
import io.redspace.ironsspellbooks.util.Utils;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.level.Level;

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


public class DevourSpell extends AbstractSpell {
public DevourSpell() {
this(1);
}

@Override
public List<MutableComponent> getUniqueInfo(LivingEntity caster) {
return List.of(
Component.translatable("ui.irons_spellbooks.damage", Utils.stringTruncation(getDamage(caster), 1)),
Component.translatable("ui.irons_spellbooks.max_hp_on_kill", getHpBonus(caster))
);
}

public static DefaultConfig defaultConfig = new DefaultConfig()
.setMinRarity(SpellRarity.UNCOMMON)
.setSchool(SchoolType.BLOOD)
.setMaxLevel(10)
.setCooldownSeconds(20)
.build();

public DevourSpell(int level) {
super(SpellType.DEVOUR_SPELL);
this.setLevel(level);
this.manaCostPerLevel = 4;
this.baseSpellPower = 6;
this.spellPowerPerLevel = 1;
this.castTime = 0;
this.baseManaCost = 25;

}

@Override
public Optional<SoundEvent> getCastStartSound() {
return Optional.empty();
}

@Override
public Optional<SoundEvent> getCastFinishSound() {
return Optional.empty();
}


@Override
public boolean checkPreCastConditions(Level level, LivingEntity entity, PlayerMagicData playerMagicData) {
return Utils.preCastTargetHelper(level, entity, playerMagicData, getSpellType(), 6, .1f);
}

@Override
public void onCast(Level world, LivingEntity entity, PlayerMagicData playerMagicData) {
if (playerMagicData.getAdditionalCastData() instanceof CastTargetingData targetData) {
var targetEntity = targetData.getTarget((ServerLevel) world);
if (targetEntity != null) {
targetEntity.setDeltaMovement(targetEntity.getDeltaMovement().add(targetEntity.position().subtract(entity.position()).scale(-.25f)));
targetEntity.hurtMarked = true;
DevourJaw devour = new DevourJaw(world, entity, targetEntity);
devour.setPos(targetEntity.position());
devour.setYRot(entity.getYRot());
devour.setDamage(getDamage(entity));
devour.vigorLevel = (getHpBonus(entity) / 2) - 1;
world.addFreshEntity(devour);
}
}

super.onCast(world, entity, playerMagicData);
}

public float getDamage(LivingEntity caster) {
return getSpellPower(caster);
}

public int getHpBonus(LivingEntity caster) {
return 2 * (int) (getSpellPower(caster) * .25f);
}

}
Loading

0 comments on commit 316942a

Please sign in to comment.