Added a second kirin ability

This commit is contained in:
Sollace 2023-10-10 20:13:45 +01:00
parent 577f5c8bb8
commit fcab76fd43
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
7 changed files with 123 additions and 3 deletions

View file

@ -55,6 +55,7 @@ public interface Abilities {
// kirin // kirin
Ability<?> RAGE = register(new KirinRageAbility(), "rage", AbilitySlot.PRIMARY); Ability<?> RAGE = register(new KirinRageAbility(), "rage", AbilitySlot.PRIMARY);
Ability<?> NIRIK_BLAST = register(new NirikBlastAbility(), "nirik_blast", AbilitySlot.SECONDARY);
Ability<?> KIRIN_CAST = register(new KirinCastingAbility(), "kirin_cast", AbilitySlot.SECONDARY); Ability<?> KIRIN_CAST = register(new KirinCastingAbility(), "kirin_cast", AbilitySlot.SECONDARY);
static <T extends Ability<?>> T register(T power, String name, AbilitySlot slot) { static <T extends Ability<?>> T register(T power, String name, AbilitySlot slot) {

View file

@ -0,0 +1,104 @@
package com.minelittlepony.unicopia.ability;
import java.util.Optional;
import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.EquinePredicates;
import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.ability.data.Hit;
import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation;
import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation.Recipient;
import com.minelittlepony.unicopia.entity.player.Pony;
import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.damage.DamageTypes;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.predicate.entity.EntityPredicates;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.random.Random;
import net.minecraft.world.BlockView;
import net.minecraft.world.World.ExplosionSourceType;
import net.minecraft.world.explosion.Explosion;
import net.minecraft.world.explosion.ExplosionBehavior;
/**
* Kirin ability to transform into a nirik
*/
public class NirikBlastAbility implements Ability<Hit> {
@Override
public int getWarmupTime(Pony player) {
return 10;
}
@Override
public int getCooldownTime(Pony player) {
return 3;
}
@Override
public boolean canUse(Race race) {
return race == Race.KIRIN;
}
@Nullable
@Override
public Optional<Hit> prepare(Pony player) {
return Hit.of(EquinePredicates.RAGING.test(player.asEntity()));
}
@Override
public Hit.Serializer<Hit> getSerializer() {
return Hit.SERIALIZER;
}
@Override
public double getCostEstimate(Pony player) {
return 0;
}
@Override
public boolean apply(Pony player, Hit data) {
player.asWorld().createExplosion(player.asEntity(), player.damageOf(DamageTypes.FIREBALL), new ExplosionBehavior(){
@Override
public boolean canDestroyBlock(Explosion explosion, BlockView world, BlockPos pos, BlockState state, float power) {
return false;
}
}, player.getOriginVector(), 5, true, ExplosionSourceType.MOB);
player.setInvulnerabilityTicks(5);
player.setAnimation(Animation.ARMS_UP, Recipient.ANYONE, 12);
player.playSound(SoundEvents.ENTITY_POLAR_BEAR_WARNING, 2F, 0.1F);
player.subtractEnergyCost(25);
coolDown(player, AbilitySlot.NONE);
for (Entity e : player.findAllEntitiesInRange(5, EntityPredicates.VALID_LIVING_ENTITY.and(EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR)).toList()) {
Vec3d offset = player.getOriginVector().subtract(e.getPos());
((LivingEntity)e).takeKnockback(1, offset.x, offset.z);
}
return true;
}
@Override
public void warmUp(Pony player, AbilitySlot slot) {
}
@Override
public void coolDown(Pony player, AbilitySlot slot) {
Random rng = player.asWorld().random;
for (int i = 0; i < 26; i++) {
Vec3d pos = player.getOriginVector().add(rng.nextGaussian(), 0, rng.nextGaussian());
player.addParticle(ParticleTypes.CAMPFIRE_SIGNAL_SMOKE, pos, new Vec3d(rng.nextGaussian(), 0.3, rng.nextGaussian()));
player.addParticle(ParticleTypes.FLAME, pos, new Vec3d(rng.nextGaussian(), 0.8, rng.nextGaussian()));
player.addParticle(ParticleTypes.LAVA, pos, new Vec3d(rng.nextGaussian(), 0.8, rng.nextGaussian()));
}
}
}

View file

@ -64,7 +64,7 @@ public class RageAbilitySpell extends AbstractSpell {
public boolean canDestroyBlock(Explosion explosion, BlockView world, BlockPos pos, BlockState state, float power) { public boolean canDestroyBlock(Explosion explosion, BlockView world, BlockPos pos, BlockState state, float power) {
return false; return false;
} }
}, source.getOriginVector(), 0, true, ExplosionSourceType.MOB); }, source.getOriginVector(), 3, true, ExplosionSourceType.MOB);
if (source instanceof Pony pony) { if (source instanceof Pony pony) {
pony.setAnimation(Animation.ARMS_UP, Recipient.ANYONE, 12); pony.setAnimation(Animation.ARMS_UP, Recipient.ANYONE, 12);
@ -87,7 +87,9 @@ public class RageAbilitySpell extends AbstractSpell {
} else { } else {
if (age % 5 == 0) { if (age % 5 == 0) {
source.spawnParticles(ParticleTypes.LAVA, 4); source.spawnParticles(ParticleTypes.LAVA, 4);
source.subtractEnergyCost(Math.min(12, 3 + source.asEntity().getVelocity().length() * 0.1)); if (source instanceof Pony pony && !pony.asEntity().handSwinging) {
source.subtractEnergyCost(Math.min(12, 3 + source.asEntity().getVelocity().length() * 0.1));
}
} }
} }

View file

@ -136,7 +136,7 @@ public class UHud {
slots.forEach(slot -> slot.renderBackground(context, abilities, swap, tickDelta)); slots.forEach(slot -> slot.renderBackground(context, abilities, swap, tickDelta));
boolean canCast = Abilities.CAST.canUse(pony.getCompositeRace()); boolean canCast = Abilities.CAST.canUse(pony.getCompositeRace()) || Abilities.KIRIN_CAST.canUse(pony.getCompositeRace());
if (canCast) { if (canCast) {
Ability<?> ability = pony.getAbilities().getStat(AbilitySlot.PRIMARY) Ability<?> ability = pony.getAbilities().getStat(AbilitySlot.PRIMARY)

View file

@ -105,6 +105,8 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
private float magicExhaustion = 0; private float magicExhaustion = 0;
private int ticksInvulnerable;
private int ticksInSun; private int ticksInSun;
private boolean hasShades; private boolean hasShades;
private int ticksSunImmunity = INITIAL_SUN_IMMUNITY; private int ticksSunImmunity = INITIAL_SUN_IMMUNITY;
@ -275,6 +277,10 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
return ticksSunImmunity > 0; return ticksSunImmunity > 0;
} }
public void setInvulnerabilityTicks(int ticks) {
this.ticksInvulnerable = Math.max(0, ticks);
}
@Override @Override
public Affinity getAffinity() { public Affinity getAffinity() {
return getSpecies().getAffinity(); return getSpecies().getAffinity();
@ -354,6 +360,10 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
); );
} }
if (ticksInvulnerable > 0) {
entity.setInvulnerable(--ticksInvulnerable > 0);
}
if (isClient()) { if (isClient()) {
if (entity.hasVehicle() && entity.isSneaking()) { if (entity.hasVehicle() && entity.isSneaking()) {
@ -850,6 +860,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
compound.put("mana", mana.toNBT()); compound.put("mana", mana.toNBT());
compound.putInt("levels", levels.get()); compound.putInt("levels", levels.get());
compound.putInt("corruption", corruption.get()); compound.putInt("corruption", corruption.get());
compound.putInt("ticksInvulnerable", ticksInvulnerable);
NbtCompound progress = new NbtCompound(); NbtCompound progress = new NbtCompound();
advancementProgress.forEach((key, count) -> { advancementProgress.forEach((key, count) -> {
@ -872,6 +883,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
magicExhaustion = compound.getFloat("magicExhaustion"); magicExhaustion = compound.getFloat("magicExhaustion");
ticksHanging = compound.getInt("ticksHanging"); ticksHanging = compound.getInt("ticksHanging");
ticksInvulnerable = compound.getInt("ticksInvulnerable");
entity.getDataTracker().set(HANGING_POSITION, NbtSerialisable.BLOCK_POS.readOptional("hangingPosition", compound)); entity.getDataTracker().set(HANGING_POSITION, NbtSerialisable.BLOCK_POS.readOptional("hangingPosition", compound));
ticksInSun = compound.getInt("ticksInSun"); ticksInSun = compound.getInt("ticksInSun");
hasShades = compound.getBoolean("hasShades"); hasShades = compound.getBoolean("hasShades");

View file

@ -404,6 +404,7 @@
"ability.unicopia.disguise": "Change Form", "ability.unicopia.disguise": "Change Form",
"ability.unicopia.rainboom": "Sonic Rainboom", "ability.unicopia.rainboom": "Sonic Rainboom",
"ability.unicopia.rage": "Rage", "ability.unicopia.rage": "Rage",
"ability.unicopia.nirik_blast": "Nirik Blast",
"gui.unicopia.trait.label": "Element of %s", "gui.unicopia.trait.label": "Element of %s",
"gui.unicopia.trait.group": "\n %s", "gui.unicopia.trait.group": "\n %s",

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB