Skip to content

Commit

Permalink
More work on the staff
Browse files Browse the repository at this point in the history
  • Loading branch information
SammySemicolon committed Dec 5, 2023
1 parent 2ae78d2 commit f8fa6c8
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,15 @@ public HexProjectileEntityRenderer(EntityRendererProvider.Context context) {
this.shadowStrength = 0;
}

private static final ResourceLocation SAW = malumPath("textures/particle/saw.png");
private static final RenderType ADDITIVE_SAW = LodestoneRenderTypeRegistry.ADDITIVE_TEXTURE.apply(SAW);
private static final RenderType LUMITRANSPARENT_SAW = LodestoneRenderTypeRegistry.TRANSPARENT_TEXTURE.apply(SAW, ShaderUniformHandler.LUMITRANSPARENT);

private static final ResourceLocation LIGHT_TRAIL = malumPath("textures/vfx/concentrated_trail.png");
private static final RenderType TRAIL_TYPE = LodestoneRenderTypeRegistry.ADDITIVE_TEXTURE_TRIANGLE.apply(LIGHT_TRAIL);

@Override
public void render(HexProjectileEntity entity, float entityYaw, float partialTicks, PoseStack poseStack, MultiBufferSource bufferIn, int packedLightIn) {
float effectScalar = entity.fadingAway ? 1 - (entity.age - 70) / 10f : 1;
if (entity.spawnDelay > 0) {
return;
}
float effectScalar = entity.fadingAway ? 1 - (entity.age - HexProjectileEntity.MAX_AGE + 10) / 10f : 1;
List<TrailPoint> spinningTrailPoints = entity.spinningTrailPointBuilder.getTrailPoints(partialTicks);
List<TrailPoint> trailPoints = entity.trailPointBuilder.getTrailPoints(partialTicks);
poseStack.pushPose();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,16 @@

public class HexProjectileEntity extends ThrowableItemProjectile {

public static final int MAX_AGE = 60;
protected static final EntityDataAccessor<Boolean> DATA_FADING_AWAY = SynchedEntityData.defineId(HexProjectileEntity.class, EntityDataSerializers.BOOLEAN);
protected static final EntityDataAccessor<Integer> DATA_SPAWN_DELAY = SynchedEntityData.defineId(HexProjectileEntity.class, EntityDataSerializers.INT);

public final TrailPointBuilder spinningTrailPointBuilder = TrailPointBuilder.create(20);
public float spinOffset = (float) (random.nextFloat() * Math.PI * 2);
public final TrailPointBuilder trailPointBuilder = TrailPointBuilder.create(12);
protected float magicDamage;
public int age;
public int spawnDelay;
public int soundCooldown = 20 + random.nextInt(100);

public boolean fadingAway;
Expand All @@ -53,22 +56,29 @@ public HexProjectileEntity(Level level, double pX, double pY, double pZ) {
noPhysics = false;
}

public void setData(Entity owner, float magicDamage) {
public void setData(Entity owner, float magicDamage, int spawnDelay) {
setOwner(owner);
this.magicDamage = magicDamage;
getEntityData().set(DATA_SPAWN_DELAY, spawnDelay);
}

@Override
protected void defineSynchedData() {
this.getEntityData().define(DATA_FADING_AWAY, false);
this.getEntityData().define(DATA_SPAWN_DELAY, 0);
super.defineSynchedData();
}

@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> pKey) {
if (DATA_FADING_AWAY.equals(pKey)) {
fadingAway = entityData.get(DATA_FADING_AWAY);
age = 70;
if (fadingAway) {
age = MAX_AGE - 10;
}
}
if (DATA_SPAWN_DELAY.equals(pKey)) {
spawnDelay = entityData.get(DATA_SPAWN_DELAY);
}
super.onSyncedDataUpdated(pKey);
}
Expand All @@ -81,6 +91,9 @@ public void addAdditionalSaveData(CompoundTag compound) {
if (age != 0) {
compound.putInt("age", age);
}
if (spawnDelay != 0) {
compound.putInt("spawnDelay", spawnDelay);
}
if (fadingAway) {
compound.putBoolean("fadingAway", true);
}
Expand All @@ -91,6 +104,7 @@ public void readAdditionalSaveData(CompoundTag compound) {
super.readAdditionalSaveData(compound);
magicDamage = compound.getFloat("magicDamage");
age = compound.getInt("age");
getEntityData().set(DATA_SPAWN_DELAY, compound.getInt("spawnDelay"));
getEntityData().set(DATA_FADING_AWAY, compound.getBoolean("fadingAway"));
}

Expand All @@ -108,7 +122,7 @@ protected boolean canHitEntity(Entity pTarget) {

@Override
protected void onHitEntity(EntityHitResult result) {
if (fadingAway) {
if (fadingAway || spawnDelay != 0) {
return;
}
if (getOwner() instanceof LivingEntity staveOwner) {
Expand All @@ -122,7 +136,7 @@ protected void onHitEntity(EntityHitResult result) {
if (success && target instanceof LivingEntity livingentity) {
ItemStack stave = getItem();
ItemHelper.applyEnchantments(staveOwner, livingentity, stave);
int i = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.FIRE_ASPECT, stave);
int i = stave.getEnchantmentLevel(Enchantments.FIRE_ASPECT);
if (i > 0) {
livingentity.setSecondsOnFire(i * 4);
}
Expand All @@ -137,6 +151,10 @@ protected void onHitEntity(EntityHitResult result) {

@Override
public void tick() {
if (spawnDelay > 0) {
spawnDelay--;
return;
}
super.tick();
Vec3 motion = getDeltaMovement();
if (!fadingAway) {
Expand All @@ -160,7 +178,7 @@ public void tick() {
trailPointBuilder.tickTrailPoints();
}
age++;
if (age >= 80) {
if (age >= MAX_AGE) {
remove(RemovalReason.DISCARDED);
}
if (this.xRotO == 0.0F && this.yRotO == 0.0F) {
Expand All @@ -169,7 +187,7 @@ public void tick() {
xRotO = getXRot();
}
if (level().isClientSide && !fadingAway) {
float scalar = age > 70 ? 1f - (age - 70) / 10f : 1f;
float scalar = age > MAX_AGE ? 1f - (age - MAX_AGE + 10) / 10f : 1f;
Vec3 norm = motion.normalize().scale(0.05f);
var lightSpecs = SpiritLightSpecs.spiritLightSpecs(level(), position(), SpiritTypeRegistry.WICKED_SPIRIT);
lightSpecs.getBuilder().multiplyLifetime(1.25f).setMotion(norm);
Expand All @@ -180,11 +198,13 @@ public void tick() {
DirectionalParticleBuilder.create(ParticleRegistry.SAW)
.setTransparencyData(GenericParticleData.create(0.9f * scalar, 0.4f * scalar, 0f).setEasing(Easing.SINE_IN_OUT, Easing.SINE_IN).build())
.setSpinData(spinData)
.setScaleData(GenericParticleData.create(0.5f * scalar, 0).setEasing(Easing.SINE_IN_OUT).build())
.setScaleData(GenericParticleData.create(0.4f * scalar, 0).setEasing(Easing.SINE_IN_OUT).build())
.setColorData(SpiritTypeRegistry.WICKED_SPIRIT.createMainColorData().build())
.setLifetime(Math.min(age * 3, 30))
.setDirection(getDeltaMovement().normalize())
.enableNoClip()
.enableForcedSpawn()
.disableCull()
.setSpritePicker(SimpleParticleOptions.ParticleSpritePicker.RANDOM_SPRITE)
.addTickActor(behavior)
.spawn(level(), position().x, position().y, position().z)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public void spawnParticles(double x, double y, double z) {
public void move() {
if (soundCooldown-- == 0) {
if (random.nextFloat() < 0.4f) {
level().playSound(null, blockPosition(), SoundRegistry.ARCANE_WHISPERS.get(), SoundSource.NEUTRAL, 0.3f, Mth.nextFloat(random, 1.1f, 2f));
level().playSound(null, blockPosition(), SoundRegistry.ARCANE_WHISPERS.get(), SoundSource.NEUTRAL, 0.3f, Mth.nextFloat(random, 0.8f, 2f));
}
soundCooldown = random.nextInt(40) + 40;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,31 @@

import com.google.common.collect.*;
import com.sammy.malum.common.entity.*;
import com.sammy.malum.registry.client.*;
import com.sammy.malum.registry.common.*;
import com.sammy.malum.registry.common.item.*;
import net.minecraft.stats.*;
import net.minecraft.util.*;
import net.minecraft.world.*;
import net.minecraft.world.entity.*;
import net.minecraft.world.entity.ai.attributes.*;
import net.minecraft.world.entity.player.*;
import net.minecraft.world.item.*;
import net.minecraft.world.item.enchantment.*;
import net.minecraft.world.level.*;
import net.minecraft.world.phys.*;
import team.lodestar.lodestone.helpers.*;
import team.lodestar.lodestone.registry.common.*;
import team.lodestar.lodestone.systems.easing.*;
import team.lodestar.lodestone.systems.particle.*;
import team.lodestar.lodestone.systems.particle.builder.*;
import team.lodestar.lodestone.systems.particle.data.*;
import team.lodestar.lodestone.systems.particle.data.spin.*;
import team.lodestar.lodestone.systems.particle.render_types.*;
import team.lodestar.lodestone.systems.particle.world.*;

import java.util.*;
import java.util.function.*;

public class MagicStaveItem extends MalumStaveItem {

Expand All @@ -31,26 +45,94 @@ public ImmutableMultimap.Builder<Attribute, AttributeModifier> createExtraAttrib
}

@Override
public InteractionResultHolder<ItemStack> use(Level pLevel, Player pPlayer, InteractionHand pUsedHand) {
ItemStack stack = pPlayer.getItemInHand(pUsedHand);
Level level = pPlayer.level();
if (!level.isClientSide && !pPlayer.getCooldowns().isOnCooldown(stack.getItem())) {
float magicDamage = (float) pPlayer.getAttributes().getValue(LodestoneAttributeRegistry.MAGIC_DAMAGE.get());
int angle = pUsedHand == InteractionHand.MAIN_HAND ? 225 : 90;
Vec3 pos = pPlayer.position().add(pPlayer.getLookAngle().scale(0.5)).add(0.5 * Math.sin(Math.toRadians(angle - pPlayer.yHeadRot)), pPlayer.getBbHeight() * 2 / 3, 0.5 * Math.cos(Math.toRadians(angle - pPlayer.yHeadRot)));
public void onUseTick(Level pLevel, LivingEntity pLivingEntity, ItemStack pStack, int pRemainingUseDuration) {
if (pLevel.isClientSide) {
RandomSource random = pLevel.random;
InteractionHand hand = pLivingEntity.getUsedItemHand();
Vec3 pos = getProjectileSpawnPos(pLivingEntity, hand, 1.5f, 0.6f);
float pct = Math.min(20, getUseDuration(pStack) - pRemainingUseDuration) / 20f;
final SpinParticleData spinData = SpinParticleData.createRandomDirection(random, 0.25f, 0.5f).setSpinOffset(RandomHelper.randomBetween(random, 0f, 6.28f)).build();
DirectionalParticleBuilder.create(ParticleRegistry.HEXAGON)
.setTransparencyData(GenericParticleData.create(0.6f * pct, 0f).setEasing(Easing.SINE_IN_OUT, Easing.SINE_IN).build())
.setSpinData(spinData)
.setScaleData(GenericParticleData.create(0.3f * pct, 0).setEasing(Easing.SINE_IN_OUT).build())
.setColorData(SpiritTypeRegistry.WICKED_SPIRIT.createMainColorData().build())
.setLifetime(5)
.setDirection(pLivingEntity.getLookAngle().normalize())
.setMotion(pLivingEntity.getLookAngle().normalize().scale(0.05f))
.enableNoClip()
.enableForcedSpawn()
.disableCull()
.setLifeDelay(2)
.setSpritePicker(SimpleParticleOptions.ParticleSpritePicker.RANDOM_SPRITE)
.spawn(pLevel, pos.x, pos.y, pos.z)
.setRenderType(LodestoneWorldParticleRenderType.LUMITRANSPARENT)
.spawn(pLevel, pos.x, pos.y, pos.z);
}

super.onUseTick(pLevel, pLivingEntity, pStack, pRemainingUseDuration);
}

@Override
public void releaseUsing(ItemStack pStack, Level pLevel, LivingEntity pLivingEntity, int pTimeCharged) {
if (pTimeCharged <= getUseDuration(pStack) - 20) {
InteractionHand hand = pLivingEntity.getUsedItemHand();
for (int i = 0; i < 3; i++) {
fireProjectile(pLivingEntity, pStack, pLevel, hand, i);
}
if (pLivingEntity instanceof Player player) {
player.awardStat(Stats.ITEM_USED.get(this));
if (!player.getAbilities().instabuild) {
pStack.hurtAndBreak(1, player, (p_220009_1_) -> {
p_220009_1_.broadcastBreakEvent(hand);
});
player.getCooldowns().addCooldown(this, 80);
}
player.swing(hand, true);
}
}
super.releaseUsing(pStack, pLevel, pLivingEntity, pTimeCharged);
}

@Override
public InteractionResultHolder<ItemStack> use(Level pLevel, Player pPlayer, InteractionHand pHand) {
ItemStack itemstack = pPlayer.getItemInHand(pHand);
if (pPlayer.getCooldowns().isOnCooldown(itemstack.getItem())) {
return InteractionResultHolder.fail(itemstack);
} else {
pPlayer.startUsingItem(pHand);
return InteractionResultHolder.consume(itemstack);
}
}

@Override
public int getUseDuration(ItemStack pStack) {
return 72000;
}

@Override
public UseAnim getUseAnimation(ItemStack pStack) {
return UseAnim.BOW;
}

public void fireProjectile(LivingEntity player, ItemStack stack, Level level, InteractionHand hand, int count) {
if (!level.isClientSide) {
float pitchOffset = 3f + count;
int spawnDelay = count * 3;
float velocity = 2.5f + 0.5f * count;
float magicDamage = (float) player.getAttributes().getValue(LodestoneAttributeRegistry.MAGIC_DAMAGE.get()) * 1.5f;
Vec3 pos = getProjectileSpawnPos(player, hand, 0.5f, 0.5f);
HexProjectileEntity entity = new HexProjectileEntity(level, pos.x, pos.y, pos.z);
entity.setData(pPlayer, magicDamage);
entity.setData(player, magicDamage, spawnDelay);
entity.setItem(stack);

entity.shootFromRotation(pPlayer, pPlayer.getXRot(), pPlayer.getYRot(), 0.0F, 1.75f, 0F);
entity.shootFromRotation(player, player.getXRot(), player.getYRot(), -pitchOffset, velocity, 0F);
level.addFreshEntity(entity);
stack.hurtAndBreak(1, pPlayer, (p_220009_1_) -> {
p_220009_1_.broadcastBreakEvent(pUsedHand);
});
pPlayer.getCooldowns().addCooldown(stack.getItem(), 15);
return InteractionResultHolder.success(stack);
}
pPlayer.awardStat(Stats.ITEM_USED.get(stack.getItem()));
return super.use(pLevel, pPlayer, pUsedHand);
}

public Vec3 getProjectileSpawnPos(LivingEntity player, InteractionHand hand, float distance, float spread) {
int angle = hand == InteractionHand.MAIN_HAND ? 225 : 90;
return player.position().add(player.getLookAngle().scale(distance)).add(spread * Math.sin(Math.toRadians(angle - player.yHeadRot)), player.getBbHeight() * 0.9f, spread * Math.cos(Math.toRadians(angle - player.yHeadRot)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public class EntityRegistry {
.build(MalumMod.malumPath("scythe_boomerang").toString()));

public static final RegistryObject<EntityType<HexProjectileEntity>> HEX_BOLT = ENTITY_TYPES.register("hex_bolt",
() -> EntityType.Builder.<HexProjectileEntity>of((e, w) -> new HexProjectileEntity(w), MobCategory.MISC).sized(0.8F, 0.8F).clientTrackingRange(10)
() -> EntityType.Builder.<HexProjectileEntity>of((e, w) -> new HexProjectileEntity(w), MobCategory.MISC).sized(1F, 1.2F).clientTrackingRange(10)
.build(MalumMod.malumPath("hex_bolt").toString()));

@Mod.EventBusSubscriber(modid = MalumMod.MALUM, value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,23 +71,28 @@ public Supplier<ParticleEffectActor> get() {
Vec3 spawnPosition = pos.add(direction.scale(distance));
direction = direction.reverse();
float lifetimeMultiplier = 0.7f;
if (random.nextFloat() < 0.75f) {
if (random.nextFloat() < 0.8f) {
var lightSpecs = spiritLightSpecs(level, spawnPosition, spiritType);
lightSpecs.getBuilder()
.multiplyLifetime(lifetimeMultiplier)
.disableCull()
.enableForcedSpawn()
.modifyData(WorldParticleBuilder::getScaleData, d -> d.multiplyValue(1.75f))
.setMotion(direction);
lightSpecs.getBloomBuilder()
.multiplyLifetime(lifetimeMultiplier)
.setMotion(direction);
lightSpecs.spawnParticles();
}
if (random.nextFloat() < 0.75f) {
if (random.nextFloat() < 0.8f) {
var sparks = SparkParticleEffects.spiritMotionSparks(level, spawnPosition, spiritType);
sparks.getBuilder()
.multiplyLifetime(lifetimeMultiplier)
.disableCull()
.enableForcedSpawn()
.setMotion(direction.scale(1.5f))
.modifyData(SparkParticleBuilder::getScaleData, d -> d.multiplyValue(1.5f))
.modifyData(SparkParticleBuilder::getLengthData, d -> d.multiplyValue(2.5f));
.modifyData(SparkParticleBuilder::getScaleData, d -> d.multiplyValue(1.75f))
.modifyData(SparkParticleBuilder::getLengthData, d -> d.multiplyValue(3f));
sparks.getBloomBuilder()
.multiplyLifetime(lifetimeMultiplier)
.setMotion(direction.scale(1.5f));
Expand Down
4 changes: 2 additions & 2 deletions src/main/resources/assets/malum/sounds.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"arcana_entry_opened": { "sounds":["malum:codex/book_entry_open1", "malum:codex/book_entry_open2", "malum:codex/book_entry_open3", "malum:codex/book_entry_open4"], "subtitle": "malum.subtitle.arcana_entry_opened" },
"arcana_entry_closed": { "sounds":["malum:codex/book_entry_close1", "malum:codex/book_entry_close2", "malum:codex/book_entry_close3", "malum:codex/book_entry_close4"], "subtitle": "malum.subtitle.arcana_entry_closed" },
"arcana_page_flipped": { "sounds":["malum:codex/book_page_turn1", "malum:codex/book_page_turn2", "malum:codex/book_page_turn3", "malum:codex/book_page_turn4"], "subtitle": "malum.subtitle.arcana_page_flipped" },
"arcana_sweetener_normal": { "sounds":["malum:codex/book_swtnr_normal1", "malum:codex/book_swtnr_normal2", "malum:codex/book_swtnr_normal3", "malum:codex/book_swtnr_normal4", "malum:codex/book_swtnr_normal5", "malum:codex/book_swtnr_normal6"]},
"arcana_sweetener_evil": { "sounds":["malum:codex/book_swtnr_evil1", "malum:codex/book_swtnr_evil2", "malum:codex/book_swtnr_evil3", "malum:codex/book_swtnr_evil4", "malum:codex/book_swtnr_evil5", "malum:codex/book_swtnr_evil6"]},
"arcana_sweetener_normal": { "sounds":["malum:codex/book_swtnr_normal1", "malum:codex/book_swtnr_normal2", "malum:codex/book_swtnr_normal3", "malum:codex/book_swtnr_normal4", "malum:codex/book_swtnr_normal5", "malum:codex/book_swtnr_normal6", "malum:codex/book_swtnr_normal7", "malum:codex/book_swtnr_normal8", "malum:codex/book_swtnr_normal6"]},
"arcana_sweetener_evil": { "sounds":["malum:codex/book_swtnr_evil1", "malum:codex/book_swtnr_evil2", "malum:codex/book_swtnr_evil3", "malum:codex/book_swtnr_evil4", "malum:codex/book_swtnr_evil5", "malum:codex/book_swtnr_evil6", "malum:codex/book_swtnr_evil7", "malum:codex/book_swtnr_evil8", "malum:codex/book_swtnr_evil6"]},
"arcana_transition_normal": { "sounds":["malum:codex/book_transition_normal1", "malum:codex/book_transition_normal2"], "subtitle": "malum.subtitle.arcana_transition_normal" },
"arcana_transition_evil": { "sounds":["malum:codex/book_transition_evil1", "malum:codex/book_transition_evil2"], "subtitle": "malum.subtitle.arcana_transition_evil" },

Expand Down

0 comments on commit f8fa6c8

Please sign in to comment.