aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.World/BowItem.cpp
blob: 949b71e73dfbb542327558259097d5d14c2fb159 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include "stdafx.h"
#include "net.minecraft.world.level.h"
#include "net.minecraft.world.entity.player.h"
#include "net.minecraft.world.entity.projectile.h"
#include "net.minecraft.world.entity.item.h"
#include "net.minecraft.world.item.enchantment.h"
#include "net.minecraft.world.h"
#include "BowItem.h"
#include "SoundTypes.h"

const wstring BowItem::TEXTURE_PULL[] = {L"bow_pull_0", L"bow_pull_1", L"bow_pull_2"};

BowItem::BowItem(int id) : Item( id )
{
	maxStackSize = 1;
	setMaxDamage(384);

	icons = NULL;
}

void BowItem::releaseUsing(shared_ptr<ItemInstance> itemInstance, Level *level, shared_ptr<Player> player, int durationLeft)
{
	bool infiniteArrows = player->abilities.instabuild || EnchantmentHelper::getEnchantmentLevel(Enchantment::arrowInfinite->id, itemInstance) > 0;

	if (infiniteArrows || player->inventory->hasResource(Item::arrow_Id))
	{
		int timeHeld = getUseDuration(itemInstance) - durationLeft;
		float pow = timeHeld / (float) MAX_DRAW_DURATION;
		pow = ((pow * pow) + pow * 2) / 3;
		if (pow < 0.1) return;
		if (pow > 1) pow = 1;

		shared_ptr<Arrow> arrow = shared_ptr<Arrow>( new Arrow(level, player, pow * 2.0f) );
		if (pow == 1) arrow->setCritArrow(true);
		int damageBonus = EnchantmentHelper::getEnchantmentLevel(Enchantment::arrowBonus->id, itemInstance);
		if (damageBonus > 0)
		{
			arrow->setBaseDamage(arrow->getBaseDamage() + (double) damageBonus * .5 + .5);
		}
		int knockbackBonus = EnchantmentHelper::getEnchantmentLevel(Enchantment::arrowKnockback->id, itemInstance);
		if (knockbackBonus > 0)
		{
			arrow->setKnockback(knockbackBonus);
		}
		if (EnchantmentHelper::getEnchantmentLevel(Enchantment::arrowFire->id, itemInstance) > 0)
		{
			arrow->setOnFire(100);
		}
		itemInstance->hurtAndBreak(1, player);

		level->playEntitySound(player, eSoundType_RANDOM_BOW, 1.0f, 1 / (random->nextFloat() * 0.4f + 1.2f) + pow * 0.5f);

		if (infiniteArrows)
		{
			arrow->pickup = Arrow::PICKUP_CREATIVE_ONLY;
		}
		else
		{
			player->inventory->removeResource(Item::arrow_Id);
		}
		if (!level->isClientSide) level->addEntity(arrow);
	}
}

shared_ptr<ItemInstance> BowItem::useTimeDepleted(shared_ptr<ItemInstance> instance, Level *level, shared_ptr<Player> player)
{
	return instance;
}

int BowItem::getUseDuration(shared_ptr<ItemInstance> itemInstance)
{
	return 20 * 60 * 60;
}

UseAnim BowItem::getUseAnimation(shared_ptr<ItemInstance> itemInstance)
{
	return UseAnim_bow;
}

shared_ptr<ItemInstance> BowItem::use(shared_ptr<ItemInstance> instance, Level *level, shared_ptr<Player> player)
{
	if (player->abilities.instabuild || player->inventory->hasResource(Item::arrow_Id))
	{
		player->startUsingItem(instance, getUseDuration(instance));
	}
	return instance;
}

int BowItem::getEnchantmentValue()
{
	return 1;
}

void BowItem::registerIcons(IconRegister *iconRegister)
{
	Item::registerIcons(iconRegister);

	icons = new Icon *[BOW_ICONS_COUNT];

	for (int i = 0; i < BOW_ICONS_COUNT; i++)
	{
		icons[i] = iconRegister->registerIcon(TEXTURE_PULL[i]);
	}
}

Icon *BowItem::getDrawnIcon(int amount)
{
	return icons[amount];
}