From 955c4d4afe9b3f8b66d81dce1db9ace44549ebea Mon Sep 17 00:00:00 2001 From: Sollace Date: Sat, 29 Apr 2023 22:32:00 +0100 Subject: [PATCH] Change flight activation to use a double-jump --- old_ideas | 63 +++++++++++++++++++ .../unicopia/entity/Living.java | 24 ++++--- .../unicopia/entity/player/PlayerPhysics.java | 35 +++++++---- .../unicopia/input/Heuristic.java | 6 ++ .../unicopia/input/Interactable.java | 44 +++++++++++++ 5 files changed, 152 insertions(+), 20 deletions(-) create mode 100644 old_ideas create mode 100644 src/main/java/com/minelittlepony/unicopia/input/Heuristic.java create mode 100644 src/main/java/com/minelittlepony/unicopia/input/Interactable.java diff --git a/old_ideas b/old_ideas new file mode 100644 index 00000000..3f7f9a91 --- /dev/null +++ b/old_ideas @@ -0,0 +1,63 @@ + + Corruption: + Corruption is gained in small amounts by using dark magic and has the effects described by wearing the alicorn amulet + Using light magic has the potential to reduce a player's corruption + + - Increasing corruption should corrupt spell's effects (higher chance of failing) + - Visual effects of corruption is a greyscale darkening of the player's view + - Players and spells with high corruption "leak" in to the surrounding areas + and corrupts other spells in the vicinity causing them to fail or turn against the caster + + - Areas with high corruption will see higher hostile mob spawns + Chances of blocks being turned into sculk when corruption is gained in an area + + + - Certain spells cannot be used above a certain corruption threshold + - Other spells (from the otherworldly category) cannot be used without a minimum amount of corruption + + + Lighting + - Gemstone Lamp + - A light source similar to torches + - Can be placed on clouds + + https://mixkit.co/free-sound-effects/magic/?page=2 + + Spell ideas (via https://www.dndbeyond.com/spells/class/sorcerer?filter-search=&filter-level=0&filter-verbal=&filter-somatic=&filter-material=&filter-concentration=&filter-ritual=&filter-sub-class= ) + + - Immobalise + Offensive + Trap the targetted entity in a floating bubble. + They have to struggle to pop the bubble and escape + + - Dark Whip + Offense + A dark magic spell that lashes out at a position or entity with a black tendril + - Needs corruption to cast + + To craft this one you have to defeat the Rift Lurker + - Throw a alicorn amulet into a large black hole + - The black hole's lightning effects change to black lightning + - The black hole collapses into a small ball + - The ball turns into an eye and tentacles crawl out revealing the Rift Lurker (an other-worldly beast from across the dimensions) + - Whilst fighting the Rift Lurker the black hole is still pulling in entities + - Every entity that falls into the black hole restores the rift lurker's health + - Every time you summon it, the rift lurker will be more powerful + + - The rift-lurker can only be defeated using magic + - When killed, the rift-lurker drops one of its tentacles + - Combine the tentacle in a spellbook with the blood, focus, and life traits to create the dark whip spell + + - To avoid having to fight the Rift Lurker every time, you can farm the tentacles + - Tentacles are edible, like carrots, but why would you eat them? Ew. + + - Dark Grip + - Corrupt version of the Arcane Grip + - Causes damage to living entities affected + - Requires corruption to cast + + - Come to life spell + - Requires corruption to cast + - Used on any container block (chest, furnace, etc) will cause it to grow legs and follow the player around + - With the darkness trait will add a chance of the block also obtaining a mouth and attacking the caster + -----Player's corruption increases chances of any spells going wrong (increases darkness trait effects) diff --git a/src/main/java/com/minelittlepony/unicopia/entity/Living.java b/src/main/java/com/minelittlepony/unicopia/entity/Living.java index 617414fd..15a3404a 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/Living.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/Living.java @@ -17,8 +17,11 @@ import com.minelittlepony.unicopia.ability.magic.SpellContainer.Operation; import com.minelittlepony.unicopia.ability.magic.spell.Situation; import com.minelittlepony.unicopia.advancement.UCriteria; import com.minelittlepony.unicopia.block.data.DragonBreathStore; +import com.minelittlepony.unicopia.entity.duck.LivingEntityDuck; import com.minelittlepony.unicopia.entity.effect.UEffects; import com.minelittlepony.unicopia.entity.player.Pony; +import com.minelittlepony.unicopia.input.Heuristic; +import com.minelittlepony.unicopia.input.Interactable; import com.minelittlepony.unicopia.item.GlassesItem; import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.network.datasync.EffectSync; @@ -50,8 +53,9 @@ public abstract class Living implements Equine, Caste private final EffectSync effectDelegate; - private boolean prevSneaking; - private boolean prevLanded; + private final Interactable sneakingHeuristic; + private final Interactable landedHeuristic; + private final Interactable jumpingHeuristic; @Nullable private Runnable landEvent; @@ -74,6 +78,10 @@ public abstract class Living implements Equine, Caste this.entity = entity; this.effectDelegate = new EffectSync(this, effect); + this.sneakingHeuristic = addTicker(new Interactable(entity::isSneaking)); + this.landedHeuristic = addTicker(new Interactable(entity::isOnGround)); + this.jumpingHeuristic = addTicker(new Interactable(((LivingEntityDuck)entity)::isJumping)); + entity.getDataTracker().startTracking(effect, new NbtCompound()); entity.getDataTracker().startTracking(CARRIER_ID, Optional.empty()); } @@ -100,11 +108,15 @@ public abstract class Living implements Equine, Caste } public boolean sneakingChanged() { - return entity.isSneaking() != prevSneaking; + return sneakingHeuristic.hasChanged(Heuristic.ONCE); } public boolean landedChanged() { - return entity.isOnGround() != prevLanded; + return landedHeuristic.hasChanged(Heuristic.ONCE); + } + + public Interactable getJumpingHeuristic() { + return jumpingHeuristic; } @Override @@ -188,7 +200,6 @@ public abstract class Living implements Equine, Caste updateVelocity(); } - if (isBeingCarried()) { Pony carrier = Pony.of(entity.getVehicle()).orElse(null); if (!carrier.getCompositeRace().any(Abilities.CARRY::canUse)) { @@ -199,9 +210,6 @@ public abstract class Living implements Equine, Caste } updateDragonBreath(); - - prevSneaking = entity.isSneaking(); - prevLanded = entity.isOnGround(); } private void updateDragonBreath() { diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java index 49a3a1dd..4fa4f5af 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java @@ -11,6 +11,7 @@ import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation; import com.minelittlepony.unicopia.entity.*; import com.minelittlepony.unicopia.entity.duck.LivingEntityDuck; import com.minelittlepony.unicopia.entity.player.MagicReserves.Bar; +import com.minelittlepony.unicopia.input.Heuristic; import com.minelittlepony.unicopia.item.AmuletItem; import com.minelittlepony.unicopia.item.ChargeableItem; import com.minelittlepony.unicopia.item.UItems; @@ -289,9 +290,14 @@ public class PlayerPhysics extends EntityPhysics implements Tickab ticksInAir = 0; wallHitCooldown = MAX_WALL_HIT_CALLDOWN; soundPlaying = false; + if (pony.getJumpingHeuristic().hasChanged(Heuristic.TWICE)) { + System.out.println("DOUBLE JUMP!!!!"); + } if (!creative && type.isAvian()) { checkAvianTakeoffConditions(velocity); + } else { + System.out.println("WRONG TYPE"); } } } else { @@ -440,23 +446,28 @@ public class PlayerPhysics extends EntityPhysics implements Tickab double horMotion = getHorizontalMotion(); double motion = entity.getPos().subtract(lastPos).lengthSquared(); - boolean takeOffCondition = velocity.y > 0 - && (horMotion > 0.2 || (motion > 0.2 && velocity.y < -0.02 * getGravitySignum())); - boolean fallingTakeOffCondition = !entity.isOnGround() && velocity.y < -1.6 * getGravitySignum(); + boolean takeOffCondition = + (horMotion > 0.05 || motion > 0.05) + && pony.getJumpingHeuristic().hasChanged(Heuristic.TWICE); + boolean fallingTakeOffCondition = !entity.isOnGround() && velocity.y < -1.6 * getGravitySignum() && entity.fallDistance > 1; if ((takeOffCondition || fallingTakeOffCondition) && !pony.isHanging() && !isCancelled) { - startFlying(false); - - if (!isGravityNegative()) { - velocity.y += horMotion + 0.3; - } - applyThrust(velocity); - - velocity.x *= 0.2; - velocity.z *= 0.2; + initiateTakeoff(velocity); } } + private void initiateTakeoff(MutableVector velocity) { + startFlying(false); + + if (!isGravityNegative()) { + velocity.y += getHorizontalMotion() + 0.3; + } + applyThrust(velocity); + + velocity.x *= 0.2; + velocity.z *= 0.2; + } + public void startFlying(boolean force) { if (force) { isCancelled = false; diff --git a/src/main/java/com/minelittlepony/unicopia/input/Heuristic.java b/src/main/java/com/minelittlepony/unicopia/input/Heuristic.java new file mode 100644 index 00000000..3c665ebf --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/input/Heuristic.java @@ -0,0 +1,6 @@ +package com.minelittlepony.unicopia.input; + +public enum Heuristic { + ONCE, + TWICE +} diff --git a/src/main/java/com/minelittlepony/unicopia/input/Interactable.java b/src/main/java/com/minelittlepony/unicopia/input/Interactable.java new file mode 100644 index 00000000..80877f24 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/input/Interactable.java @@ -0,0 +1,44 @@ +package com.minelittlepony.unicopia.input; + +import java.util.function.BooleanSupplier; + +import com.minelittlepony.unicopia.util.Tickable; + +public class Interactable implements Tickable { + + private final BooleanSupplier stateGetter; + + private boolean prevState; + private boolean currentState; + + private long prevActivationTime; + private long activationTime; + + public Interactable(BooleanSupplier stateGetter) { + this.stateGetter = stateGetter; + } + + @Override + public void tick() { + prevState = currentState; + currentState = stateGetter.getAsBoolean(); + if (prevState != currentState && currentState) { + prevActivationTime = activationTime; + activationTime = System.currentTimeMillis(); + } + } + + public boolean getState() { + return currentState; + } + + public boolean hasChanged(Heuristic changeType) { + if (changeType == Heuristic.ONCE) { + return prevState != currentState; + } + + final long stageDuration = 250; + final long now = System.currentTimeMillis(); + return activationTime > now - stageDuration && prevActivationTime > activationTime - stageDuration; + } +}