Added an ability for seaponies

This commit is contained in:
Sollace 2023-11-10 18:14:26 +00:00
parent 4a1ac9fede
commit 2305775a55
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
11 changed files with 151 additions and 2 deletions

View file

@ -0,0 +1,16 @@
package com.minelittlepony.unicopia;
import net.fabricmc.fabric.api.object.builder.v1.world.poi.PointOfInterestHelper;
import net.minecraft.block.AbstractChestBlock;
import net.minecraft.block.Block;
import net.minecraft.registry.Registries;
import net.minecraft.world.poi.PointOfInterestType;
public interface UPOIs {
PointOfInterestType CHESTS = PointOfInterestHelper.register(Unicopia.id("chests"), 1, 64, Registries.BLOCK.getEntrySet().stream()
.map(entry -> entry.getValue())
.filter(b -> b instanceof AbstractChestBlock)
.toArray(Block[]::new));
static void bootstrap() { }
}

View file

@ -29,6 +29,7 @@ public interface USounds {
SoundEvent ENTITY_PLAYER_UNICORN_TELEPORT = register("entity.player.unicorn.teleport");
SoundEvent ENTITY_PLAYER_KIRIN_RAGE = ENTITY_POLAR_BEAR_WARNING;
SoundEvent ENTITY_PLAYER_KIRIN_RAGE_LOOP = register("entity.player.kirin.rage.loop");
SoundEvent ENTITY_PLAYER_SEAPONY_SONAR = register("entity.player.seapony.sonar", 64);
SoundEvent ENTITY_PLAYER_EARS_RINGING = register("entity.player.ears_ring");
SoundEvent ENTITY_PLAYER_HEARTBEAT = register("entity.player.heartbeat");
@ -148,6 +149,11 @@ public interface USounds {
return Registry.register(Registries.SOUND_EVENT, id, SoundEvent.of(id));
}
static SoundEvent register(String name, float range) {
Identifier id = Unicopia.id(name);
return Registry.register(Registries.SOUND_EVENT, id, SoundEvent.of(id, range));
}
static void bootstrap() {}
static final class Vanilla extends SoundEvents {}

View file

@ -91,6 +91,7 @@ public class Unicopia implements ModInitializer {
UGameEvents.bootstrap();
UBlocks.bootstrap();
UPOIs.bootstrap();
UItems.bootstrap();
UPotions.bootstrap();
UParticles.bootstrap();

View file

@ -67,6 +67,9 @@ public interface Abilities {
Ability<?> NIRIK_BLAST = register(new NirikBlastAbility(), "nirik_blast", AbilitySlot.SECONDARY);
Ability<?> KIRIN_CAST = register(new KirinCastingAbility(), "kirin_cast", AbilitySlot.SECONDARY);
// seapony
Ability<?> SONAR_PULSE = register(new SeaponySonarPulseAbility(), "sonar_pulse", AbilitySlot.SECONDARY);
static <T extends Ability<?>> T register(T power, String name, AbilitySlot slot) {
Identifier id = Unicopia.id(name);
BY_SLOT.computeIfAbsent(slot, s -> new LinkedHashSet<>()).add(power);

View file

@ -0,0 +1,112 @@
package com.minelittlepony.unicopia.ability;
import java.util.Comparator;
import java.util.Optional;
import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.AwaitTickQueue;
import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.UPOIs;
import com.minelittlepony.unicopia.USounds;
import com.minelittlepony.unicopia.ability.data.Hit;
import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation;
import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.particle.ParticleUtils;
import com.minelittlepony.unicopia.particle.UParticles;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityGroup;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.mob.HostileEntity;
import net.minecraft.registry.tag.FluidTags;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.SoundCategory;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.event.GameEvent;
import net.minecraft.world.poi.PointOfInterestStorage.OccupationStatus;
public class SeaponySonarPulseAbility implements Ability<Hit> {
@Override
public int getWarmupTime(Pony player) {
return 10;
}
@Override
public int getCooldownTime(Pony player) {
return 100;
}
@Override
public boolean canUse(Race race) {
return race == Race.SEAPONY;
}
@Nullable
@Override
public Optional<Hit> prepare(Pony player) {
return Hit.INSTANCE;
}
@Override
public Hit.Serializer<Hit> getSerializer() {
return Hit.SERIALIZER;
}
@Override
public double getCostEstimate(Pony player) {
return 5;
}
@Override
public boolean apply(Pony player, Hit data) {
player.setAnimation(Animation.ARMS_UP, Animation.Recipient.ANYONE);
for (Entity target : player.findAllEntitiesInRange(64, e -> {
return (e instanceof LivingEntity && (e instanceof HostileEntity || ((LivingEntity)e).getGroup() == EntityGroup.AQUATIC)) && e.isSubmergedInWater();
}).sorted(Comparator.comparing(e -> e.distanceTo(player.asEntity()))).toList()) {
Vec3d offset = target.getPos().subtract(player.getOriginVector());
float distance = target.distanceTo(player.asEntity());
if (distance < 4) {
float scale = 1 - (distance/10F);
((LivingEntity)target).takeKnockback(0.7 * scale, -offset.x, -offset.z);
target.damage(target.getDamageSources().sonicBoom(player.asEntity()), 10 * scale);
} else {
emitPing(player, target.getPos(), 10, 1, 1.3F);
}
}
player.subtractEnergyCost(5);
if (player.asWorld() instanceof ServerWorld sw) {
sw.getPointOfInterestStorage().getNearestPosition(
type -> type.value() == UPOIs.CHESTS,
pos -> player.asWorld().getFluidState(pos).isIn(FluidTags.WATER), player.getOrigin(), 64, OccupationStatus.ANY)
.ifPresent(chestPos -> {
emitPing(player, chestPos.toCenterPos(), 20, 0.5F, 2F);
});
}
player.playSound(USounds.ENTITY_PLAYER_SEAPONY_SONAR, 1);
player.spawnParticles(UParticles.SHOCKWAVE, 1);
player.asEntity().emitGameEvent(GameEvent.INSTRUMENT_PLAY);
return true;
}
private void emitPing(Pony player, Vec3d pos, int delay, float volume, float pitch) {
AwaitTickQueue.scheduleTask(player.asWorld(), w -> {
ParticleUtils.spawnParticle(w, UParticles.SHOCKWAVE, pos, Vec3d.ZERO);
float loudness = Math.max(0, 1.4F - (float)Math.log10(player.getOriginVector().distanceTo(pos)));
w.playSound(null, pos.x, pos.y, pos.z, USounds.ENTITY_PLAYER_SEAPONY_SONAR, SoundCategory.AMBIENT, volume * loudness, pitch);
w.emitGameEvent(player.asEntity(), GameEvent.INSTRUMENT_PLAY, pos);
}, delay + (int)player.getOriginVector().distanceTo(pos));
}
@Override
public void warmUp(Pony player, AbilitySlot slot) {
player.getMagicalReserves().getExertion().addPercent(6);
}
@Override
public void coolDown(Pony player, AbilitySlot slot) {
}
}

View file

@ -497,6 +497,7 @@
"ability.unicopia.peck.block.unfased": "The block is unfazed by your threats",
"ability.unicopia.dash": "Flying Dash",
"ability.unicopia.change_form": "Change Form",
"ability.unicopia.sonar_pulse": "Sonar Pulse",
"gui.unicopia.trait.label": "Element of %s",
"gui.unicopia.trait.group": "\n %s",
@ -959,8 +960,10 @@
"unicopia.subtitle.wind_rush": "Wind gusts",
"unicopia.subtitle.insects": "Insects Scurrying",
"unicopia.subtitle.changeling_buzz": "Drone buzzing",
"unicopia.subtitle.batpony_eeee": "Batpony screeches",
"unicopia.subtitle.batpony_eeee": "Batpony Screeches",
"unicopia.subtitle.sonar": "Sonar Pulses",
"unicopia.subtitle.changeling.transform": "Changeling transforms",
"unicopia.subtitle.screech": "Hippogriff Screeches",
"unicopia.subtitle.pegasus.molt": "Pegasus loses feather",
"unicopia.subtitle.unicorn.teleport": "Magic pops",
"unicopia.subtitle.player.wololo": "Wololo!",

View file

@ -33,7 +33,15 @@
"category": "player",
"subtitle": "unicopia.subtitle.screech",
"sounds": [
"unicopia:screech/screech0"
"unicopia:screech/screech1",
"unicopia:screech/screech2"
]
},
"entity.player.seapony.sonar": {
"category": "player",
"subtitle": "unicopia.subtitle.sonar",
"sounds": [
"unicopia:sonar/sonar0"
]
},
"item.magic.aura": {

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB