mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-30 16:28:00 +01:00
Added support for thrown spells. Projectiles with a spell attached.
This commit is contained in:
parent
41923f82e1
commit
28e294803e
14 changed files with 247 additions and 71 deletions
|
@ -1,7 +1,14 @@
|
||||||
package com.minelittlepony.unicopia.entity;
|
package com.minelittlepony.unicopia.entity;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.item.ITossable;
|
import com.minelittlepony.unicopia.network.EffectSync;
|
||||||
|
import com.minelittlepony.unicopia.spell.ICaster;
|
||||||
|
import com.minelittlepony.unicopia.spell.IMagicEffect;
|
||||||
|
import com.minelittlepony.unicopia.spell.SpellAffinity;
|
||||||
|
import com.minelittlepony.unicopia.spell.SpellRegistry;
|
||||||
|
import com.minelittlepony.unicopia.tossable.ITossable;
|
||||||
|
import com.minelittlepony.unicopia.tossable.ITossableItem;
|
||||||
|
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.entity.IProjectile;
|
import net.minecraft.entity.IProjectile;
|
||||||
import net.minecraft.entity.projectile.EntitySnowball;
|
import net.minecraft.entity.projectile.EntitySnowball;
|
||||||
|
@ -16,13 +23,19 @@ import net.minecraft.util.EnumParticleTypes;
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class EntityProjectile extends EntitySnowball {
|
public class EntityProjectile extends EntitySnowball implements IMagicals, ICaster<EntityLivingBase> {
|
||||||
|
|
||||||
private static final DataParameter<ItemStack> ITEM = EntityDataManager
|
private static final DataParameter<ItemStack> ITEM = EntityDataManager
|
||||||
.createKey(EntityProjectile.class, DataSerializers.ITEM_STACK);
|
.createKey(EntityProjectile.class, DataSerializers.ITEM_STACK);
|
||||||
|
|
||||||
private static final DataParameter<Float> DAMAGE = EntityDataManager
|
private static final DataParameter<Float> DAMAGE = EntityDataManager
|
||||||
.createKey(EntityProjectile.class, DataSerializers.FLOAT);
|
.createKey(EntityProjectile.class, DataSerializers.FLOAT);
|
||||||
|
|
||||||
|
private static final DataParameter<NBTTagCompound> EFFECT = EntityDataManager
|
||||||
|
.createKey(EntitySpell.class, DataSerializers.COMPOUND_TAG);
|
||||||
|
|
||||||
|
private final EffectSync<EntityLivingBase> effectDelegate = new EffectSync<>(this, EFFECT);
|
||||||
|
|
||||||
public EntityProjectile(World world) {
|
public EntityProjectile(World world) {
|
||||||
super(world);
|
super(world);
|
||||||
}
|
}
|
||||||
|
@ -39,6 +52,7 @@ public class EntityProjectile extends EntitySnowball {
|
||||||
protected void entityInit() {
|
protected void entityInit() {
|
||||||
getDataManager().register(ITEM, ItemStack.EMPTY);
|
getDataManager().register(ITEM, ItemStack.EMPTY);
|
||||||
getDataManager().register(DAMAGE, (float)0);
|
getDataManager().register(DAMAGE, (float)0);
|
||||||
|
getDataManager().register(EFFECT, new NBTTagCompound());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemStack getItem() {
|
public ItemStack getItem() {
|
||||||
|
@ -47,6 +61,50 @@ public class EntityProjectile extends EntitySnowball {
|
||||||
return stack == null ? ItemStack.EMPTY : stack;
|
return stack == null ? ItemStack.EMPTY : stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Entity getEntity() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOwner(EntityLivingBase owner) {
|
||||||
|
thrower = owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityLivingBase getOwner() {
|
||||||
|
return getThrower();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCurrentLevel() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCurrentLevel(int level) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SpellAffinity getAffinity() {
|
||||||
|
return hasEffect() ? SpellAffinity.NEUTRAL : getEffect().getAffinity();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setEffect(IMagicEffect effect) {
|
||||||
|
effectDelegate.set(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends IMagicEffect> T getEffect(Class<T> type, boolean update) {
|
||||||
|
return effectDelegate.get(type, update);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasEffect() {
|
||||||
|
return effectDelegate.has();
|
||||||
|
}
|
||||||
|
|
||||||
public void setItem(ItemStack stack) {
|
public void setItem(ItemStack stack) {
|
||||||
getDataManager().set(ITEM, stack);
|
getDataManager().set(ITEM, stack);
|
||||||
getDataManager().setDirty(ITEM);
|
getDataManager().setDirty(ITEM);
|
||||||
|
@ -71,6 +129,27 @@ public class EntityProjectile extends EntitySnowball {
|
||||||
} else {
|
} else {
|
||||||
setItem(itemstack);
|
setItem(itemstack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (compound.hasKey("effect")) {
|
||||||
|
setEffect(SpellRegistry.instance().createEffectFromNBT(compound.getCompoundTag("effect")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUpdate() {
|
||||||
|
super.onUpdate();
|
||||||
|
|
||||||
|
if (hasEffect()) {
|
||||||
|
if (getEffect().getDead()) {
|
||||||
|
setDead();
|
||||||
|
} else {
|
||||||
|
getEffect().update(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (world.isRemote) {
|
||||||
|
getEffect().render(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -93,6 +172,10 @@ public class EntityProjectile extends EntitySnowball {
|
||||||
if (!itemstack.isEmpty()) {
|
if (!itemstack.isEmpty()) {
|
||||||
compound.setTag("Item", itemstack.writeToNBT(new NBTTagCompound()));
|
compound.setTag("Item", itemstack.writeToNBT(new NBTTagCompound()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasEffect()) {
|
||||||
|
compound.setTag("effect", SpellRegistry.instance().serializeEffectToNBT(getEffect()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -101,8 +184,15 @@ public class EntityProjectile extends EntitySnowball {
|
||||||
if (result.typeOfHit == RayTraceResult.Type.BLOCK) {
|
if (result.typeOfHit == RayTraceResult.Type.BLOCK) {
|
||||||
Item item = getItem().getItem();
|
Item item = getItem().getItem();
|
||||||
|
|
||||||
if (item instanceof ITossable) {
|
if (item instanceof ITossableItem) {
|
||||||
((ITossable)item).onImpact(world, result.getBlockPos(), world.getBlockState(result.getBlockPos()));
|
((ITossableItem)item).onImpact(world, 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()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,8 +200,6 @@ public class EntityProjectile extends EntitySnowball {
|
||||||
result.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, getThrower()), getThrowDamage());
|
result.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, getThrower()), getThrowDamage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!world.isRemote) {
|
if (!world.isRemote) {
|
||||||
world.setEntityState(this, (byte)3);
|
world.setEntityState(this, (byte)3);
|
||||||
setDead();
|
setDead();
|
||||||
|
|
|
@ -154,14 +154,8 @@ public class ItemSpell extends Item implements ICastable {
|
||||||
@Override
|
@Override
|
||||||
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {
|
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {
|
||||||
|
|
||||||
Entity target = VecHelper.getLookedAtEntity(player, 5);
|
|
||||||
|
|
||||||
ItemStack stack = player.getHeldItem(hand);
|
ItemStack stack = player.getHeldItem(hand);
|
||||||
|
|
||||||
if (target == null) {
|
|
||||||
return new ActionResult<ItemStack>(EnumActionResult.PASS, stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!SpellRegistry.stackHasEnchantment(stack)) {
|
if (!SpellRegistry.stackHasEnchantment(stack)) {
|
||||||
return new ActionResult<ItemStack>(EnumActionResult.FAIL, stack);
|
return new ActionResult<ItemStack>(EnumActionResult.FAIL, stack);
|
||||||
}
|
}
|
||||||
|
@ -169,7 +163,7 @@ public class ItemSpell extends Item implements ICastable {
|
||||||
IUseAction effect = SpellRegistry.instance().getUseActionFrom(stack);
|
IUseAction effect = SpellRegistry.instance().getUseActionFrom(stack);
|
||||||
|
|
||||||
if (effect != null) {
|
if (effect != null) {
|
||||||
SpellCastResult result = effect.onUse(stack, getAffinity(stack), player, world, target);
|
SpellCastResult result = effect.onUse(stack, getAffinity(stack), player, world, VecHelper.getLookedAtEntity(player, 5));
|
||||||
|
|
||||||
if (result != SpellCastResult.NONE) {
|
if (result != SpellCastResult.NONE) {
|
||||||
if (result == SpellCastResult.PLACE && !player.capabilities.isCreativeMode) {
|
if (result == SpellCastResult.PLACE && !player.capabilities.isCreativeMode) {
|
||||||
|
|
|
@ -8,6 +8,7 @@ import javax.annotation.Nullable;
|
||||||
import com.google.common.collect.HashMultimap;
|
import com.google.common.collect.HashMultimap;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
import com.minelittlepony.unicopia.Predicates;
|
import com.minelittlepony.unicopia.Predicates;
|
||||||
|
import com.minelittlepony.unicopia.tossable.ITossableItem;
|
||||||
import com.minelittlepony.util.lang.ClientLocale;
|
import com.minelittlepony.util.lang.ClientLocale;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
|
@ -32,7 +33,7 @@ import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class ItemStaff extends ItemSword implements ITossable {
|
public class ItemStaff extends ItemSword implements ITossableItem {
|
||||||
|
|
||||||
protected static final UUID ATTACK_REACH_MODIFIER = UUID.fromString("FA235E1C-4280-A865-B01B-CBAE9985ACA3");
|
protected static final UUID ATTACK_REACH_MODIFIER = UUID.fromString("FA235E1C-4280-A865-B01B-CBAE9985ACA3");
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@ package com.minelittlepony.unicopia.item;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.forgebullshit.IMultiItem;
|
import com.minelittlepony.unicopia.forgebullshit.IMultiItem;
|
||||||
import com.minelittlepony.unicopia.player.PlayerSpeciesList;
|
import com.minelittlepony.unicopia.player.PlayerSpeciesList;
|
||||||
|
import com.minelittlepony.unicopia.tossable.ITossableItem;
|
||||||
|
|
||||||
import net.minecraft.block.material.Material;
|
import net.minecraft.block.material.Material;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.creativetab.CreativeTabs;
|
import net.minecraft.creativetab.CreativeTabs;
|
||||||
|
@ -17,7 +19,7 @@ import net.minecraft.util.NonNullList;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class ItemTomato extends ItemFood implements ITossable, IMultiItem {
|
public class ItemTomato extends ItemFood implements ITossableItem, IMultiItem {
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.minelittlepony.unicopia.spell;
|
||||||
|
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.init.SoundEvents;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.SoundEvent;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public interface IRangedEffect extends IMagicEffect {
|
||||||
|
void onImpact(World world, BlockPos pos, IBlockState state);
|
||||||
|
|
||||||
|
default SoundEvent getThrowSound(ItemStack stack) {
|
||||||
|
return SoundEvents.ENTITY_SNOWBALL_THROW;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package com.minelittlepony.unicopia.spell;
|
||||||
|
|
||||||
|
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.item.ItemStack;
|
||||||
|
import net.minecraft.util.SoundCategory;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public interface ITossedEffect extends IMagicEffect, ITossable<ICaster<?>> {
|
||||||
|
|
||||||
|
default void 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));
|
||||||
|
|
||||||
|
if (!world.isRemote) {
|
||||||
|
EntityProjectile projectile = new EntityProjectile(world, caster.getOwner());
|
||||||
|
|
||||||
|
projectile.setItem(new ItemStack(UItems.spell));
|
||||||
|
projectile.setThrowDamage(getThrowDamage(caster));
|
||||||
|
projectile.setOwner(caster.getOwner());
|
||||||
|
projectile.setEffect(this);
|
||||||
|
projectile.shoot(entity, entity.rotationPitch, entity.rotationYaw, 0, 1.5F, 1);
|
||||||
|
|
||||||
|
world.spawnEntity(projectile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
package com.minelittlepony.unicopia.spell;
|
package com.minelittlepony.unicopia.spell;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
@ -43,5 +43,5 @@ public interface IUseAction {
|
||||||
*
|
*
|
||||||
* @return ActionResult for the type of action to perform
|
* @return ActionResult for the type of action to perform
|
||||||
*/
|
*/
|
||||||
SpellCastResult onUse(ItemStack stack, SpellAffinity affinity, EntityPlayer player, World world, @Nonnull Entity hitEntity);
|
SpellCastResult onUse(ItemStack stack, SpellAffinity affinity, EntityPlayer player, World world, @Nullable Entity hitEntity);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,22 @@ package com.minelittlepony.unicopia.spell;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.minelittlepony.util.shape.Sphere;
|
import com.minelittlepony.util.shape.Sphere;
|
||||||
|
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.EnumParticleTypes;
|
import net.minecraft.util.EnumParticleTypes;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class SpellAwkward extends AbstractSpell {
|
public class SpellAwkward extends AbstractSpell implements ITossedEffect, IUseAction {
|
||||||
|
|
||||||
private final List<String> names = Lists.newArrayList(EnumParticleTypes.getParticleNames());
|
private final List<String> names = Lists.newArrayList(EnumParticleTypes.getParticleNames());
|
||||||
|
|
||||||
|
@ -60,4 +69,22 @@ public class SpellAwkward extends AbstractSpell {
|
||||||
default: return true;
|
default: return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onImpact(World world, BlockPos pos, IBlockState state) {
|
||||||
|
// noop
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SpellCastResult onUse(ItemStack stack, SpellAffinity affinity, EntityPlayer player, World world, BlockPos pos, EnumFacing side, float hitX, float hitY, float hitZ) {
|
||||||
|
return SpellCastResult.PLACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SpellCastResult onUse(ItemStack stack, SpellAffinity affinity, EntityPlayer player, World world, @Nullable Entity hitEntity) {
|
||||||
|
|
||||||
|
CasterUtils.toCaster(player).ifPresent(this::toss);
|
||||||
|
|
||||||
|
return SpellCastResult.NONE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.minelittlepony.unicopia.spell;
|
package com.minelittlepony.unicopia.spell;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.Predicates;
|
import com.minelittlepony.unicopia.Predicates;
|
||||||
import com.minelittlepony.unicopia.entity.IMagicals;
|
import com.minelittlepony.unicopia.entity.IMagicals;
|
||||||
|
@ -114,7 +114,11 @@ public class SpellFire extends AbstractSpell.RangedAreaSpell implements IUseActi
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SpellCastResult onUse(ItemStack stack, SpellAffinity affinity, EntityPlayer player, World world, @Nonnull Entity hitEntity) {
|
public SpellCastResult onUse(ItemStack stack, SpellAffinity affinity, EntityPlayer player, World world, @Nullable Entity hitEntity) {
|
||||||
|
if (hitEntity == null) {
|
||||||
|
return SpellCastResult.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
return applyEntitySingle(player, world, hitEntity) ? SpellCastResult.DEFAULT : SpellCastResult.NONE;
|
return applyEntitySingle(player, world, hitEntity) ? SpellCastResult.DEFAULT : SpellCastResult.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.minelittlepony.unicopia.spell;
|
package com.minelittlepony.unicopia.spell;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.init.UMaterials;
|
import com.minelittlepony.unicopia.init.UMaterials;
|
||||||
import com.minelittlepony.util.MagicalDamageSource;
|
import com.minelittlepony.util.MagicalDamageSource;
|
||||||
import com.minelittlepony.util.PosHelper;
|
import com.minelittlepony.util.PosHelper;
|
||||||
|
@ -96,7 +98,7 @@ public class SpellIce extends AbstractSpell.RangedAreaSpell implements IUseActio
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SpellCastResult onUse(ItemStack stack, SpellAffinity affinity, EntityPlayer player, World world, Entity hitEntity) {
|
public SpellCastResult onUse(ItemStack stack, SpellAffinity affinity, EntityPlayer player, World world, @Nullable Entity hitEntity) {
|
||||||
if (hitEntity != null && applyEntitySingle(player, hitEntity)) {
|
if (hitEntity != null && applyEntitySingle(player, hitEntity)) {
|
||||||
return SpellCastResult.DEFAULT;
|
return SpellCastResult.DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import java.util.Locale;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.entity.EntitySpell;
|
import com.minelittlepony.unicopia.entity.EntitySpell;
|
||||||
|
@ -127,7 +126,7 @@ public class SpellPortal extends AbstractSpell.RangedAreaSpell implements IUseAc
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SpellCastResult onUse(ItemStack stack, SpellAffinity affinity, EntityPlayer player, World world, @Nonnull Entity hitEntity) {
|
public SpellCastResult onUse(ItemStack stack, SpellAffinity affinity, EntityPlayer player, World world, @Nullable Entity hitEntity) {
|
||||||
return SpellCastResult.NONE;
|
return SpellCastResult.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
package com.minelittlepony.unicopia.tossable;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockDispenser;
|
||||||
|
import net.minecraft.dispenser.BehaviorDefaultDispenseItem;
|
||||||
|
import net.minecraft.dispenser.IBlockSource;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
|
|
||||||
|
class DispenserBehaviour extends BehaviorDefaultDispenseItem {
|
||||||
|
@Override
|
||||||
|
public ItemStack dispenseStack(IBlockSource source, ItemStack stack) {
|
||||||
|
ITossableItem tossable = (ITossableItem)stack.getItem();
|
||||||
|
|
||||||
|
if (tossable.canBeThrown(stack)) {
|
||||||
|
return shootStack(source, stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.dispenseStack(source, stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStack shootStack(IBlockSource source, ItemStack stack) {
|
||||||
|
return ((ITossableItem)stack.getItem()).toss(source.getWorld(),
|
||||||
|
BlockDispenser.getDispensePosition(source),
|
||||||
|
(EnumFacing)source.getBlockState().getValue(BlockDispenser.FACING),
|
||||||
|
stack, getProjectileInaccuracy(), getProjectileVelocity());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected float getProjectileInaccuracy() {
|
||||||
|
return 6.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected float getProjectileVelocity() {
|
||||||
|
return 1.1F;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.minelittlepony.unicopia.tossable;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
default SoundEvent getThrowSound(T stack) {
|
||||||
|
return SoundEvents.ENTITY_SNOWBALL_THROW;
|
||||||
|
}
|
||||||
|
|
||||||
|
default int getThrowDamage(T stack) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,45 +1,29 @@
|
||||||
package com.minelittlepony.unicopia.item;
|
package com.minelittlepony.unicopia.tossable;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.entity.EntityProjectile;
|
import com.minelittlepony.unicopia.entity.EntityProjectile;
|
||||||
|
|
||||||
import net.minecraft.block.BlockDispenser;
|
import net.minecraft.block.BlockDispenser;
|
||||||
import net.minecraft.block.state.IBlockState;
|
|
||||||
import net.minecraft.dispenser.BehaviorDefaultDispenseItem;
|
|
||||||
import net.minecraft.dispenser.IBehaviorDispenseItem;
|
import net.minecraft.dispenser.IBehaviorDispenseItem;
|
||||||
import net.minecraft.dispenser.IBlockSource;
|
|
||||||
import net.minecraft.dispenser.IPosition;
|
import net.minecraft.dispenser.IPosition;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.init.SoundEvents;
|
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.stats.StatList;
|
import net.minecraft.stats.StatList;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.SoundCategory;
|
import net.minecraft.util.SoundCategory;
|
||||||
import net.minecraft.util.SoundEvent;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public interface ITossable {
|
public interface ITossableItem extends ITossable<ItemStack> {
|
||||||
IBehaviorDispenseItem dispenserBehavior = new ITossable.DispenserBehaviour();
|
IBehaviorDispenseItem dispenserBehavior = new DispenserBehaviour();
|
||||||
|
|
||||||
boolean canBeThrown(ItemStack stack);
|
boolean canBeThrown(ItemStack stack);
|
||||||
|
|
||||||
void onImpact(World world, BlockPos pos, IBlockState state);
|
|
||||||
|
|
||||||
default Item setDispenseable() {
|
default Item setDispenseable() {
|
||||||
BlockDispenser.DISPENSE_BEHAVIOR_REGISTRY.putObject((Item)(Object)this, dispenserBehavior);
|
BlockDispenser.DISPENSE_BEHAVIOR_REGISTRY.putObject((Item)(Object)this, dispenserBehavior);
|
||||||
|
|
||||||
return (Item)(Object)this;
|
return (Item)(Object)this;
|
||||||
}
|
}
|
||||||
|
|
||||||
default SoundEvent getThrowSound(ItemStack stack) {
|
|
||||||
return SoundEvents.ENTITY_SNOWBALL_THROW;
|
|
||||||
}
|
|
||||||
|
|
||||||
default int getThrowDamage(ItemStack stack) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
default void toss(World world, ItemStack itemstack, EntityPlayer player) {
|
default void toss(World world, ItemStack itemstack, EntityPlayer player) {
|
||||||
if (!player.capabilities.isCreativeMode) {
|
if (!player.capabilities.isCreativeMode) {
|
||||||
itemstack.shrink(1);
|
itemstack.shrink(1);
|
||||||
|
@ -74,32 +58,4 @@ public interface ITossable {
|
||||||
|
|
||||||
return stack;
|
return stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
class DispenserBehaviour extends BehaviorDefaultDispenseItem {
|
|
||||||
@Override
|
|
||||||
public ItemStack dispenseStack(IBlockSource source, ItemStack stack) {
|
|
||||||
ITossable tossable = (ITossable)stack.getItem();
|
|
||||||
|
|
||||||
if (tossable.canBeThrown(stack)) {
|
|
||||||
return shootStack(source, stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.dispenseStack(source, stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemStack shootStack(IBlockSource source, ItemStack stack) {
|
|
||||||
return ((ITossable)stack.getItem()).toss(source.getWorld(),
|
|
||||||
BlockDispenser.getDispensePosition(source),
|
|
||||||
(EnumFacing)source.getBlockState().getValue(BlockDispenser.FACING),
|
|
||||||
stack, getProjectileInaccuracy(), getProjectileVelocity());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected float getProjectileInaccuracy() {
|
|
||||||
return 6.0F;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected float getProjectileVelocity() {
|
|
||||||
return 1.1F;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
Loading…
Reference in a new issue