diff --git a/src/main/java/tconstruct/library/util/BehaviorProjectileBaseDispense.java b/src/main/java/tconstruct/library/util/BehaviorProjectileBaseDispense.java new file mode 100644 index 00000000000..784849cbe26 --- /dev/null +++ b/src/main/java/tconstruct/library/util/BehaviorProjectileBaseDispense.java @@ -0,0 +1,74 @@ +package tconstruct.library.util; + +import net.minecraft.block.BlockDispenser; +import net.minecraft.dispenser.BehaviorDefaultDispenseItem; +import net.minecraft.dispenser.IBlockSource; +import net.minecraft.dispenser.IPosition; +import net.minecraft.entity.Entity; +import net.minecraft.entity.IProjectile; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; +import net.minecraft.world.World; +import tconstruct.library.entity.ProjectileBase; +import tconstruct.library.weaponry.IAmmo; + +public abstract class BehaviorProjectileBaseDispense extends BehaviorDefaultDispenseItem { + /** + * Dispense the specified stack, play the dispense sound and spawn particles. + */ + @Override + public ItemStack dispenseStack(IBlockSource blockSource, ItemStack stack) + { + World world = blockSource.getWorld(); + IPosition iposition = BlockDispenser.func_149939_a(blockSource); + EnumFacing enumfacing = BlockDispenser.func_149937_b(blockSource.getBlockMetadata()); + + ItemStack reference; + + if(stack.getItem() instanceof IAmmo) + { + IAmmo ammo = (IAmmo) stack.getItem(); + // needs ammo to shoot + if(ammo.getAmmoCount(stack) <= 0) + return stack; + ammo.consumeAmmo(1, stack); + reference = stack.copy(); + ((IAmmo)reference.getItem()).setAmmo(1, reference); + } + else + reference = stack.splitStack(1); + + ProjectileBase projectile = this.getProjectileEntity(world, iposition, reference); + projectile.setThrowableHeading((double)enumfacing.getFrontOffsetX(), (double)((float)enumfacing.getFrontOffsetY() + ballistic()), (double)enumfacing.getFrontOffsetZ(), this.accuraccy(), this.speed()); + projectile.returnStack = reference; + projectile.canBePickedUp = 1; + world.spawnEntityInWorld(projectile); + + return stack; + } + + /** + * Play the dispense sound from the specified block. + */ + protected void playDispenseSound(IBlockSource p_82485_1_) + { + p_82485_1_.getWorld().playAuxSFX(1002, p_82485_1_.getXInt(), p_82485_1_.getYInt(), p_82485_1_.getZInt(), 0); + } + + /** + * Return the projectile entity spawned by this dispense behavior. + */ + protected abstract ProjectileBase getProjectileEntity(World world, IPosition position, ItemStack stack); + + protected float speed() + { + return 6.0F; + } + + protected float accuraccy() + { + return 1.1F; + } + + protected float ballistic() { return 0.1f; } +} diff --git a/src/main/java/tconstruct/library/weaponry/AmmoItem.java b/src/main/java/tconstruct/library/weaponry/AmmoItem.java index 196e814ca4b..aeb80b94072 100644 --- a/src/main/java/tconstruct/library/weaponry/AmmoItem.java +++ b/src/main/java/tconstruct/library/weaponry/AmmoItem.java @@ -60,6 +60,14 @@ public int consumeAmmo(int toUse, ItemStack stack) { return toUse - (oldCount - newCount); } + @Override + public void setAmmo(int count, ItemStack stack) { + if(!stack.hasTagCompound()) return; + + NBTTagCompound tags = stack.getTagCompound().getCompoundTag("InfiTool"); + tags.setInteger("Ammo", count); + } + public float getAmmoModifier() { return 0.1f; } public boolean pickupAmmo(ItemStack stack, ItemStack candidate, EntityPlayer player) diff --git a/src/main/java/tconstruct/library/weaponry/AmmoWeapon.java b/src/main/java/tconstruct/library/weaponry/AmmoWeapon.java index fac9cc2804e..9209d55e6b2 100644 --- a/src/main/java/tconstruct/library/weaponry/AmmoWeapon.java +++ b/src/main/java/tconstruct/library/weaponry/AmmoWeapon.java @@ -105,7 +105,8 @@ protected void launchProjectile(ItemStack stack, World world, EntityPlayer playe if(!world.isRemote) { ItemStack reference = stack.copy(); reference.stackSize = 1; - reference.getTagCompound().getCompoundTag("InfiTool").setInteger("Ammo", 1); + ((IAmmo)reference.getItem()).setAmmo(1, reference); + Entity projectile = createProjectile(reference, world, player, getAccuracy(stack, time), time); world.spawnEntityInWorld(projectile); } diff --git a/src/main/java/tconstruct/library/weaponry/IAmmo.java b/src/main/java/tconstruct/library/weaponry/IAmmo.java index 5ed123e8b5b..8c70a9c1885 100644 --- a/src/main/java/tconstruct/library/weaponry/IAmmo.java +++ b/src/main/java/tconstruct/library/weaponry/IAmmo.java @@ -35,4 +35,11 @@ public interface IAmmo { * @return The amount of ammo that couldn't be removed. If you try to remove 5, but only 3 are left, it'll return 2. */ int consumeAmmo(int count, ItemStack stack); + + /** + * Sets the Ammo amount to that absolute value. Behaviour for values below 0 or above the max ammo is undefined. + * @param count How much + * @param stack The itemstack to set the ammo for. Has to have proper NBT. + */ + void setAmmo(int count, ItemStack stack); } diff --git a/src/main/java/tconstruct/weaponry/TinkerWeaponry.java b/src/main/java/tconstruct/weaponry/TinkerWeaponry.java index bf9ccfb24e9..37b82c296c6 100644 --- a/src/main/java/tconstruct/weaponry/TinkerWeaponry.java +++ b/src/main/java/tconstruct/weaponry/TinkerWeaponry.java @@ -9,19 +9,24 @@ import cpw.mods.fml.common.registry.GameRegistry; import mantle.pulsar.pulse.Handler; import mantle.pulsar.pulse.Pulse; +import net.minecraft.block.BlockDispenser; +import net.minecraft.dispenser.IPosition; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; import tconstruct.TConstruct; import tconstruct.library.TConstructRegistry; import tconstruct.library.crafting.*; +import tconstruct.library.entity.ProjectileBase; import tconstruct.library.tools.DynamicToolPart; import tconstruct.library.tools.FletchlingLeafMaterial; +import tconstruct.library.util.BehaviorProjectileBaseDispense; import tconstruct.library.util.IPattern; import tconstruct.library.util.IToolPart; import tconstruct.modifiers.tools.ModAttack; @@ -36,6 +41,7 @@ import tconstruct.weaponry.ammo.ArrowAmmo; import tconstruct.weaponry.ammo.BoltAmmo; import tconstruct.library.tools.DualMaterialToolPart; +import tconstruct.weaponry.entity.*; import tconstruct.weaponry.items.GlassArrows; import tconstruct.weaponry.items.WeaponryPattern; import tconstruct.library.weaponry.AmmoItem; @@ -114,6 +120,8 @@ public void init(FMLInitializationEvent event) ModifyBuilder.registerModifier(TinkerTools.modAttack); TConstructRegistry.registerActiveToolMod(new WeaponryActiveToolMod()); + + registerDispenserProjectiles(); } @Handler @@ -389,4 +397,53 @@ private void setupCreativeTab() TConstructRegistry.weaponryTab.init(tool); } + + private void registerDispenserProjectiles() { + // shuriken + BlockDispenser.dispenseBehaviorRegistry.putObject(shuriken, new BehaviorProjectileBaseDispense() { + + @Override + protected ProjectileBase getProjectileEntity(World world, IPosition position, ItemStack stack) { + return new ShurikenEntity(world, position.getX(), position.getY(), position.getZ()); + } + + @Override + protected float ballistic() { + // shurikens are shot out straight + return 0f; + } + }); + // throwing knifes + BlockDispenser.dispenseBehaviorRegistry.putObject(throwingknife, new BehaviorProjectileBaseDispense() { + + @Override + protected ProjectileBase getProjectileEntity(World world, IPosition position, ItemStack stack) { + return new ThrowingKnifeEntity(world, position.getX(), position.getY(), position.getZ()); + } + }); + // Javelin + BlockDispenser.dispenseBehaviorRegistry.putObject(javelin, new BehaviorProjectileBaseDispense() { + + @Override + protected ProjectileBase getProjectileEntity(World world, IPosition position, ItemStack stack) { + return new JavelinEntity(world, position.getX(), position.getY(), position.getZ()); + } + }); + + // arrows + BlockDispenser.dispenseBehaviorRegistry.putObject(arrowAmmo, new BehaviorProjectileBaseDispense() { + @Override + protected ProjectileBase getProjectileEntity(World world, IPosition position, ItemStack stack) { + return new ArrowEntity(world, position.getX(), position.getY(), position.getZ()); + } + }); + + // bolts + BlockDispenser.dispenseBehaviorRegistry.putObject(boltAmmo, new BehaviorProjectileBaseDispense() { + @Override + protected ProjectileBase getProjectileEntity(World world, IPosition position, ItemStack stack) { + return new BoltEntity(world, position.getX(), position.getY(), position.getZ()); + } + }); + } }