mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-01 19:46:42 +01:00
Added the catapult spell type
This commit is contained in:
parent
9bb2818c2c
commit
c0eeb5b5e1
4 changed files with 116 additions and 2 deletions
|
@ -0,0 +1,101 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.ProjectileSpell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
import com.minelittlepony.unicopia.util.RayTraceHelper;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.FallingBlockEntity;
|
||||
import net.minecraft.predicate.entity.EntityPredicates;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.hit.EntityHitResult;
|
||||
import net.minecraft.util.hit.HitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class CatapultSpell extends AbstractSpell implements ProjectileSpell {
|
||||
public static final SpellTraits DEFAULT_TRAITS = new SpellTraits.Builder()
|
||||
.with(Trait.FOCUS, 50)
|
||||
.with(Trait.KNOWLEDGE, 1)
|
||||
.with(Trait.EARTH, 60)
|
||||
.with(Trait.STRENGTH, 50)
|
||||
.build();
|
||||
|
||||
private static final float HORIZONTAL_VARIANCE = 0.25F;
|
||||
private static final float MAX_STRENGTH = 120;
|
||||
|
||||
protected CatapultSpell(SpellType<?> type, SpellTraits traits) {
|
||||
super(type, traits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(MagicProjectileEntity projectile, BlockPos pos, BlockState state) {
|
||||
if (!projectile.isClient()) {
|
||||
createBlockEntity(projectile.world, pos, e -> apply(projectile, e));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(MagicProjectileEntity projectile, Entity entity) {
|
||||
if (!projectile.isClient()) {
|
||||
apply(projectile, entity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tick(Caster<?> caster, Situation situation) {
|
||||
if (situation == Situation.PROJECTILE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
getTarget(caster, e -> apply(caster, e));
|
||||
return situation == Situation.PROJECTILE;
|
||||
}
|
||||
|
||||
protected void apply(Caster<?> caster, Entity e) {
|
||||
Vec3d vel = caster.getEntity().getVelocity();
|
||||
e.addVelocity(
|
||||
((caster.getWorld().random.nextFloat() * HORIZONTAL_VARIANCE) - HORIZONTAL_VARIANCE + vel.x * 0.8F) * 0.1F,
|
||||
0.1F + (getTraits().get(Trait.STRENGTH, -MAX_STRENGTH, MAX_STRENGTH) - 50) / 16D,
|
||||
((caster.getWorld().random.nextFloat() * HORIZONTAL_VARIANCE) - HORIZONTAL_VARIANCE + vel.z * 0.8F) * 0.1F
|
||||
);
|
||||
e.world.spawnEntity(e);
|
||||
}
|
||||
|
||||
protected void getTarget(Caster<?> caster, Consumer<Entity> apply) {
|
||||
if (caster.isClient()) {
|
||||
return;
|
||||
}
|
||||
|
||||
double maxDistance = 2 + (getTraits().get(Trait.FOCUS) - 50) * 8;
|
||||
|
||||
HitResult ray = RayTraceHelper.doTrace(caster.getMaster(), maxDistance, 1, EntityPredicates.EXCEPT_SPECTATOR).getResult();
|
||||
|
||||
if (ray.getType() == HitResult.Type.ENTITY) {
|
||||
EntityHitResult result = (EntityHitResult)ray;
|
||||
Optional.ofNullable(result.getEntity()).ifPresent(apply);
|
||||
} else if (ray.getType() == HitResult.Type.BLOCK) {
|
||||
createBlockEntity(caster.getWorld(), ((BlockHitResult)ray).getBlockPos(), apply);
|
||||
}
|
||||
}
|
||||
|
||||
static void createBlockEntity(World world, BlockPos bpos, Consumer<Entity> apply) {
|
||||
Vec3d pos = Vec3d.ofBottomCenter(bpos);
|
||||
FallingBlockEntity e = new FallingBlockEntity(world, pos.x, pos.y, pos.z, world.getBlockState(bpos));
|
||||
world.removeBlock(bpos, true);
|
||||
e.setOnGround(false);
|
||||
e.timeFalling = Integer.MIN_VALUE;
|
||||
|
||||
apply.accept(e);
|
||||
world.spawnEntity(e);
|
||||
}
|
||||
}
|
|
@ -16,6 +16,9 @@ import net.minecraft.util.math.BlockPos;
|
|||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
/**
|
||||
* Converts surrounding blocks and entities into their nether equivalent
|
||||
*/
|
||||
public class InfernoSpell extends FireSpell {
|
||||
|
||||
protected InfernoSpell(SpellType<?> type, SpellTraits traits) {
|
||||
|
|
|
@ -56,8 +56,9 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
|||
public static final SpellType<SiphoningSpell> DRAINING = register("draining", Affinity.BAD, 0xe308ab, true, SiphoningSpell::new);
|
||||
public static final SpellType<RevealingSpell> REVEALING = register("reveal", Affinity.GOOD, 0x5CE81F, true, RevealingSpell::new);
|
||||
public static final SpellType<AwkwardSpell> AWKWARD = register("awkward", Affinity.GOOD, 0xE1239C, true, AwkwardSpell::new);
|
||||
public static final SpellType<TransformationSpell> TRANSFORMATION = register("transformation", Affinity.NEUTRAL, 0x3A59AA, true, TransformationSpell::new);
|
||||
public static final SpellType<TransformationSpell> TRANSFORMATION = register("transformation", Affinity.GOOD, 0x3A59AA, true, TransformationSpell::new);
|
||||
public static final SpellType<FeatherFallSpell> FEATHER_FALL = register("feather_fall", Affinity.GOOD, 0x00EEFF, true, FeatherFallSpell.DEFAULT_TRAITS, FeatherFallSpell::new);
|
||||
public static final SpellType<CatapultSpell> CATAPULT = register("catapult", Affinity.GOOD, 0x33FF00, true, CatapultSpell.DEFAULT_TRAITS, CatapultSpell::new);
|
||||
|
||||
private final Identifier id;
|
||||
private final Affinity affinity;
|
||||
|
|
|
@ -11,6 +11,7 @@ import java.util.Map.Entry;
|
|||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
@ -50,13 +51,21 @@ public final class SpellTraits implements Iterable<Map.Entry<Trait, Float>> {
|
|||
return factor == 0 ? EMPTY : map(v -> v * factor);
|
||||
}
|
||||
|
||||
public SpellTraits add(float amount) {
|
||||
return amount == 0 ? this : map(v -> v + amount);
|
||||
}
|
||||
|
||||
public SpellTraits map(Function<Float, Float> function) {
|
||||
return map((k, v) -> function.apply(v));
|
||||
}
|
||||
|
||||
public SpellTraits map(BiFunction<Trait, Float, Float> function) {
|
||||
if (isEmpty()) {
|
||||
return this;
|
||||
}
|
||||
|
||||
Map<Trait, Float> newMap = new EnumMap<>(traits);
|
||||
newMap.entrySet().forEach(entry -> entry.setValue(function.apply(entry.getValue())));
|
||||
newMap.entrySet().forEach(entry -> entry.setValue(function.apply(entry.getKey(), entry.getValue())));
|
||||
return fromEntries(newMap.entrySet().stream()).orElse(EMPTY);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue