Change flight activation to use a double-jump

This commit is contained in:
Sollace 2023-04-29 22:32:00 +01:00
parent 6f9addd903
commit 955c4d4afe
5 changed files with 152 additions and 20 deletions

63
old_ideas Normal file
View file

@ -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)

View file

@ -17,8 +17,11 @@ import com.minelittlepony.unicopia.ability.magic.SpellContainer.Operation;
import com.minelittlepony.unicopia.ability.magic.spell.Situation; import com.minelittlepony.unicopia.ability.magic.spell.Situation;
import com.minelittlepony.unicopia.advancement.UCriteria; import com.minelittlepony.unicopia.advancement.UCriteria;
import com.minelittlepony.unicopia.block.data.DragonBreathStore; 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.effect.UEffects;
import com.minelittlepony.unicopia.entity.player.Pony; 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.GlassesItem;
import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.item.UItems;
import com.minelittlepony.unicopia.network.datasync.EffectSync; import com.minelittlepony.unicopia.network.datasync.EffectSync;
@ -50,8 +53,9 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
private final EffectSync effectDelegate; private final EffectSync effectDelegate;
private boolean prevSneaking; private final Interactable sneakingHeuristic;
private boolean prevLanded; private final Interactable landedHeuristic;
private final Interactable jumpingHeuristic;
@Nullable @Nullable
private Runnable landEvent; private Runnable landEvent;
@ -74,6 +78,10 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
this.entity = entity; this.entity = entity;
this.effectDelegate = new EffectSync(this, effect); 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(effect, new NbtCompound());
entity.getDataTracker().startTracking(CARRIER_ID, Optional.empty()); entity.getDataTracker().startTracking(CARRIER_ID, Optional.empty());
} }
@ -100,11 +108,15 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
} }
public boolean sneakingChanged() { public boolean sneakingChanged() {
return entity.isSneaking() != prevSneaking; return sneakingHeuristic.hasChanged(Heuristic.ONCE);
} }
public boolean landedChanged() { public boolean landedChanged() {
return entity.isOnGround() != prevLanded; return landedHeuristic.hasChanged(Heuristic.ONCE);
}
public Interactable getJumpingHeuristic() {
return jumpingHeuristic;
} }
@Override @Override
@ -188,7 +200,6 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
updateVelocity(); updateVelocity();
} }
if (isBeingCarried()) { if (isBeingCarried()) {
Pony carrier = Pony.of(entity.getVehicle()).orElse(null); Pony carrier = Pony.of(entity.getVehicle()).orElse(null);
if (!carrier.getCompositeRace().any(Abilities.CARRY::canUse)) { if (!carrier.getCompositeRace().any(Abilities.CARRY::canUse)) {
@ -199,9 +210,6 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
} }
updateDragonBreath(); updateDragonBreath();
prevSneaking = entity.isSneaking();
prevLanded = entity.isOnGround();
} }
private void updateDragonBreath() { private void updateDragonBreath() {

View file

@ -11,6 +11,7 @@ import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation;
import com.minelittlepony.unicopia.entity.*; import com.minelittlepony.unicopia.entity.*;
import com.minelittlepony.unicopia.entity.duck.LivingEntityDuck; import com.minelittlepony.unicopia.entity.duck.LivingEntityDuck;
import com.minelittlepony.unicopia.entity.player.MagicReserves.Bar; 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.AmuletItem;
import com.minelittlepony.unicopia.item.ChargeableItem; import com.minelittlepony.unicopia.item.ChargeableItem;
import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.item.UItems;
@ -289,9 +290,14 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
ticksInAir = 0; ticksInAir = 0;
wallHitCooldown = MAX_WALL_HIT_CALLDOWN; wallHitCooldown = MAX_WALL_HIT_CALLDOWN;
soundPlaying = false; soundPlaying = false;
if (pony.getJumpingHeuristic().hasChanged(Heuristic.TWICE)) {
System.out.println("DOUBLE JUMP!!!!");
}
if (!creative && type.isAvian()) { if (!creative && type.isAvian()) {
checkAvianTakeoffConditions(velocity); checkAvianTakeoffConditions(velocity);
} else {
System.out.println("WRONG TYPE");
} }
} }
} else { } else {
@ -440,22 +446,27 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
double horMotion = getHorizontalMotion(); double horMotion = getHorizontalMotion();
double motion = entity.getPos().subtract(lastPos).lengthSquared(); double motion = entity.getPos().subtract(lastPos).lengthSquared();
boolean takeOffCondition = velocity.y > 0 boolean takeOffCondition =
&& (horMotion > 0.2 || (motion > 0.2 && velocity.y < -0.02 * getGravitySignum())); (horMotion > 0.05 || motion > 0.05)
boolean fallingTakeOffCondition = !entity.isOnGround() && velocity.y < -1.6 * getGravitySignum(); && pony.getJumpingHeuristic().hasChanged(Heuristic.TWICE);
boolean fallingTakeOffCondition = !entity.isOnGround() && velocity.y < -1.6 * getGravitySignum() && entity.fallDistance > 1;
if ((takeOffCondition || fallingTakeOffCondition) && !pony.isHanging() && !isCancelled) { if ((takeOffCondition || fallingTakeOffCondition) && !pony.isHanging() && !isCancelled) {
initiateTakeoff(velocity);
}
}
private void initiateTakeoff(MutableVector velocity) {
startFlying(false); startFlying(false);
if (!isGravityNegative()) { if (!isGravityNegative()) {
velocity.y += horMotion + 0.3; velocity.y += getHorizontalMotion() + 0.3;
} }
applyThrust(velocity); applyThrust(velocity);
velocity.x *= 0.2; velocity.x *= 0.2;
velocity.z *= 0.2; velocity.z *= 0.2;
} }
}
public void startFlying(boolean force) { public void startFlying(boolean force) {
if (force) { if (force) {

View file

@ -0,0 +1,6 @@
package com.minelittlepony.unicopia.input;
public enum Heuristic {
ONCE,
TWICE
}

View file

@ -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;
}
}