mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-08 14:36:44 +01:00
Added a second kirin ability
This commit is contained in:
parent
577f5c8bb8
commit
fcab76fd43
7 changed files with 123 additions and 3 deletions
|
@ -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) {
|
||||||
|
|
|
@ -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()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -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,9 +87,11 @@ 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);
|
||||||
|
if (source instanceof Pony pony && !pony.asEntity().handSwinging) {
|
||||||
source.subtractEnergyCost(Math.min(12, 3 + source.asEntity().getVelocity().length() * 0.1));
|
source.subtractEnergyCost(Math.min(12, 3 + source.asEntity().getVelocity().length() * 0.1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (source instanceof Pony pony) {
|
if (source instanceof Pony pony) {
|
||||||
if (source.isClient() && pony.asEntity().getAttackCooldownProgress(0) == 0) {
|
if (source.isClient() && pony.asEntity().getAttackCooldownProgress(0) == 0) {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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 |
Loading…
Reference in a new issue