mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Add projectile actions to the displacement, light, and necro spells so they can be used with staffs
This commit is contained in:
parent
9ebe391a2b
commit
77bf8aa1de
5 changed files with 104 additions and 18 deletions
|
@ -7,13 +7,16 @@ import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
|||
import com.minelittlepony.unicopia.entity.CastSpellEntity;
|
||||
import com.minelittlepony.unicopia.entity.EntityReference;
|
||||
import com.minelittlepony.unicopia.particle.ParticleHandle.Attachment;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
import com.minelittlepony.unicopia.projectile.ProjectileDelegate;
|
||||
import com.minelittlepony.unicopia.util.MagicalDamageSource;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.util.hit.EntityHitResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public class DisplacementSpell extends AbstractSpell implements HomingSpell, PlaceableSpell.PlacementDelegate {
|
||||
public class DisplacementSpell extends AbstractSpell implements HomingSpell, PlaceableSpell.PlacementDelegate, ProjectileDelegate.EntityHitListener {
|
||||
|
||||
private final EntityReference<Entity> target = new EntityReference<>();
|
||||
|
||||
|
@ -41,23 +44,29 @@ public class DisplacementSpell extends AbstractSpell implements HomingSpell, Pla
|
|||
}
|
||||
|
||||
if (ticks == 0) {
|
||||
target.ifPresent(originator.asWorld(), target -> {
|
||||
|
||||
Vec3d destinationPos = target.getPos();
|
||||
Vec3d destinationVel = target.getVelocity();
|
||||
|
||||
Vec3d sourcePos = originator.getOriginVector();
|
||||
Vec3d sourceVel = originator.asEntity().getVelocity();
|
||||
|
||||
teleport(target, sourcePos, sourceVel);
|
||||
teleport(originator.asEntity(), destinationPos, destinationVel);
|
||||
originator.subtractEnergyCost(destinationPos.distanceTo(sourcePos) / 20F);
|
||||
});
|
||||
target.ifPresent(originator.asWorld(), target -> apply(originator, target));
|
||||
}
|
||||
|
||||
return ticks >= -10;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(MagicProjectileEntity projectile, EntityHitResult hit) {
|
||||
Caster.of(projectile.getMaster()).ifPresent(originator -> apply(originator, hit.getEntity()));
|
||||
}
|
||||
|
||||
private void apply(Caster<?> originator, Entity target) {
|
||||
Vec3d destinationPos = target.getPos();
|
||||
Vec3d destinationVel = target.getVelocity();
|
||||
|
||||
Vec3d sourcePos = originator.getOriginVector();
|
||||
Vec3d sourceVel = originator.asEntity().getVelocity();
|
||||
|
||||
teleport(target, sourcePos, sourceVel);
|
||||
teleport(originator.asEntity(), destinationPos, destinationVel);
|
||||
originator.subtractEnergyCost(destinationPos.distanceTo(sourcePos) / 20F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlaced(Caster<?> source, PlaceableSpell parent, CastSpellEntity entity) {
|
||||
|
||||
|
|
|
@ -11,13 +11,15 @@ import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
|||
import com.minelittlepony.unicopia.entity.EntityReference;
|
||||
import com.minelittlepony.unicopia.entity.FairyEntity;
|
||||
import com.minelittlepony.unicopia.entity.UEntities;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
import com.minelittlepony.unicopia.projectile.ProjectileDelegate;
|
||||
import com.minelittlepony.unicopia.util.VecHelper;
|
||||
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.nbt.NbtElement;
|
||||
import net.minecraft.nbt.NbtList;
|
||||
|
||||
public class LightSpell extends AbstractSpell implements TimedSpell {
|
||||
public class LightSpell extends AbstractSpell implements TimedSpell, ProjectileDelegate.HitListener {
|
||||
public static final SpellTraits DEFAULT_TRAITS = new SpellTraits.Builder()
|
||||
.with(Trait.LIFE, 10)
|
||||
.with(Trait.AIR, 0.3F)
|
||||
|
@ -80,6 +82,11 @@ public class LightSpell extends AbstractSpell implements TimedSpell {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(MagicProjectileEntity projectile) {
|
||||
Caster.of(projectile.getMaster()).ifPresent(getTypeAndTraits()::apply);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyed(Caster<?> caster) {
|
||||
if (caster.isClient()) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
|
@ -10,17 +11,25 @@ import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
|||
import com.minelittlepony.unicopia.entity.Creature;
|
||||
import com.minelittlepony.unicopia.entity.EntityReference;
|
||||
import com.minelittlepony.unicopia.entity.Equine;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
import com.minelittlepony.unicopia.projectile.ProjectileDelegate;
|
||||
import com.minelittlepony.unicopia.util.Weighted;
|
||||
import com.minelittlepony.unicopia.util.shape.Shape;
|
||||
import com.minelittlepony.unicopia.util.shape.Sphere;
|
||||
|
||||
import net.minecraft.entity.*;
|
||||
import net.minecraft.entity.effect.StatusEffectInstance;
|
||||
import net.minecraft.entity.effect.StatusEffects;
|
||||
import net.minecraft.entity.mob.MobEntity;
|
||||
import net.minecraft.entity.passive.VillagerEntity;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.nbt.NbtElement;
|
||||
import net.minecraft.nbt.NbtList;
|
||||
import net.minecraft.particle.ParticleTypes;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.hit.EntityHitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.Difficulty;
|
||||
|
@ -29,7 +38,7 @@ import net.minecraft.world.WorldEvents;
|
|||
/**
|
||||
* An area-effect spell that summons the undead.
|
||||
*/
|
||||
public class NecromancySpell extends AbstractAreaEffectSpell {
|
||||
public class NecromancySpell extends AbstractAreaEffectSpell implements ProjectileDelegate.EntityHitListener, ProjectileDelegate.BlockHitListener {
|
||||
private final Supplier<Optional<EntityType<? extends LivingEntity>>> spawnPool = new Weighted.Builder<EntityType<? extends LivingEntity>>()
|
||||
.put(7, EntityType.ZOMBIE)
|
||||
.put(4, EntityType.HUSK)
|
||||
|
@ -38,6 +47,23 @@ public class NecromancySpell extends AbstractAreaEffectSpell {
|
|||
.put(1, EntityType.ZOMBIE_VILLAGER)
|
||||
.build();
|
||||
|
||||
static final Map<Predicate<Entity>, EntityType<? extends MobEntity>> NECROMANTIC_CONVERSIONS = Map.of(
|
||||
match(EntityType.PIGLIN), EntityType.ZOMBIFIED_PIGLIN,
|
||||
match(EntityType.HOGLIN), EntityType.ZOGLIN,
|
||||
match(EntityType.HORSE), EntityType.ZOMBIE_HORSE,
|
||||
match(EntityType.DONKEY), EntityType.SKELETON_HORSE,
|
||||
match(EntityType.ZOMBIE), EntityType.HUSK,
|
||||
match(EntityType.SKELETON), EntityType.WITHER_SKELETON,
|
||||
match(EntityType.WANDERING_TRADER), EntityType.WITCH,
|
||||
match(EntityType.WITHER), EntityType.WARDEN,
|
||||
match(EntityType.WARDEN), EntityType.RABBIT,
|
||||
(e -> e instanceof VillagerEntity), EntityType.ZOMBIE_VILLAGER
|
||||
);
|
||||
|
||||
static Predicate<Entity> match(EntityType<?> type) {
|
||||
return e -> e.getType() == type;
|
||||
}
|
||||
|
||||
private final List<EntityReference<LivingEntity>> summonedEntities = new ArrayList<>();
|
||||
|
||||
private int spawnCountdown;
|
||||
|
@ -172,4 +198,37 @@ public class NecromancySpell extends AbstractAreaEffectSpell {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(MagicProjectileEntity source, BlockHitResult hit) {
|
||||
|
||||
// source.asWorld().createExplosion(source, hit.getPos().x, hit.getPos().y, hit.getPos().z, 3, ExplosionSourceType.MOB);
|
||||
|
||||
Shape affectRegion = new Sphere(false, 3);
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
Vec3d pos = affectRegion.computePoint(source.asWorld().random).add(source.getOriginVector());
|
||||
|
||||
BlockPos loc = new BlockPos(pos);
|
||||
|
||||
if (source.asWorld().isAir(loc.up()) && !source.asWorld().isAir(loc)) {
|
||||
spawnPool.get().ifPresent(type -> {
|
||||
spawnMonster(source, pos, type);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
summonedEntities.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(MagicProjectileEntity projectile, EntityHitResult hit) {
|
||||
NECROMANTIC_CONVERSIONS.entrySet().stream().filter(entry -> entry.getKey().test(hit.getEntity())).findFirst().ifPresent(entry -> {
|
||||
MobEntity newEntity = ((MobEntity)hit.getEntity()).convertTo(entry.getValue(), true);
|
||||
|
||||
if (newEntity != null) {
|
||||
newEntity.addStatusEffect(new StatusEffectInstance(StatusEffects.NAUSEA, 200, 0));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
|||
import com.minelittlepony.unicopia.entity.CastSpellEntity;
|
||||
import com.minelittlepony.unicopia.entity.UEntities;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.item.group.MultiItem;
|
||||
|
||||
import net.minecraft.client.item.TooltipContext;
|
||||
import net.minecraft.entity.Entity;
|
||||
|
@ -32,7 +33,7 @@ import net.minecraft.util.TypedActionResult;
|
|||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class EnchantedStaffItem extends StaffItem implements EnchantableItem, ChargeableItem {
|
||||
public class EnchantedStaffItem extends StaffItem implements EnchantableItem, ChargeableItem, MultiItem {
|
||||
|
||||
private static final Map<EntityType<?>, SpellType<?>> ENTITY_TYPE_TO_SPELL = new HashMap<>();
|
||||
public static <T extends Spell> SpellType<T> register(EntityType<?> entityType, SpellType<T> spellType) {
|
||||
|
@ -58,6 +59,7 @@ public class EnchantedStaffItem extends StaffItem implements EnchantableItem, Ch
|
|||
register(EntityType.CREEPER, SpellType.CATAPULT);
|
||||
register(EntityType.HUSK, SpellType.HYDROPHOBIC);
|
||||
register(EntityType.SNOW_GOLEM, SpellType.FROST);
|
||||
register(EntityType.POLAR_BEAR, SpellType.FROST);
|
||||
register(EntityType.FIREBALL, SpellType.FLAME);
|
||||
register(EntityType.SMALL_FIREBALL, SpellType.FLAME);
|
||||
register(EntityType.ENDER_DRAGON, SpellType.DISPLACEMENT);
|
||||
|
@ -78,8 +80,8 @@ public class EnchantedStaffItem extends StaffItem implements EnchantableItem, Ch
|
|||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getDefaultStack() {
|
||||
return EnchantableItem.enchant(super.getDefaultStack(), SpellType.FIRE_BOLT);
|
||||
public List<ItemStack> getDefaultStacks() {
|
||||
return ENTITY_TYPE_TO_SPELL.values().stream().distinct().map(type -> EnchantableItem.enchant(getDefaultStack(), type)).toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -197,6 +199,14 @@ public class EnchantedStaffItem extends StaffItem implements EnchantableItem, Ch
|
|||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getName(ItemStack stack) {
|
||||
if (EnchantableItem.isEnchanted(stack) && hasCharge(stack)) {
|
||||
return Text.translatable(this.getTranslationKey(stack) + ".enchanted", super.getName(stack), EnchantableItem.getSpellKey(stack).getName());
|
||||
}
|
||||
return super.getName(stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDischarge(ItemStack stack) {
|
||||
if ((stack.hasNbt() && stack.getNbt().contains("energy") ? stack.getNbt().getFloat("energy") : 0) == 0) {
|
||||
|
|
|
@ -97,6 +97,7 @@
|
|||
"item.unicopia.grogars_bell": "Grogar's Bell",
|
||||
"item.unicopia.grogars_bell.charges": "Charges: %d / %d",
|
||||
"item.unicopia.magic_staff": "Magic Staff",
|
||||
"item.unicopia.magic_staff.enchanted": "%s of %s",
|
||||
"item.unicopia.magic_staff.charges": "Charges: %d / %d",
|
||||
"item.unicopia.meadowbrooks_staff": "Meadowbrook's Staff",
|
||||
"item.unicopia.meadowbrooks_staff.lore": "A Heavy Stick",
|
||||
|
|
Loading…
Reference in a new issue