-
Notifications
You must be signed in to change notification settings - Fork 73
Expand file tree
/
Copy pathItemComponentsTrait.php
More file actions
156 lines (136 loc) · 5.92 KB
/
ItemComponentsTrait.php
File metadata and controls
156 lines (136 loc) · 5.92 KB
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
<?php
declare(strict_types=1);
namespace customiesdevs\customies\item;
use customiesdevs\customies\item\component\AllowOffHandComponent;
use customiesdevs\customies\item\component\CanDestroyInCreativeComponent;
use customiesdevs\customies\item\component\CooldownComponent;
use customiesdevs\customies\item\component\CreativeCategoryComponent;
use customiesdevs\customies\item\component\CreativeGroupComponent;
use customiesdevs\customies\item\component\DamageComponent;
use customiesdevs\customies\item\component\DisplayNameComponent;
use customiesdevs\customies\item\component\DurabilityComponent;
use customiesdevs\customies\item\component\FoodComponent;
use customiesdevs\customies\item\component\FuelComponent;
use customiesdevs\customies\item\component\HandEquippedComponent;
use customiesdevs\customies\item\component\IconComponent;
use customiesdevs\customies\item\component\ItemComponent;
use customiesdevs\customies\item\component\MaxStackSizeComponent;
use customiesdevs\customies\item\component\ProjectileComponent;
use customiesdevs\customies\item\component\ThrowableComponent;
use customiesdevs\customies\item\component\UnbreakableComponent;
use customiesdevs\customies\item\component\UseAnimationComponent;
use customiesdevs\customies\item\component\UseDurationComponent;
use customiesdevs\customies\item\component\WearableComponent;
use customiesdevs\customies\util\NBT;
use pocketmine\entity\Consumable;
use pocketmine\inventory\ArmorInventory;
use pocketmine\item\Armor;
use pocketmine\item\Durable;
use pocketmine\item\Food;
use pocketmine\item\ProjectileItem;
use pocketmine\item\Sword;
use pocketmine\item\Tool;
use pocketmine\nbt\tag\CompoundTag;
use RuntimeException;
trait ItemComponentsTrait {
/** @var ItemComponent[] */
private array $components;
public function addComponent(ItemComponent $component): void {
$this->components[$component->getName()] = $component;
}
public function hasComponent(string $name): bool {
return isset($this->components[$name]);
}
public function getComponents(): CompoundTag {
$components = CompoundTag::create();
$properties = CompoundTag::create();
foreach($this->components as $component){
$tag = NBT::getTagType($component->getValue());
if($tag === null) {
throw new RuntimeException("Failed to get tag type for component " . $component->getName());
}
if($component->isProperty()) {
$properties->setTag($component->getName(), $tag);
continue;
}
$components->setTag($component->getName(), $tag);
}
$components->setTag("item_properties", $properties);
return CompoundTag::create()
->setTag("components", $components);
}
/**
* Initializes the item with default components that are required for the item to function correctly.
*/
protected function initComponent(string $texture, ?CreativeInventoryInfo $creativeInfo = null): void {
$creativeInfo ??= CreativeInventoryInfo::DEFAULT();
$this->addComponent(new CreativeCategoryComponent($creativeInfo));
$this->addComponent(new CreativeGroupComponent($creativeInfo));
$this->addComponent(new CanDestroyInCreativeComponent());
$this->addComponent(new IconComponent($texture));
$this->addComponent(new MaxStackSizeComponent($this->getMaxStackSize()));
if($this instanceof Armor) {
$slot = match ($this->getArmorSlot()) {
ArmorInventory::SLOT_HEAD => WearableComponent::SLOT_ARMOR_HEAD,
ArmorInventory::SLOT_CHEST => WearableComponent::SLOT_ARMOR_CHEST,
ArmorInventory::SLOT_LEGS => WearableComponent::SLOT_ARMOR_LEGS,
ArmorInventory::SLOT_FEET => WearableComponent::SLOT_ARMOR_FEET,
default => WearableComponent::SLOT_ARMOR
};
$this->addComponent(new WearableComponent($slot, $this->getDefensePoints()));
}
if($this instanceof Consumable) {
if(($food = $this instanceof Food)) {
$this->addComponent(new FoodComponent(!$this->requiresHunger()));
}
$this->addComponent(new UseAnimationComponent($food ? UseAnimationComponent::ANIMATION_EAT : UseAnimationComponent::ANIMATION_DRINK));
$this->setUseDuration(20);
}
if($this instanceof Durable) {
$this->addComponent(new DurabilityComponent($this->getMaxDurability()));
}
if($this instanceof ProjectileItem) {
$this->addComponent(new ProjectileComponent(1.25, "projectile"));
$this->addComponent(new ThrowableComponent(true));
}
if($this->getName() !== "Unknown") {
$this->addComponent(new DisplayNameComponent($this->getName()));
}
if($this->getFuelTime() > 0) {
$this->addComponent(new FuelComponent($this->getFuelTime()));
}
if($this->getAttackPoints() > 0) {
$this->addComponent(new DamageComponent($this->getAttackPoints() - 1));
}
if($this instanceof Tool) {
$this->addComponent(new HandEquippedComponent());
if ($this instanceof Sword) {
$this->addComponent(new CanDestroyInCreativeComponent(false));
}
}
if($this instanceof Durable && $this->isUnbreakable()){
$this->addComponent(new UnbreakableComponent(true));
}
}
/**
* Change if you want to allow the item to be placed in a player's off-hand or not. This is set to false by default,
* so it only needs to be set if you want to allow it.
*/
protected function allowOffHand(bool $offHand = true): void {
$this->addComponent(new AllowOffHandComponent($offHand));
}
/**
* Set the number of seconds the item should be on cooldown for after being used. By default, the cooldown category
* will be the name of the item, but to share the cooldown across multiple items you can provide a shared category.
*/
protected function setUseCooldown(float $duration, string $category = ""): void {
$this->addComponent(new CooldownComponent($category !== "" ? $category : $this->getName(), $duration));
}
/**
* Set the number of ticks the use animation should play for before consuming the item. There are 20 ticks in a
* second, so providing the number 20 will create a duration of 1 second.
*/
protected function setUseDuration(int $ticks): void {
$this->addComponent(new UseDurationComponent($ticks));
}
}