Added the catapult spell type

This commit is contained in:
Sollace 2021-11-22 00:48:40 +02:00
parent 9bb2818c2c
commit c0eeb5b5e1
4 changed files with 116 additions and 2 deletions

View file

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

View file

@ -16,6 +16,9 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World; import net.minecraft.world.World;
/**
* Converts surrounding blocks and entities into their nether equivalent
*/
public class InfernoSpell extends FireSpell { public class InfernoSpell extends FireSpell {
protected InfernoSpell(SpellType<?> type, SpellTraits traits) { protected InfernoSpell(SpellType<?> type, SpellTraits traits) {

View file

@ -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<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<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<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<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 Identifier id;
private final Affinity affinity; private final Affinity affinity;

View file

@ -11,6 +11,7 @@ import java.util.Map.Entry;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; 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); 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) { public SpellTraits map(Function<Float, Float> function) {
return map((k, v) -> function.apply(v));
}
public SpellTraits map(BiFunction<Trait, Float, Float> function) {
if (isEmpty()) { if (isEmpty()) {
return this; return this;
} }
Map<Trait, Float> newMap = new EnumMap<>(traits); 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); return fromEntries(newMap.entrySet().stream()).orElse(EMPTY);
} }