1+ package dev .overgrown .thaumaturge .spell .impl .victus ;
2+
3+ import dev .overgrown .thaumaturge .registry .ModSounds ;
4+ import dev .overgrown .thaumaturge .spell .modifier .ModifierEffect ;
5+ import dev .overgrown .thaumaturge .spell .modifier .PowerModifierEffect ;
6+ import dev .overgrown .thaumaturge .spell .pattern .AspectEffect ;
7+ import dev .overgrown .thaumaturge .spell .tier .AoeSpellDelivery ;
8+ import dev .overgrown .thaumaturge .spell .tier .SelfSpellDelivery ;
9+ import dev .overgrown .thaumaturge .spell .tier .TargetedSpellDelivery ;
10+ import net .minecraft .entity .LivingEntity ;
11+ import net .minecraft .particle .ParticleTypes ;
12+ import net .minecraft .server .network .ServerPlayerEntity ;
13+ import net .minecraft .server .world .ServerWorld ;
14+ import net .minecraft .sound .SoundCategory ;
15+ import net .minecraft .util .math .BlockPos ;
16+ import net .minecraft .world .World ;
17+
18+ import java .util .List ;
19+
20+ public class VictusEffect implements AspectEffect {
21+ private static final float BASE_HEALING = 2.0F ; // 1 heart
22+ private static final float BASE_DAMAGE = 2.0F ; // 1 heart of damage
23+
24+ @ Override
25+ public void applySelf (SelfSpellDelivery delivery ) {
26+ ServerPlayerEntity caster = delivery .getCaster ();
27+ playSound (caster .getWorld (), caster .getX (), caster .getY (), caster .getZ ());
28+ applyVictusEffect (caster , getPowerMultiplier (delivery .getModifiers ()), caster );
29+ }
30+
31+ @ Override
32+ public void applyTargeted (TargetedSpellDelivery delivery ) {
33+ if (delivery .isEntityTarget () && delivery .getTargetEntity () instanceof LivingEntity target ) {
34+ playSound (delivery .getWorld (), target .getX (), target .getY (), target .getZ ());
35+ applyVictusEffect (target , getPowerMultiplier (delivery .getModifiers ()), delivery .getCaster ());
36+ } else if (delivery .isBlockTarget ()) {
37+ BlockPos pos = delivery .getBlockPos ();
38+ playSound (delivery .getWorld (), pos .getX () + 0.5 , pos .getY () + 0.5 , pos .getZ () + 0.5 );
39+ }
40+ }
41+
42+ @ Override
43+ public void applyAoe (AoeSpellDelivery delivery ) {
44+ BlockPos center = delivery .getCenter ();
45+ playSound (delivery .getWorld (), center .getX () + 0.5 , center .getY () + 0.5 , center .getZ () + 0.5 );
46+
47+ float multiplier = getPowerMultiplier (delivery .getModifiers ());
48+ List <LivingEntity > entities = delivery .getEntitiesInAabb (LivingEntity .class , entity -> true );
49+
50+ for (LivingEntity entity : entities ) {
51+ applyVictusEffect (entity , multiplier , delivery .getCaster ());
52+ }
53+ }
54+
55+ private void playSound (World world , double x , double y , double z ) {
56+ if (world instanceof ServerWorld serverWorld ) {
57+ serverWorld .playSound (
58+ null , // No specific player
59+ x , y , z ,
60+ ModSounds .VICTUS_SPELL_CAST ,
61+ SoundCategory .PLAYERS ,
62+ 1.0F , 1.0F ,
63+ serverWorld .random .nextLong ()
64+ );
65+ }
66+ }
67+
68+ private float getPowerMultiplier (List <ModifierEffect > modifiers ) {
69+ for (ModifierEffect mod : modifiers ) {
70+ if (mod instanceof PowerModifierEffect powerMod ) {
71+ return powerMod .getMultiplier ();
72+ }
73+ }
74+ return 1.0F ;
75+ }
76+
77+ private void applyVictusEffect (LivingEntity target , float powerMultiplier , ServerPlayerEntity caster ) {
78+ float amount = target .isUndead () ? BASE_DAMAGE * powerMultiplier : BASE_HEALING * powerMultiplier ;
79+
80+ if (target .isUndead ()) {
81+ target .damage (target .getWorld ().getDamageSources ().magic (), amount );
82+ } else {
83+ target .heal (amount );
84+ if (target .isAlive ()) {
85+ spawnHealParticles ((ServerWorld ) target .getWorld (), target );
86+ }
87+ }
88+ }
89+
90+ private void spawnHealParticles (ServerWorld world , LivingEntity entity ) {
91+ double x = entity .getX ();
92+ double y = entity .getY () + entity .getHeight () * 0.5 ;
93+ double z = entity .getZ ();
94+ world .spawnParticles (ParticleTypes .HEART , x , y , z , 5 , 0.5 , 0.5 , 0.5 , 0.0 );
95+ }
96+ }
0 commit comments