mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Added the staff of remembrance
This commit is contained in:
parent
6c8cb739cd
commit
2384663901
19 changed files with 372 additions and 49 deletions
|
@ -153,8 +153,19 @@ public class EntityProjectile extends EntitySnowball implements IMagicals, ICast
|
|||
|
||||
@Override
|
||||
public void onUpdate() {
|
||||
|
||||
if (!world.isRemote) {
|
||||
if (Math.abs(motionX) < 0.01 && Math.abs(motionZ) < 0.01 && Math.abs(motionY) < 0.01) {
|
||||
setDead();
|
||||
}
|
||||
}
|
||||
|
||||
super.onUpdate();
|
||||
|
||||
if (ticksExisted % 1000 == 0) {
|
||||
setNoGravity(false);
|
||||
}
|
||||
|
||||
if (hasEffect()) {
|
||||
if (getEffect().getDead()) {
|
||||
setDead();
|
||||
|
@ -211,13 +222,13 @@ public class EntityProjectile extends EntitySnowball implements IMagicals, ICast
|
|||
Item item = getItem().getItem();
|
||||
|
||||
if (item instanceof ITossableItem) {
|
||||
((ITossableItem)item).onImpact(world, result.getBlockPos(), world.getBlockState(result.getBlockPos()));
|
||||
((ITossableItem)item).onImpact(this, result.getBlockPos(), world.getBlockState(result.getBlockPos()));
|
||||
}
|
||||
|
||||
if (hasEffect()) {
|
||||
IMagicEffect effect = this.getEffect();
|
||||
if (effect instanceof ITossable) {
|
||||
((ITossable<?>)effect).onImpact(world, result.getBlockPos(), world.getBlockState(result.getBlockPos()));
|
||||
((ITossable<?>)effect).onImpact(this, result.getBlockPos(), world.getBlockState(result.getBlockPos()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import com.minelittlepony.unicopia.item.ItemCereal;
|
|||
import com.minelittlepony.unicopia.item.ItemCloud;
|
||||
import com.minelittlepony.unicopia.item.ItemCurse;
|
||||
import com.minelittlepony.unicopia.item.ItemFruitLeaves;
|
||||
import com.minelittlepony.unicopia.item.ItemMagicStaff;
|
||||
import com.minelittlepony.unicopia.item.ItemMoss;
|
||||
import com.minelittlepony.unicopia.item.ItemOfHolding;
|
||||
import com.minelittlepony.unicopia.item.ItemRottenApple;
|
||||
|
@ -22,6 +23,7 @@ import com.minelittlepony.unicopia.item.UItemDecoration;
|
|||
import com.minelittlepony.unicopia.item.UItemSlab;
|
||||
import com.minelittlepony.unicopia.item.URecord;
|
||||
import com.minelittlepony.unicopia.spell.SpellRegistry;
|
||||
import com.minelittlepony.unicopia.spell.SpellScorch;
|
||||
|
||||
import net.minecraft.block.BlockDoublePlant;
|
||||
import net.minecraft.block.BlockFlower;
|
||||
|
@ -140,6 +142,7 @@ public class UItems {
|
|||
|
||||
public static final ItemSpellbook spellbook = new ItemSpellbook(Unicopia.MODID, "spellbook");
|
||||
public static final Item staff_meadow_brook = new ItemStaff(Unicopia.MODID, "staff_meadow_brook").setMaxDamage(2);
|
||||
public static final Item staff_remembrance = new ItemMagicStaff(Unicopia.MODID, "staff_remembrance", new SpellScorch());
|
||||
|
||||
public static final ItemMoss moss = new ItemMoss(Unicopia.MODID, "moss");
|
||||
|
||||
|
@ -243,7 +246,7 @@ public class UItems {
|
|||
cloud_farmland, mist_door, library_door, bakery_door, anvil,
|
||||
|
||||
bag_of_holding, spell, curse, spellbook, mug, enchanted_torch,
|
||||
staff_meadow_brook, alicorn_amulet,
|
||||
staff_meadow_brook, staff_remembrance, alicorn_amulet,
|
||||
|
||||
alfalfa_seeds, alfalfa_leaves,
|
||||
cereal, sugar_cereal, sugar_block,
|
||||
|
@ -278,7 +281,7 @@ public class UItems {
|
|||
cloud_farmland, mist_door, library_door, bakery_door, anvil,
|
||||
|
||||
bag_of_holding, spell, curse, spellbook, mug, enchanted_torch,
|
||||
staff_meadow_brook, alicorn_amulet,
|
||||
staff_meadow_brook, staff_remembrance, alicorn_amulet,
|
||||
|
||||
alfalfa_seeds, alfalfa_leaves,
|
||||
cereal, sugar_cereal, sugar_block,
|
||||
|
|
|
@ -0,0 +1,160 @@
|
|||
package com.minelittlepony.unicopia.item;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.Predicates;
|
||||
import com.minelittlepony.unicopia.power.IPower;
|
||||
import com.minelittlepony.unicopia.spell.CasterUtils;
|
||||
import com.minelittlepony.unicopia.spell.IAligned;
|
||||
import com.minelittlepony.unicopia.spell.ICaster;
|
||||
import com.minelittlepony.unicopia.spell.ITossedEffect;
|
||||
import com.minelittlepony.unicopia.spell.SpellAffinity;
|
||||
import com.minelittlepony.unicopia.tossable.ITossableItem;
|
||||
import com.minelittlepony.util.lang.ClientLocale;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.util.ITooltipFlag;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.SoundEvents;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.EnumActionResult;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.EnumParticleTypes;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class ItemMagicStaff extends ItemStaff implements IAligned, ITossableItem {
|
||||
|
||||
@Nonnull
|
||||
private final ITossedEffect effect;
|
||||
|
||||
public ItemMagicStaff(String domain, String name, @Nonnull ITossedEffect effect) {
|
||||
super(domain, name);
|
||||
|
||||
this.effect = effect;
|
||||
setMaxDamage(500);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInformation(ItemStack stack, @Nullable World worldIn, List<String> tooltip, ITooltipFlag flagIn) {
|
||||
SpellAffinity affinity = getAffinity();
|
||||
tooltip.add(affinity.getColourCode() + ClientLocale.format(affinity.getUnlocalizedName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {
|
||||
if (Predicates.MAGI.test(player) && hand == EnumHand.MAIN_HAND) {
|
||||
ItemStack itemstack = player.getHeldItem(hand);
|
||||
|
||||
player.setActiveHand(hand);
|
||||
|
||||
return new ActionResult<ItemStack>(EnumActionResult.SUCCESS, itemstack);
|
||||
}
|
||||
|
||||
return super.onItemRightClick(world, player, hand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerStoppedUsing(ItemStack itemstack, World world, EntityLivingBase entity, int timeLeft) {
|
||||
if (Predicates.MAGI.test(entity) && entity instanceof EntityPlayer) {
|
||||
|
||||
int i = getMaxItemUseDuration(itemstack) - timeLeft;
|
||||
|
||||
if (i > 10) {
|
||||
if (canBeThrown(itemstack)) {
|
||||
toss(world, itemstack, (EntityPlayer)entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean castContainedEffect(ItemStack stack, EntityLivingBase target, EntityLivingBase attacker) {
|
||||
if (attacker.isSneaking()) {
|
||||
stack.damageItem(50, attacker);
|
||||
|
||||
if (attacker instanceof EntityPlayer) {
|
||||
IPower.takeFromPlayer((EntityPlayer)attacker, 4);
|
||||
}
|
||||
|
||||
onImpact(
|
||||
CasterUtils.toCaster(target).orElseGet(() -> CasterUtils.near(target)),
|
||||
target.getPosition(),
|
||||
target.getEntityWorld().getBlockState(target.getPosition())
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void onUpdate(ItemStack stack, World world, Entity entity, int itemSlot, boolean isSelected) {
|
||||
|
||||
if (entity instanceof EntityLivingBase) {
|
||||
EntityLivingBase living = (EntityLivingBase)entity;
|
||||
|
||||
if (living.getActiveItemStack().getItem() == this) {
|
||||
Vec3d eyes = entity.getPositionEyes(1);
|
||||
|
||||
float i = getMaxItemUseDuration(stack) - living.getItemInUseCount();
|
||||
|
||||
world.spawnParticle(i > 150 ? EnumParticleTypes.SMOKE_LARGE : EnumParticleTypes.CLOUD, eyes.x, eyes.y, eyes.z,
|
||||
(world.rand.nextGaussian() - 0.5) / 10,
|
||||
(world.rand.nextGaussian() - 0.5) / 10,
|
||||
(world.rand.nextGaussian() - 0.5) / 10
|
||||
);
|
||||
world.playSound(null, entity.getPosition(), SoundEvents.ENTITY_GUARDIAN_ATTACK, SoundCategory.PLAYERS, 1, i / 20);
|
||||
|
||||
if (i > 200) {
|
||||
living.resetActiveHand();
|
||||
living.attackEntityFrom(DamageSource.MAGIC, 1200);
|
||||
onImpact(
|
||||
CasterUtils.toCaster(entity).orElseGet(() -> CasterUtils.near(entity)),
|
||||
entity.getPosition(),
|
||||
entity.getEntityWorld().getBlockState(entity.getPosition())
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int getMaxItemUseDuration(ItemStack stack) {
|
||||
return 72000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeThrown(ItemStack stack) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toss(World world, ItemStack stack, EntityPlayer player) {
|
||||
CasterUtils.toCaster(player).ifPresent(effect::toss);
|
||||
|
||||
IPower.takeFromPlayer(player, 4);
|
||||
|
||||
stack.damageItem(1, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(ICaster<?> caster, BlockPos pos, IBlockState state) {
|
||||
effect.onImpact(caster, pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpellAffinity getAffinity() {
|
||||
return effect.getAffinity();
|
||||
}
|
||||
|
||||
}
|
|
@ -8,11 +8,9 @@ import javax.annotation.Nullable;
|
|||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.minelittlepony.unicopia.Predicates;
|
||||
import com.minelittlepony.unicopia.tossable.ITossableItem;
|
||||
import com.minelittlepony.util.lang.ClientLocale;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.util.ITooltipFlag;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
|
@ -25,15 +23,11 @@ import net.minecraft.inventory.EntityEquipmentSlot;
|
|||
import net.minecraft.item.EnumAction;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemSword;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.EnumActionResult;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.EnumParticleTypes;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class ItemStaff extends ItemSword implements ITossableItem {
|
||||
public class ItemStaff extends ItemSword {
|
||||
|
||||
protected static final UUID ATTACK_REACH_MODIFIER = UUID.fromString("FA235E1C-4280-A865-B01B-CBAE9985ACA3");
|
||||
|
||||
|
@ -46,19 +40,6 @@ public class ItemStaff extends ItemSword implements ITossableItem {
|
|||
setMaxStackSize(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {
|
||||
ItemStack itemstack = player.getHeldItem(hand);
|
||||
|
||||
if (canBeThrown(itemstack)) {
|
||||
toss(world, itemstack, player);
|
||||
|
||||
return new ActionResult<ItemStack>(EnumActionResult.SUCCESS, itemstack);
|
||||
}
|
||||
|
||||
return super.onItemRightClick(world, player, hand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLeftClickEntity(ItemStack stack, EntityPlayer player, Entity target) {
|
||||
World w = player.getEntityWorld();
|
||||
|
@ -113,16 +94,6 @@ public class ItemStaff extends ItemSword implements ITossableItem {
|
|||
return EnumAction.BOW;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeThrown(ItemStack stack) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(World world, BlockPos pos, IBlockState state) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Multimap<String, AttributeModifier> getItemAttributeModifiers(EntityEquipmentSlot slot) {
|
||||
Multimap<String, AttributeModifier> multimap = HashMultimap.create();
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.minelittlepony.unicopia.item;
|
|||
|
||||
import com.minelittlepony.unicopia.forgebullshit.IMultiItem;
|
||||
import com.minelittlepony.unicopia.player.PlayerSpeciesList;
|
||||
import com.minelittlepony.unicopia.spell.ICaster;
|
||||
import com.minelittlepony.unicopia.tossable.ITossableItem;
|
||||
|
||||
import net.minecraft.block.material.Material;
|
||||
|
@ -96,9 +97,9 @@ public class ItemTomato extends ItemFood implements ITossableItem, IMultiItem {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(World world, BlockPos pos, IBlockState state) {
|
||||
if (!world.isRemote && state.getMaterial() == Material.GLASS) {
|
||||
world.destroyBlock(pos, true);
|
||||
public void onImpact(ICaster<?> caster, BlockPos pos, IBlockState state) {
|
||||
if (caster.isLocal() && state.getMaterial() == Material.GLASS) {
|
||||
caster.getWorld().destroyBlock(pos, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,12 @@ package com.minelittlepony.unicopia.spell;
|
|||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.collect.Streams;
|
||||
import com.minelittlepony.unicopia.Predicates;
|
||||
import com.minelittlepony.unicopia.entity.EntitySpell;
|
||||
import com.minelittlepony.unicopia.player.PlayerSpeciesList;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
|
@ -71,6 +73,13 @@ public class CasterUtils {
|
|||
.anyMatch(s -> s.equals(effectName));
|
||||
}
|
||||
|
||||
public static ICaster<?> near(@Nonnull Entity entity) {
|
||||
EntitySpell caster = new EntitySpell(entity.world);
|
||||
caster.copyLocationAndAnglesFrom(entity);
|
||||
|
||||
return caster;
|
||||
}
|
||||
|
||||
public static Optional<ICaster<?>> toCaster(@Nullable Entity entity) {
|
||||
|
||||
if (entity instanceof ICaster<?>) {
|
||||
|
|
|
@ -7,6 +7,7 @@ import java.util.stream.Stream;
|
|||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.entity.EntitySpell;
|
||||
import com.minelittlepony.unicopia.player.IOwned;
|
||||
import com.minelittlepony.unicopia.power.IPower;
|
||||
import com.minelittlepony.util.shape.IShape;
|
||||
|
@ -59,6 +60,20 @@ public interface ICaster<E extends EntityLivingBase> extends IOwned<E>, ILevelle
|
|||
return getEntity().getEntityWorld();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if we're executing on the client.
|
||||
*/
|
||||
default boolean isRemote() {
|
||||
return getWorld().isRemote;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if we're executing on the server.
|
||||
*/
|
||||
default boolean isLocal() {
|
||||
return !isRemote();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the center position where this caster is located.
|
||||
*/
|
||||
|
@ -66,6 +81,14 @@ public interface ICaster<E extends EntityLivingBase> extends IOwned<E>, ILevelle
|
|||
return getEntity().getPosition();
|
||||
}
|
||||
|
||||
default ICaster<?> at(BlockPos newOrigin) {
|
||||
EntitySpell spell = new EntitySpell(getWorld());
|
||||
spell.setPosition(newOrigin.getX(), newOrigin.getY(), newOrigin.getZ());
|
||||
spell.setOwner(getOwner());
|
||||
|
||||
return spell;
|
||||
}
|
||||
|
||||
default Vec3d getOriginVector() {
|
||||
return getEntity().getPositionVector();
|
||||
}
|
||||
|
@ -99,6 +122,4 @@ public interface ICaster<E extends EntityLivingBase> extends IOwned<E>, ILevelle
|
|||
default Stream<Entity> findAllEntitiesInRange(double radius) {
|
||||
return VecHelper.findAllEntitiesInRange(getEntity(), getWorld(), getOrigin(), radius);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,29 +1,38 @@
|
|||
package com.minelittlepony.unicopia.spell;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.entity.EntityProjectile;
|
||||
import com.minelittlepony.unicopia.init.UItems;
|
||||
import com.minelittlepony.unicopia.tossable.ITossable;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.init.SoundEvents;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.SoundEvent;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public interface ITossedEffect extends IMagicEffect, ITossable<ICaster<?>> {
|
||||
|
||||
default SoundEvent getThrowSound(ICaster<?> caster) {
|
||||
return SoundEvents.ITEM_CHORUS_FRUIT_TELEPORT;
|
||||
}
|
||||
|
||||
default ItemStack getCastAppearance(ICaster<?> caster) {
|
||||
Item item = this.getAffinity() == SpellAffinity.BAD ? UItems.curse : UItems.spell;
|
||||
|
||||
return SpellRegistry.instance().enchantStack(new ItemStack(item), getName());
|
||||
}
|
||||
|
||||
default void toss(ICaster<?> caster) {
|
||||
@Nullable
|
||||
default EntityProjectile toss(ICaster<?> caster) {
|
||||
World world = caster.getWorld();
|
||||
|
||||
Entity entity = caster.getOwner();
|
||||
|
||||
world.playSound(null, entity.posX, entity.posY, entity.posZ, getThrowSound(caster), SoundCategory.NEUTRAL, 0.5F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F));
|
||||
world.playSound(null, entity.posX, entity.posY, entity.posZ, getThrowSound(caster), SoundCategory.NEUTRAL, 0.7F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F));
|
||||
|
||||
if (!world.isRemote) {
|
||||
EntityProjectile projectile = new EntityProjectile(world, caster.getOwner());
|
||||
|
@ -36,6 +45,10 @@ public interface ITossedEffect extends IMagicEffect, ITossable<ICaster<?>> {
|
|||
projectile.shoot(entity, entity.rotationPitch, entity.rotationYaw, 0, 1.5F, 1);
|
||||
|
||||
world.spawnEntity(projectile);
|
||||
|
||||
return projectile;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,10 @@ public enum SpellAffinity {
|
|||
return this == BAD ? "curse" : "spell";
|
||||
}
|
||||
|
||||
public String getUnlocalizedName() {
|
||||
return "affinity." + getTranslationKey() + ".name";
|
||||
}
|
||||
|
||||
public int getCorruption() {
|
||||
return corruption;
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ public class SpellAwkward extends AbstractSpell implements ITossedEffect, IUseAc
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(World world, BlockPos pos, IBlockState state) {
|
||||
public void onImpact(ICaster<?> caster, BlockPos pos, IBlockState state) {
|
||||
// noop
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ import com.minelittlepony.unicopia.init.USounds;
|
|||
import com.minelittlepony.unicopia.player.IPlayer;
|
||||
import com.minelittlepony.unicopia.player.PlayerSpeciesList;
|
||||
import com.minelittlepony.util.WorldEvent;
|
||||
import com.minelittlepony.util.vector.VecHelper;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
@ -20,7 +19,6 @@ import net.minecraft.potion.PotionEffect;
|
|||
import net.minecraft.util.EnumParticleTypes;
|
||||
import net.minecraft.util.SoundEvent;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class SpellChangelingTrap extends AbstractSpell implements ITossedEffect, IAttachedEffect {
|
||||
|
||||
|
@ -154,9 +152,9 @@ public class SpellChangelingTrap extends AbstractSpell implements ITossedEffect,
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(World world, BlockPos pos, IBlockState state) {
|
||||
if (!world.isRemote) {
|
||||
VecHelper.findAllEntitiesInRange(null, world, pos, 5)
|
||||
public void onImpact(ICaster<?> caster, BlockPos pos, IBlockState state) {
|
||||
if (caster.isLocal()) {
|
||||
caster.findAllEntitiesInRange(5)
|
||||
.filter(e -> e instanceof EntityPlayer)
|
||||
.map(e -> PlayerSpeciesList.instance().getPlayer((EntityPlayer)e))
|
||||
.forEach(this::entrap);
|
||||
|
|
|
@ -48,6 +48,7 @@ public class SpellRegistry {
|
|||
registerSpell(SpellSiphon::new);
|
||||
registerSpell(SpellLight::new);
|
||||
registerSpell(SpellChangelingTrap::new);
|
||||
registerSpell(SpellScorch::new);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
package com.minelittlepony.unicopia.spell;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.entity.EntityProjectile;
|
||||
import com.minelittlepony.unicopia.init.UParticles;
|
||||
import com.minelittlepony.util.PosHelper;
|
||||
import com.minelittlepony.util.shape.Sphere;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.util.EnumParticleTypes;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
public class SpellScorch extends SpellFire implements ITossedEffect {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "scorch";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCraftable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTint() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update(ICaster<?> source) {
|
||||
|
||||
BlockPos pos = PosHelper.findSolidGroundAt(source.getWorld(), source.getOrigin());
|
||||
|
||||
IBlockState state = source.getWorld().getBlockState(pos);
|
||||
|
||||
IBlockState newState = affected.getConverted(state);
|
||||
|
||||
if (!state.equals(newState)) {
|
||||
source.getWorld().setBlockState(pos, newState, 3);
|
||||
source.spawnParticles(new Sphere(false, 1), 5, p -> {
|
||||
p = PosHelper.offset(p, pos);
|
||||
|
||||
source.getWorld().spawnParticle(EnumParticleTypes.SMOKE_NORMAL,
|
||||
p.x, p.y, p.z, 0, 0, 0);
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(ICaster<?> source) {
|
||||
source.spawnParticles(EnumParticleTypes.FLAME.getParticleID(), 3);
|
||||
source.spawnParticles(UParticles.UNICORN_MAGIC, 3, getTint());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpellAffinity getAffinity() {
|
||||
return SpellAffinity.BAD;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public EntityProjectile toss(ICaster<?> caster) {
|
||||
EntityProjectile projectile = ITossedEffect.super.toss(caster);
|
||||
|
||||
if (projectile != null) {
|
||||
projectile.setNoGravity(true);
|
||||
}
|
||||
|
||||
return projectile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(ICaster<?> caster, BlockPos pos, IBlockState state) {
|
||||
if (caster.isLocal()) {
|
||||
caster.getWorld().newExplosion(caster.getOwner(), pos.getX(), pos.getY(), pos.getZ(), 2, true, true);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,13 +1,14 @@
|
|||
package com.minelittlepony.unicopia.tossable;
|
||||
|
||||
import com.minelittlepony.unicopia.spell.ICaster;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.SoundEvents;
|
||||
import net.minecraft.util.SoundEvent;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public interface ITossable<T> {
|
||||
void onImpact(World world, BlockPos pos, IBlockState state);
|
||||
void onImpact(ICaster<?> caster, BlockPos pos, IBlockState state);
|
||||
|
||||
default SoundEvent getThrowSound(T stack) {
|
||||
return SoundEvents.ENTITY_SNOWBALL_THROW;
|
||||
|
|
|
@ -12,10 +12,25 @@ import com.minelittlepony.util.shape.IShape;
|
|||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraft.util.math.BlockPos.MutableBlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class PosHelper {
|
||||
|
||||
public static Vec3d offset(Vec3d a, Vec3i b) {
|
||||
return a.add(b.getX(), b.getY(), b.getZ());
|
||||
}
|
||||
|
||||
public static BlockPos findSolidGroundAt(World world, BlockPos pos) {
|
||||
while ((pos.getY() > 0 || !world.isOutsideBuildHeight(pos))
|
||||
&& (world.isAirBlock(pos) || world.getBlockState(pos).getBlock().isReplaceable(world, pos))) {
|
||||
pos = pos.down();
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
public static void all(BlockPos origin, Consumer<BlockPos> consumer, EnumFacing... directions) {
|
||||
for (EnumFacing facing : directions) {
|
||||
consumer.accept(origin.offset(facing));
|
||||
|
|
|
@ -43,6 +43,7 @@ item.chitin_shell.name=Chitinous Shell
|
|||
item.moss.name=Moss
|
||||
item.staff_meadow_brook.name=Meadow Brook's Staff
|
||||
item.staff_meadow_brook.tagline=It's a big stick
|
||||
item.staff_remembrance.name=Staff of Remembrance
|
||||
item.alicorn_amulet.name=The Alicorn Amulet
|
||||
item.alicorn_amulet.tagline=Time Worn: %s
|
||||
|
||||
|
@ -53,6 +54,10 @@ item.gem.enchanted.name=Gem of %s
|
|||
item.corrupted_gem.name=Fractured Gem
|
||||
item.corrupted_gem.enchanted.name=Fractured Gem of %s
|
||||
|
||||
affinity.good.name=Pure
|
||||
affinity.neutral.name=Neutral
|
||||
affinity.bad.name=Corrupt
|
||||
|
||||
spell.shield.name=Defense
|
||||
spell.shield.tagline=Protection I
|
||||
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "unicopia:item/handheld_staff",
|
||||
"textures": {
|
||||
"layer0": "unicopia:items/staff_remembrance"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"pattern": [
|
||||
" /*",
|
||||
" / ",
|
||||
"/ "
|
||||
],
|
||||
"key": {
|
||||
"/": [
|
||||
{ "item": "minecraft:stick" }
|
||||
],
|
||||
"*": [
|
||||
{
|
||||
"item": "unicopia:gem",
|
||||
"nbt": {
|
||||
"spell": "fire"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"result": { "item": "unicopia:staff_remembrence", "count": 1 }
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
Loading…
Reference in a new issue