From fef8de15d865529021fb2ccb567d2dc834953f7d Mon Sep 17 00:00:00 2001 From: Sollace Date: Sat, 13 Feb 2021 19:59:12 +0200 Subject: [PATCH] Unicorns now have the option to takes friends with them when they teleport (at an extra cost) --- .../unicopia/ability/Abilities.java | 1 + .../ability/UnicornGroupTeleportAbility.java | 34 ++++++++++++++++ .../ability/UnicornTeleportAbility.java | 29 ++++++++----- .../unicopia/ability/magic/Caster.java | 30 +++++++++++++- .../unicopia/ability/magic/CasterUtils.java | 38 ------------------ .../unicopia/entity/behaviour/Disguise.java | 5 +-- .../unicopia/mixin/MixinLivingEntity.java | 4 +- .../unicopia/mixin/MixinMilkBucketItem.java | 4 +- .../resources/assets/unicopia/lang/en_us.json | 1 + .../gui/ability/group_teleport_far.png | Bin 0 -> 455 bytes .../gui/ability/group_teleport_near.png | Bin 0 -> 547 bytes 11 files changed, 89 insertions(+), 57 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/ability/UnicornGroupTeleportAbility.java delete mode 100644 src/main/java/com/minelittlepony/unicopia/ability/magic/CasterUtils.java create mode 100644 src/main/resources/assets/unicopia/textures/gui/ability/group_teleport_far.png create mode 100644 src/main/resources/assets/unicopia/textures/gui/ability/group_teleport_near.png diff --git a/src/main/java/com/minelittlepony/unicopia/ability/Abilities.java b/src/main/java/com/minelittlepony/unicopia/ability/Abilities.java index 25136c06..3b99a868 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/Abilities.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/Abilities.java @@ -17,6 +17,7 @@ public interface Abilities { // unicorn / alicorn Ability CAST = register(new UnicornCastingAbility(), "cast", AbilitySlot.PRIMARY); Ability TELEPORT = register(new UnicornTeleportAbility(), "teleport", AbilitySlot.SECONDARY); + Ability GROUP_TELEPORT = register(new UnicornGroupTeleportAbility(), "group_teleport", AbilitySlot.SECONDARY); Ability SHOOT = register(new UnicornProjectileAbility(), "shoot", AbilitySlot.TERTIARY); // earth / alicorn diff --git a/src/main/java/com/minelittlepony/unicopia/ability/UnicornGroupTeleportAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/UnicornGroupTeleportAbility.java new file mode 100644 index 00000000..0f7f1abc --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/ability/UnicornGroupTeleportAbility.java @@ -0,0 +1,34 @@ +package com.minelittlepony.unicopia.ability; + +import java.util.stream.Stream; + +import com.minelittlepony.unicopia.ability.data.Pos; +import com.minelittlepony.unicopia.ability.magic.Caster; +import com.minelittlepony.unicopia.entity.player.Pony; +import com.minelittlepony.unicopia.item.FriendshipBraceletItem; + +/** + * Unicorn teleport ability with friends + */ +public class UnicornGroupTeleportAbility extends UnicornTeleportAbility { + + @Override + public double getCostEstimate(Pony player) { + double cost = super.getCostEstimate(player); + + if (cost == 0) { + return 0; + } + return cost * (1 + getComrades(player).count()); + } + + @Override + public void apply(Pony player, Pos data) { + getComrades(player).forEach(teleportee -> teleport(player, teleportee, data)); + super.apply(player, data); + } + + private Stream> getComrades(Pony player) { + return Caster.stream(player.findAllEntitiesInRange(3, e -> FriendshipBraceletItem.isComrade(player, e))); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/ability/UnicornTeleportAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/UnicornTeleportAbility.java index 9e773b44..2cd69cb6 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/UnicornTeleportAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/UnicornTeleportAbility.java @@ -3,6 +3,7 @@ package com.minelittlepony.unicopia.ability; import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.ability.data.Hit; import com.minelittlepony.unicopia.ability.data.Pos; +import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.particle.MagicParticleEffect; import com.minelittlepony.unicopia.util.RayTraceHelper; @@ -12,6 +13,7 @@ import net.minecraft.block.FenceBlock; import net.minecraft.block.LeavesBlock; import net.minecraft.block.WallBlock; import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.network.packet.s2c.play.EntityPassengersSetS2CPacket; import net.minecraft.predicate.entity.EntityPredicates; @@ -23,6 +25,7 @@ import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.HitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; /** @@ -30,9 +33,6 @@ import net.minecraft.world.World; */ public class UnicornTeleportAbility implements Ability { - /** - * The icon representing this ability on the UI and HUD. - */ @Override public Identifier getIcon(Pony player, boolean swap) { Identifier id = Abilities.REGISTRY.getId(this); @@ -125,10 +125,15 @@ public class UnicornTeleportAbility implements Ability { @Override public void apply(Pony iplayer, Pos data) { - iplayer.getWorld().playSound(null, iplayer.getOrigin(), SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.PLAYERS, 1, 1); + teleport(iplayer, iplayer, data); + } - PlayerEntity player = iplayer.getMaster(); - double distance = data.distanceTo(iplayer) / 10; + protected void teleport(Pony teleporter, Caster teleportee, Pos destination) { + teleportee.getWorld().playSound(null, teleportee.getOrigin(), SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.PLAYERS, 1, 1); + + double distance = destination.distanceTo(teleportee) / 10; + + LivingEntity player = teleportee.getMaster(); if (player.hasVehicle()) { Entity mount = player.getVehicle(); @@ -140,15 +145,17 @@ public class UnicornTeleportAbility implements Ability { } } + Vec3d offset = teleportee.getOriginVector().subtract(teleporter.getOriginVector()); + player.teleport( - data.x + (player.getX() - Math.floor(player.getX())), - data.y, - data.z + (player.getZ() - Math.floor(player.getZ()))); - iplayer.subtractEnergyCost(distance); + destination.x + offset.x + (player.getX() - Math.floor(player.getX())), + destination.y + offset.y, + destination.z + offset.z + (player.getZ() - Math.floor(player.getZ()))); + teleporter.subtractEnergyCost(distance); player.fallDistance /= distance; - player.world.playSound(null, data.pos(), SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.PLAYERS, 1, 1); + player.world.playSound(null, destination.pos(), SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.PLAYERS, 1, 1); } private boolean enterable(World w, BlockPos pos) { diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/Caster.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/Caster.java index e329de55..b2b27f26 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/Caster.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/Caster.java @@ -6,8 +6,10 @@ import java.util.stream.Stream; import javax.annotation.Nullable; +import com.minelittlepony.unicopia.EquinePredicates; import com.minelittlepony.unicopia.Owned; import com.minelittlepony.unicopia.entity.Physics; +import com.minelittlepony.unicopia.entity.PonyContainer; import com.minelittlepony.unicopia.network.EffectSync; import com.minelittlepony.unicopia.particle.ParticleSource; import com.minelittlepony.unicopia.util.VecHelper; @@ -105,7 +107,11 @@ public interface Caster extends Owned, Levelled, Affi } default Stream> findAllSpellsInRange(double radius) { - return CasterUtils.findInRange(this, radius); + return findAllSpellsInRange(radius, null); + } + + default Stream> findAllSpellsInRange(double radius, @Nullable Predicate test) { + return stream(findAllEntitiesInRange(radius, test == null ? EquinePredicates.IS_CASTER : EquinePredicates.IS_CASTER.and(test))); } default Stream findAllEntitiesInRange(double radius, @Nullable Predicate test) { @@ -115,4 +121,26 @@ public interface Caster extends Owned, Levelled, Affi default Stream findAllEntitiesInRange(double radius) { return findAllEntitiesInRange(radius, null); } + + static Stream> stream(Stream entities) { + return entities + .map(Caster::of) + .filter(Optional::isPresent) + .map(Optional::get); + } + + /** + * Attempts to convert the passed entity into a caster using all the known methods. + */ + static Optional> of(@Nullable Entity entity) { + if (entity instanceof Caster) { + return Optional.of((Caster)entity); + } + + if (entity instanceof LivingEntity && !(entity instanceof Magical)) { + return PonyContainer.of(entity).map(PonyContainer::getCaster); + } + + return Optional.empty(); + } } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/CasterUtils.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/CasterUtils.java deleted file mode 100644 index 246635b3..00000000 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/CasterUtils.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.minelittlepony.unicopia.ability.magic; - -import java.util.Optional; -import java.util.stream.Stream; - -import javax.annotation.Nullable; - -import com.minelittlepony.unicopia.EquinePredicates; -import com.minelittlepony.unicopia.entity.PonyContainer; -import net.minecraft.entity.Entity; -import net.minecraft.entity.LivingEntity; - -public class CasterUtils { - /** - * Finds all surrounding spells within range from the given caster. - */ - static Stream> findInRange(Caster source, double radius) { - return source.findAllEntitiesInRange(radius, EquinePredicates.IS_CASTER) - .map(e -> toCaster(e).filter(o -> o != source)) - .filter(Optional::isPresent) - .map(Optional::get); - } - - /** - * Attempts to convert the passed entity into a caster using all the known methods. - */ - public static Optional> toCaster(@Nullable Entity entity) { - if (entity instanceof Caster) { - return Optional.of((Caster)entity); - } - - if (entity instanceof LivingEntity && !(entity instanceof Magical)) { - return PonyContainer.of(entity).map(PonyContainer::getCaster); - } - - return Optional.empty(); - } -} diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java index f8b00f4e..6ed3a705 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java @@ -14,7 +14,6 @@ import com.minelittlepony.unicopia.FlightType; import com.minelittlepony.unicopia.InteractionManager; import com.minelittlepony.unicopia.Owned; import com.minelittlepony.unicopia.ability.magic.Caster; -import com.minelittlepony.unicopia.ability.magic.CasterUtils; import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.projectile.ProjectileUtil; @@ -171,7 +170,7 @@ public class Disguise implements NbtSerialisable { return; } - CasterUtils.toCaster(entity).ifPresent(c -> c.setSpell(null)); + Caster.of(entity).ifPresent(c -> c.setSpell(null)); if (source.isClient()) { source.getWorld().spawnEntity(entity); @@ -340,7 +339,7 @@ public class Disguise implements NbtSerialisable { VoxelShape entityShape = VoxelShapes.cuboid(box.expand(1.0E-6D)); world.getOtherEntities(entity, box.expand(0.5), predicate.and(e -> { - CasterUtils.toCaster(e).flatMap(c -> c.getSpellOrEmpty(DisguiseSpell.class, false)).ifPresent(p -> { + Caster.of(e).flatMap(c -> c.getSpellOrEmpty(DisguiseSpell.class, false)).ifPresent(p -> { p.getDisguise().getCollissionShapes(ctx, shape -> { if (!shape.isEmpty() && VoxelShapes.matchesAnywhere(shape, entityShape, BooleanBiFunction.AND)) { shapes.add(shape); diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java index 257ee818..2b65644c 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java @@ -11,7 +11,7 @@ import org.spongepowered.asm.mixin.injection.ModifyConstant; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import com.minelittlepony.unicopia.ability.magic.CasterUtils; +import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; import com.minelittlepony.unicopia.entity.Creature; import com.minelittlepony.unicopia.entity.PonyContainer; @@ -72,7 +72,7 @@ abstract class MixinLivingEntity extends Entity implements PonyContainer info) { - CasterUtils.toCaster(this) + Caster.of(this) .flatMap(c -> c.getSpellOrEmpty(DisguiseSpell.class, false)) .map(DisguiseSpell::getDisguise) .map(Disguise::getAppearance) diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinMilkBucketItem.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinMilkBucketItem.java index 9ce1ad77..cda0d2ed 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinMilkBucketItem.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinMilkBucketItem.java @@ -5,7 +5,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import com.minelittlepony.unicopia.ability.magic.CasterUtils; +import com.minelittlepony.unicopia.ability.magic.Caster; import net.minecraft.entity.LivingEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -18,6 +18,6 @@ abstract class MixinMilkBucketItem extends Item { @Inject(method = "finishUsing", at = @At("HEAD"), cancellable = true) private void finishUsing(ItemStack stack, World world, LivingEntity entity, CallbackInfoReturnable info) { - CasterUtils.toCaster(entity).ifPresent(c -> c.setSpell(null)); + Caster.of(entity).ifPresent(c -> c.setSpell(null)); } } diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index c06710c9..b5ce7b7c 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -132,6 +132,7 @@ "ability.unicopia.shoot": "Magic Missle", "ability.unicopia.cast": "Counterspell", "ability.unicopia.teleport": "Teleport", + "ability.unicopia.group_teleport": "Teleport (Group)", "ability.unicopia.grow": "Earthly Nourishment", "ability.unicopia.stomp": "Ground Pound", "ability.unicopia.kick": "Crushing Blow", diff --git a/src/main/resources/assets/unicopia/textures/gui/ability/group_teleport_far.png b/src/main/resources/assets/unicopia/textures/gui/ability/group_teleport_far.png new file mode 100644 index 0000000000000000000000000000000000000000..a6b079a8f43944d9f1c32e35271f700d452205ea GIT binary patch literal 455 zcmV;&0XY7NP)6^K4jI1S#9ZGVf6EVgfpx*`DXe?S=ec?Zpf63SefoNdf4!{P|v! z=1uJ-H*ul_5E02?A(PRx+n1-_Xp<8W%@P9xt8RRrTObI9%t1=kzBh`9P$6S6kmMNg zxQtUc*_`AlA2W6ZlK~Xq4Kg#wWg8zk0Agk+`W$SkvSokWC|J=WIuu%m;Kc|45jkCV zsRuy)4fSU2HT9qR`U3#)_4@9`xjqOzY3Ry`HS>?iel~wXT+cpCdp$^)Eyh)XQ%ESr xOOZ_|?A;Kel&&}?*utw5Zq%tsYKVR!y-i{9{@_OQl`lt#Em{C-=Hf0BCw@rEES#sN;|a(rO8;@6eeki z;ZvfE%xD`N=Ww{iVQ~a-!3F;d4AO^YpL#fT-C#iCuu8;B9G*%f=rLz%kh*B~d1{b4 z0Mlcia*4J^_*;0ExbToB%*RiZ?|*+`e5hF=9`NkxW0RR^7 z;g6C70A%qM{^%3zLnde`e-T_=gbg+Tuq2j`T_l2z>?)DB-vDnevPP- zxD&~yI9_=R5yH;zUETx!NnmFSS2U)GNjQoQO01rls~-lbGf<>n9}JYEUeiEj)sT~$ zh?lgyPJJ|3&eQ9x4~d{lghyr8duQd&iHJb&cK~1|e)&!|&Pwd++HxC-tFB7e`8@&r z^6cN0DZBjaUwz3Yv$MtStS6Y)2fPdAW@Jyu^z