Jump to content

[1.8.9] Changing the Values of Bow Damage


NovaViper

Recommended Posts

The damage dealt by arrows is calculated in

EntityArrow#onUpdate

, which uses values set in

ItemBow#onPlayerStoppedUsing

. You can override these methods in your own classes to do whatever you want.

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Link to comment
Share on other sites

Set the maximum use duration to 0, the use action to

NONE

and fire the arrows from

Item#onItemRightClick

instead of

Item#onItemUseFinish

.

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Link to comment
Share on other sites

You need to store the last use time (

World#getTotalWorldTime

) in the NBT and compare it against the current time in

Item#onItemRightClick

. If it's been at least

COOLDOWN

ticks, update the last use time and fire the arrow.

 

I have an example of a similar weapon here that fires snowballs at a fixed rate while right click is held.

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Link to comment
Share on other sites

What do I do with the other events in the arrow? So far I have the code like this but I'm not sure wthat to do with the rest

 

package novaviper.tetracraft.common.item;

import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.projectile.EntityArrow;
import net.minecraft.init.Items;
import net.minecraft.item.EnumAction;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagLong;
import net.minecraft.stats.StatList;
import net.minecraft.world.World;

/**
* Created by NovaViper on 2/12/2016.
* Class Purpose:
*/
public class ItemContinousBow extends ItemModBow{
int fireRate;

public ItemContinousBow(String unlocalizedName, CreativeTabs tab, String type, int damage, int fireRate) {
	super(unlocalizedName, tab, type, damage);
	this.fireRate = fireRate;
}

/**
 * Has it been at least FIRE_RATE ticks since the bow was last used?
 *
 * @param stack The launcher ItemStack
 * @param world The World to check the time against
 * @return True if the ItemStack was last used at least FIRE_RATE ticks ago or if it has never been used
 */
private boolean isOffCooldown(ItemStack stack, World world) {
	return !stack.hasTagCompound() || (world.getTotalWorldTime() - stack.getTagCompound().getLong("lastUsage")) >= fireRate;
}

/**
 * Set the bow's last use time to the specified time.
 *
 * @param stack The bow ItemStack
 * @param time  The time
 */
private void setLastUsage(ItemStack stack, long time) {
	stack.setTagInfo("lastUsage", new NBTTagLong(time));
}

/**
 * Does the player need ammunition to fire the bows?
 *
 * @param stack  The bow ItemStack
 * @param player The player to check
 * @return True if the player is not in creative mode and the launcher doesn't have the Infinity enchantment
 */
private boolean playerNeedsAmmo(ItemStack stack, EntityPlayer player) {
	return !player.capabilities.isCreativeMode && EnchantmentHelper.getEnchantmentLevel(Enchantment.infinity.effectId, stack) == 0;
}

/**
 * How long it takes to use or consume an item
 */
@Override
public int getMaxItemUseDuration(ItemStack stack)
{
	return 20;
}

/**
 * returns the action that specifies what animation to play when the items is being used
 */
@Override
public EnumAction getItemUseAction(ItemStack stack)
{
	return EnumAction.BOW;
}

/**
 * Called whenever this item is equipped and the right mouse button is pressed. Args: itemStack, world, entityPlayer
 */
@Override
public ItemStack onItemRightClick(ItemStack stack, World worldIn, EntityPlayer playerIn)
{

	boolean cooldownOfff = isOffCooldown(stack, worldIn);
	boolean needsAmmo = playerNeedsAmmo(stack, playerIn);
	{

		if (cooldownOfff && (!needsAmmo || playerIn.inventory.consumeInventoryItem(Items.arrow))) {
			setLastUsage(stack, worldIn.getTotalWorldTime());
			net.minecraftforge.event.entity.player.ArrowLooseEvent event = new net.minecraftforge.event.entity.player.ArrowLooseEvent(playerIn, stack, i);
			if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) return null;
			i = event.charge;
			float f = (float) i / 20.0F;
			f = (f * f + f * 2.0F) / 3.0F;

			if ((double) f < 0.1D) {
				return null;
			}

			if (f > 1.0F) {
				f = 1.0F;
			}

			EntityArrow entityarrow = new EntityArrow(worldIn, playerIn, f * 2.0F);

			if (f == 1.0F) {
				entityarrow.setIsCritical(true);
			}

			int j = EnchantmentHelper.getEnchantmentLevel(Enchantment.power.effectId, stack);

			if (j > 0) {
				entityarrow.setDamage(entityarrow.getDamage() + (double) j * 0.5D + 0.5D);
			}

			int k = EnchantmentHelper.getEnchantmentLevel(Enchantment.punch.effectId, stack);

			if (k > 0) {
				entityarrow.setKnockbackStrength(k);
			}

			if (EnchantmentHelper.getEnchantmentLevel(Enchantment.flame.effectId, stack) > 0) {
				entityarrow.setFire(100);
			}

			stack.damageItem(1, playerIn);
			worldIn.playSoundAtEntity(playerIn, "random.bow", 1.0F, 1.0F / (itemRand.nextFloat() * 0.4F + 1.2F) + f * 0.5F);

			if (flag) {
				entityarrow.canBePickedUp = 2;
			} else {
				playerIn.inventory.consumeInventoryItem(Items.arrow);
			}

			playerIn.triggerAchievement(StatList.objectUseStats[item.getIdFromItem(this)]);

			if (!worldIn.isRemote) {
				worldIn.spawnEntityInWorld(entityarrow);
			}
		}
	}
	return stack;
}
}

Main Developer and Owner of Zero Quest

Visit the Wiki for more information

If I helped anyone, please give me a applaud and a thank you!

Link to comment
Share on other sites

You've got a block (pair of braces) surrounding the

if

statement, which isn't required.

 

You don't need to consume an arrow in the body of the

if

statement, the

InventoryPlayer#consumeInventoryItem

call in the conditional already does that.

 

There's no point in setting the maximum use duration (

Item#getMaxItemUseDuration

) and use action (

Item#getItemUseAction

) if you never set the item in use (

EntityPlayer#setItemInUse

).

 

You should rename the variables in

onItemRightClick

with meaningful names that describe their purpose, e.g.

charge

instead if

i

(because that holds the bow's charge).

 

You never declare the variable

i

.

 

What is it that want to know?

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Link to comment
Share on other sites

Alright.. I got everything up, now I need help modding the textures

 

package novaviper.tetracraft.common.item;

import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.projectile.EntityArrow;
import net.minecraft.init.Items;
import net.minecraft.item.EnumAction;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagLong;
import net.minecraft.stats.StatList;
import net.minecraft.world.World;
import novaviper.tetracraft.common.lib.ModelJsonReference;

/**
* Created by NovaViper on 2/12/2016.
* Class Purpose:
*/
public class ItemContinousBow extends ItemModBow{
int fireRate;

public ItemContinousBow(String unlocalizedName, CreativeTabs tab, String type, int damage, int fireRate) {
	super(unlocalizedName, tab, type, damage);
	this.fireRate = fireRate;
}

/**
 * Has it been at least FIRE_RATE ticks since thebowr was last used?
 *
 * @param stack The launcher ItemStack
 * @param world The World to check the time against
 * @return True if the ItemStack was last used at least FIRE_RATE ticks ago or if it has never been used
 */
private boolean isOffCooldown(ItemStack stack, World world) {
	return !stack.hasTagCompound() || (world.getTotalWorldTime() - stack.getTagCompound().getLong("lastUsage")) >=fireRate;
}

/**
 * Set thbower's last use time to the specified time.
 *
 * @param stack Thbower ItemStack
 * @param time  The time
 */
private void setLastUsage(ItemStack stack, long time) {
	stack.setTagInfo("lastUsage", new NBTTagLong(time));
}

/**
 * Does the player need ammunition to fire tbowsher?
 *
 * @param stack  Tbowher ItemStack
 * @param player The player to check
 * @return True if the player is not in creative mode and the launcher doesn't have the Infinity enchantment
 */
private boolean playerNeedsAmmo(ItemStack stack, EntityPlayer player) {
	return !player.capabilities.isCreativeMode && EnchantmentHelper.getEnchantmentLevel(Enchantment.infinity.effectId, stack) == 0;
}

/**
 * How long it takes to use or consume an item
 */
@Override
public int getMaxItemUseDuration(ItemStack stack){return 0;}

/**
 * returns the action that specifies what animation to play when the items is being used
 */
@Override
public EnumAction getItemUseAction(ItemStack stack)
{
	return EnumAction.BOW;
}

@Override
public ModelResourceLocation getModel(ItemStack stack, EntityPlayer player, int useRemaining) {
	ModelResourceLocation modelresourcelocation = new ModelResourceLocation(ModelJsonReference.getBowStandbyModel(bowType), "inventory");

	//System.out.println(player.getItemInUse() +":" + useRemaining); //USE FOR DEBUGGING ONLY

	if (stack.getItem() == this && player.getItemInUse() != null) {
		if (useRemaining >= 71987) {
			modelresourcelocation = new ModelResourceLocation(ModelJsonReference.getBowPullingModel(bowType, "0"), "inventory");
		}
		else if (useRemaining > 71980) {
			modelresourcelocation = new ModelResourceLocation(ModelJsonReference.getBowPullingModel(bowType, "1"), "inventory");
		}
		else if (useRemaining <= 71976 || useRemaining >= 71976) {
			modelresourcelocation = new ModelResourceLocation(ModelJsonReference.getBowPullingModel(bowType, "2"), "inventory");
		}
	}
	return modelresourcelocation;
}

/**
 * Called whenever this item is equipped and the right mouse button is pressed. Args: itemStack, world, entityPlayer
 */
@Override
public ItemStack onItemRightClick(ItemStack itemStackIn, World worldIn, EntityPlayer playerIn)
{

	boolean offCooldown = isOffCooldown(itemStackIn, worldIn);
	boolean needsAmmo = playerNeedsAmmo(itemStackIn, playerIn);
	{

		if (offCooldown && (!needsAmmo || playerIn.inventory.consumeInventoryItem(Items.arrow))) {
			setLastUsage(itemStackIn, worldIn.getTotalWorldTime());
			net.minecraftforge.event.entity.player.ArrowLooseEvent event = new net.minecraftforge.event.entity.player.ArrowLooseEvent(playerIn, itemStackIn, fireRate);
			if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) return null;
			int charge = event.charge + 15;
			float charge2 = (float) charge / 20.0F;
			charge2 = (charge2 * charge2 + charge2 * 2.0F) / 3.0F;

			if ((double) charge2 < 0.1D) {
				return null;
			}

			if (charge2 > 1.0F) {
				charge2 = 1.0F;
			}

			EntityArrow entityarrow = new EntityArrow(worldIn, playerIn, charge2 * 2.0F);
			int j = EnchantmentHelper.getEnchantmentLevel(Enchantment.power.effectId, itemStackIn);
			entityarrow.setIsCritical(true);

			if (j > 0) {
				entityarrow.setDamage(entityarrow.getDamage() + (double) j * 0.5D + 0.5D);
			}

			int k = EnchantmentHelper.getEnchantmentLevel(Enchantment.punch.effectId, itemStackIn);

			if (k > 0) {
				entityarrow.setKnockbackStrength(k);
			}

			if (EnchantmentHelper.getEnchantmentLevel(Enchantment.flame.effectId, itemStackIn) > 0) {
				entityarrow.setFire(100);
			}

			itemStackIn.damageItem(1, playerIn);
			worldIn.playSoundAtEntity(playerIn, "random.bow", 1.0F, 1.0F / (itemRand.nextFloat() * 0.4F + 1.2F) + charge2 * 0.5F);

			playerIn.triggerAchievement(StatList.objectUseStats[item.getIdFromItem(this)]);

			if (!worldIn.isRemote) {
				worldIn.spawnEntityInWorld(entityarrow);
			}
		}
	}
	return itemStackIn;
}
}

Main Developer and Owner of Zero Quest

Visit the Wiki for more information

If I helped anyone, please give me a applaud and a thank you!

Link to comment
Share on other sites

Just register a model for the bow like you would any other item (

ModelBakery.registerItemVariants

and

ModelLoader.setCustomModelResourceLocation

or

ModelLoader.setCustomMeshDefinition

). Since it's never set in use, the pulling models will never be used.

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Link to comment
Share on other sites

If you set the item in use from

Item#onItemRightClick

, the pulling models returned by

Item#getModel

will be used (you can adjust the timings for each model in that method). Just make sure you override

Item#onItemUseStopped

to do nothing.

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Link to comment
Share on other sites

Sorry for taking a while to respond, been busy and I put the method in but still having texture issues

 

package novaviper.tetracraft.common.item;

import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.projectile.EntityArrow;
import net.minecraft.init.Items;
import net.minecraft.item.EnumAction;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagLong;
import net.minecraft.stats.StatList;
import net.minecraft.world.World;
import novaviper.tetracraft.common.lib.ModelJsonReference;

/**
* Created by NovaViper on 2/12/2016.
* Class Purpose:
*/
public class ItemContinousBow extends ItemModBow{
int fireRate;
//int using;

public ItemContinousBow(String unlocalizedName, CreativeTabs tab, String type, int damage, int fireRate) {
	super(unlocalizedName, tab, type, damage);
	this.fireRate = fireRate;
}

/**
 * Has it been at least FIRE_RATE ticks since thebowr was last used?
 *
 * @param stack The launcher ItemStack
 * @param world The World to check the time against
 * @return True if the ItemStack was last used at least FIRE_RATE ticks ago or if it has never been used
 */
private boolean isOffCooldown(ItemStack stack, World world) {
	return !stack.hasTagCompound() || (world.getTotalWorldTime() - stack.getTagCompound().getLong("lastUsage")) >=fireRate;
}

/**
 * Set thbower's last use time to the specified time.
 *
 * @param stack Thbower ItemStack
 * @param time  The time
 */
private void setLastUsage(ItemStack stack, long time) {
	stack.setTagInfo("lastUsage", new NBTTagLong(time));
}

/**
 * Does the player need ammunition to fire tbowsher?
 *
 * @param stack  Tbowher ItemStack
 * @param player The player to check
 * @return True if the player is not in creative mode and the launcher doesn't have the Infinity enchantment
 */
private boolean playerNeedsAmmo(ItemStack stack, EntityPlayer player) {
	return !player.capabilities.isCreativeMode && EnchantmentHelper.getEnchantmentLevel(Enchantment.infinity.effectId, stack) == 0;
}

/**
 * How long it takes to use or consume an item
 */
@Override
public int getMaxItemUseDuration(ItemStack stack){return 10;}

/**
 * returns the action that specifies what animation to play when the items is being used
 */
@Override
public EnumAction getItemUseAction(ItemStack stack)
{
	return EnumAction.BOW;
}

@Override
public ModelResourceLocation getModel(ItemStack stack, EntityPlayer player, int useRemaining) {
	ModelResourceLocation modelresourcelocation = new ModelResourceLocation(ModelJsonReference.getBowStandbyModel(bowType), "inventory");

	//System.out.println(player.getItemInUse() +":" + useRemaining); //USE FOR DEBUGGING ONLY

	if (stack.getItem() == this && isOffCooldown(stack, player.getEntityWorld() )) {
		if (useRemaining >= 9) {
			modelresourcelocation = new ModelResourceLocation(ModelJsonReference.getBowPullingModel(bowType, "0"), "inventory");
		}
		else if (useRemaining > 6) {
			modelresourcelocation = new ModelResourceLocation(ModelJsonReference.getBowPullingModel(bowType, "1"), "inventory");
		}
		else if (useRemaining <= 4 || useRemaining >= 3) {
			modelresourcelocation = new ModelResourceLocation(ModelJsonReference.getBowPullingModel(bowType, "2"), "inventory");
		}
	}
	return modelresourcelocation;
}

/**
 * Called whenever this item is equipped and the right mouse button is pressed. Args: itemStack, world, entityPlayer
 */
@Override
public ItemStack onItemRightClick(ItemStack itemStackIn, World worldIn, EntityPlayer playerIn)
{

	boolean offCooldown = isOffCooldown(itemStackIn, worldIn);
	boolean needsAmmo = playerNeedsAmmo(itemStackIn, playerIn);
	{

		if (offCooldown && (!needsAmmo || playerIn.inventory.consumeInventoryItem(Items.arrow))) {
			setLastUsage(itemStackIn, worldIn.getTotalWorldTime());
			playerIn.setItemInUse(itemStackIn, this.getMaxItemUseDuration(itemStackIn));
			net.minecraftforge.event.entity.player.ArrowLooseEvent event = new net.minecraftforge.event.entity.player.ArrowLooseEvent(playerIn, itemStackIn, fireRate);
			if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) return null;
			int charge = event.charge + 15;
			float charge2 = (float) charge / 20.0F;
			charge2 = (charge2 * charge2 + charge2 * 2.0F) / 3.0F;

			if ((double) charge2 < 0.1D) {
				return null;
			}

			if (charge2 > 1.0F) {
				charge2 = 1.0F;
			}

			EntityArrow entityarrow = new EntityArrow(worldIn, playerIn, charge2 * 2.0F);
			int j = EnchantmentHelper.getEnchantmentLevel(Enchantment.power.effectId, itemStackIn);
			entityarrow.setIsCritical(true);

			if (j > 0) {
				entityarrow.setDamage(entityarrow.getDamage() + (double) j * 0.5D + 0.5D);
			}

			int k = EnchantmentHelper.getEnchantmentLevel(Enchantment.punch.effectId, itemStackIn);

			if (k > 0) {
				entityarrow.setKnockbackStrength(k);
			}

			if (EnchantmentHelper.getEnchantmentLevel(Enchantment.flame.effectId, itemStackIn) > 0) {
				entityarrow.setFire(100);
			}

			itemStackIn.damageItem(1, playerIn);
			worldIn.playSoundAtEntity(playerIn, "random.bow", 1.0F, 1.0F / (itemRand.nextFloat() * 0.4F + 1.2F) + charge2 * 0.5F);

			playerIn.triggerAchievement(StatList.objectUseStats[item.getIdFromItem(this)]);

			if (!worldIn.isRemote) {
				worldIn.spawnEntityInWorld(entityarrow);
			}
		}
	}
	return itemStackIn;
}
}

Main Developer and Owner of Zero Quest

Visit the Wiki for more information

If I helped anyone, please give me a applaud and a thank you!

Link to comment
Share on other sites

If you want to fire arrows continuously but still have the player draw back the bow, it may be better to fire them from

Item#onItemUseFinish

and

Item#onPlayerStoppedUsing

instead of from

Item#onItemRightClick

with a cooldown.

 

I've written an example of this here (parent class).

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Link to comment
Share on other sites

Just to jump in real quick.

 

You've got a block (pair of braces) surrounding the

if

statement, which isn't required.

 

While not required, there are totally legitimate reasons to do untyped code blocks.

I was working on something just the other week where I wanted to tab stuff in just to reduce the mental gymnastics necessary to understand what it was doing, and the IDE kept untabbing it, so I said "fuck it, code block."

 

Incidentally, code blocks also add another level of local scope.

 

int v = 1;
{
    int v = 2;
    System.out.println("v is " + v); //prints 2
}

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

If you want to fire arrows continuously but still have the player draw back the bow, it may be better to fire them from

Item#onItemUseFinish

and

Item#onPlayerStoppedUsing

instead of from

Item#onItemRightClick

with a cooldown.

 

I've written an example of this here (parent class).

 

I tried out the methods you made and they work perfectly (I did put your name next to them so I won't steal the credit from you)

Main Developer and Owner of Zero Quest

Visit the Wiki for more information

If I helped anyone, please give me a applaud and a thank you!

Link to comment
Share on other sites

  • 2 weeks later...

Oh, I did forgot to ask one question (sorry if this counts as bumping, I just want it to stay in the same thread in case someone comes across this) I did finally manage to figure out how to set the damage of the bows. Now my question is how do I know the number im putting in is the acutal damage that an entity takes?

Main Developer and Owner of Zero Quest

Visit the Wiki for more information

If I helped anyone, please give me a applaud and a thank you!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.