mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Added bubble spell
This commit is contained in:
parent
ef318822c1
commit
3c065ac097
3 changed files with 176 additions and 0 deletions
|
@ -0,0 +1,173 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.minelittlepony.unicopia.USounds;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.*;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||
import com.minelittlepony.unicopia.entity.*;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.particle.ParticleHandle;
|
||||
import com.minelittlepony.unicopia.particle.SphereParticleEffect;
|
||||
import com.minelittlepony.unicopia.particle.UParticles;
|
||||
import com.minelittlepony.unicopia.particle.ParticleHandle.Attachment;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
import com.minelittlepony.unicopia.projectile.ProjectileDelegate;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.attribute.*;
|
||||
import net.minecraft.entity.attribute.EntityAttributeModifier.Operation;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.util.hit.EntityHitResult;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public class BubbleSpell extends AbstractSpell implements TimedSpell,
|
||||
ProjectileDelegate.EntityHitListener {
|
||||
private static final EntityAttributeModifier GRAVITY_MODIFIER =
|
||||
new EntityAttributeModifier(UUID.fromString("9dc7818b-927b-46e0-acbe-48d31a28128f"), "Bubble Floating", 0.02D - 1D, Operation.MULTIPLY_TOTAL);
|
||||
private static final EntityAttributeModifier SPEED_MODIFIER =
|
||||
new EntityAttributeModifier(UUID.fromString("9dc7818b-927b-46e0-acbe-48d31a28128f"), "Bubble Floating", 0.01D - 1D, Operation.MULTIPLY_TOTAL);
|
||||
|
||||
private static final Map<EntityAttribute, EntityAttributeModifier> MODIFIERS = Map.of(
|
||||
UEntityAttributes.ENTITY_GRAVTY_MODIFIER, GRAVITY_MODIFIER,
|
||||
UEntityAttributes.EXTENDED_REACH_DISTANCE, GRAVITY_MODIFIER,
|
||||
UEntityAttributes.EXTENDED_ATTACK_DISTANCE, GRAVITY_MODIFIER,
|
||||
EntityAttributes.GENERIC_MOVEMENT_SPEED, SPEED_MODIFIER,
|
||||
EntityAttributes.GENERIC_FLYING_SPEED, SPEED_MODIFIER
|
||||
);
|
||||
|
||||
public static final SpellTraits DEFAULT_TRAITS = new SpellTraits.Builder()
|
||||
.with(Trait.FOCUS, 6)
|
||||
.with(Trait.POWER, 1)
|
||||
.build();
|
||||
|
||||
protected final ParticleHandle particlEffect = new ParticleHandle();
|
||||
|
||||
private final Timer timer;
|
||||
|
||||
private int struggles;
|
||||
private float radius;
|
||||
|
||||
protected BubbleSpell(CustomisedSpellType<?> type) {
|
||||
super(type);
|
||||
timer = new Timer((120 + (int)(getTraits().get(Trait.FOCUS, 0, 160) * 19)) * 20);
|
||||
struggles = (int)(getTraits().get(Trait.POWER) * 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timer getTimer() {
|
||||
return timer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Caster<?> source) {
|
||||
|
||||
if (getType().isOn(source)) {
|
||||
source.getSpellSlot().removeWhere(getType(), true);
|
||||
return false;
|
||||
}
|
||||
|
||||
Entity entity = source.asEntity();
|
||||
|
||||
if (entity instanceof LivingEntity l) {
|
||||
MODIFIERS.forEach((attribute, modifier) -> {
|
||||
if (l.getAttributes().hasAttribute(attribute)) {
|
||||
l.getAttributeInstance(attribute).addPersistentModifier(modifier);
|
||||
}
|
||||
});
|
||||
}
|
||||
radius = Math.max(entity.getHeight(), entity.getWidth()) * 1.2F;
|
||||
source.playSound(USounds.ENTITY_PLAYER_UNICORN_TELEPORT, 1);
|
||||
entity.addVelocity(0, 0.2F * source.getPhysics().getGravitySignum(), 0);
|
||||
Living.updateVelocity(entity);
|
||||
|
||||
return super.apply(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tick(Caster<?> source, Situation situation) {
|
||||
|
||||
if (situation == Situation.PROJECTILE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
timer.tick();
|
||||
|
||||
if (timer.getTicksRemaining() <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
setDirty();
|
||||
|
||||
source.asEntity().addVelocity(
|
||||
MathHelper.sin(source.asEntity().age / 6F) / 50F,
|
||||
MathHelper.sin(source.asEntity().age / 6F) / 50F,
|
||||
MathHelper.sin(source.asEntity().age / 6F) / 50F
|
||||
);
|
||||
|
||||
source.asEntity().fallDistance = 0;
|
||||
|
||||
Vec3d origin = source.getOriginVector();
|
||||
|
||||
if (source instanceof Pony pony && pony.sneakingChanged() && pony.asEntity().isSneaking()) {
|
||||
setDirty();
|
||||
radius += 0.5F;
|
||||
source.playSound(SoundEvents.BLOCK_HONEY_BLOCK_STEP, 1);
|
||||
if (struggles-- <= 0) {
|
||||
setDead();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
particlEffect.update(getUuid(), source, spawner -> {
|
||||
spawner.addParticle(new SphereParticleEffect(UParticles.SPHERE, 0xFFFFFF, 0.3F, 0, new Vec3d(0, radius / 2F, 0)), origin, Vec3d.ZERO);
|
||||
}).ifPresent(p -> {
|
||||
p.setAttribute(Attachment.ATTR_RADIUS, radius);
|
||||
});
|
||||
|
||||
return !isDead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyed(Caster<?> source) {
|
||||
particlEffect.destroy();
|
||||
if (source.asEntity() instanceof LivingEntity l) {
|
||||
MODIFIERS.forEach((attribute, modifier) -> {
|
||||
if (l.getAttributes().hasAttribute(attribute)) {
|
||||
l.getAttributeInstance(attribute).removeModifier(modifier);
|
||||
}
|
||||
});
|
||||
}
|
||||
source.playSound(USounds.ENTITY_PLAYER_UNICORN_TELEPORT, 1);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onImpact(MagicProjectileEntity projectile, EntityHitResult hit) {
|
||||
Caster.of(hit.getEntity()).ifPresent(caster -> {
|
||||
getTypeAndTraits().apply(caster);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toNBT(NbtCompound compound) {
|
||||
super.toNBT(compound);
|
||||
compound.putInt("struggles", struggles);
|
||||
compound.putFloat("radius", radius);
|
||||
timer.toNBT(compound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromNBT(NbtCompound compound) {
|
||||
super.fromNBT(compound);
|
||||
struggles = compound.getInt("struggles");
|
||||
radius = compound.getFloat("radius");
|
||||
timer.fromNBT(compound);
|
||||
}
|
||||
}
|
|
@ -65,6 +65,7 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
|||
public static final SpellType<MimicSpell> MIMIC = register("mimic", Affinity.GOOD, 0xFFFF00, true, SpellTraits.EMPTY, MimicSpell::new);
|
||||
public static final SpellType<MindSwapSpell> MIND_SWAP = register("mind_swap", Affinity.BAD, 0xF9FF99, true, SpellTraits.EMPTY, MindSwapSpell::new);
|
||||
public static final SpellType<HydrophobicSpell> HYDROPHOBIC = register("hydrophobic", Affinity.NEUTRAL, 0xF999FF, true, SpellTraits.EMPTY, s -> new HydrophobicSpell(s, FluidTags.WATER));
|
||||
public static final SpellType<BubbleSpell> BUBBLE = register("bubble", Affinity.NEUTRAL, 0xF999FF, true, BubbleSpell.DEFAULT_TRAITS, BubbleSpell::new);
|
||||
|
||||
public static void bootstrap() {}
|
||||
|
||||
|
|
|
@ -204,6 +204,8 @@
|
|||
"spell.unicopia.fire_bolt.lore": "Produces several burning projectiles",
|
||||
"spell.unicopia.shield": "Protection",
|
||||
"spell.unicopia.shield.lore": "Casts a protective shield around the user",
|
||||
"spell.unicopia.bubble": "Bubble",
|
||||
"spell.unicopia.bubble.lore": "Traps any creature it hits in a soap bubble",
|
||||
"spell.unicopia.arcane_protection": "Arcane Protections",
|
||||
"spell.unicopia.arcane_protection.lore": "Creates a protective shroud over an area in which no other spells can be cast",
|
||||
"spell.unicopia.vortex": "Arcane Attraction",
|
||||
|
|
Loading…
Reference in a new issue