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
|
#include "StarConsumableItem.hpp"
#include "StarRoot.hpp"
#include "StarJsonExtra.hpp"
#include "StarRandom.hpp"
#include "StarStatusController.hpp"
namespace Star {
ConsumableItem::ConsumableItem(Json const& config, String const& directory, Json const& data)
: Item(config, directory, data), SwingableItem(config) {
setWindupTime(0);
setCooldownTime(0.25f);
m_requireEdgeTrigger = true;
m_swingStart = config.getFloat("swingStart", -60) * Constants::pi / 180;
m_swingFinish = config.getFloat("swingFinish", 40) * Constants::pi / 180;
m_swingAimFactor = config.getFloat("swingAimFactor", 0.2f);
m_blockingEffects = jsonToStringSet(instanceValue("blockingEffects", JsonArray()));
if (auto foodValue = instanceValue("foodValue")) {
m_foodValue = foodValue.toFloat();
m_blockingEffects.add("wellfed");
}
m_emitters = jsonToStringSet(instanceValue("emitters", JsonArray{"eating"}));
m_emote = instanceValue("emote", "eat").toString();
m_consuming = false;
}
ItemPtr ConsumableItem::clone() const {
return make_shared<ConsumableItem>(*this);
}
List<Drawable> ConsumableItem::drawables() const {
auto drawables = iconDrawables();
Drawable::scaleAll(drawables, 1.0f / TilePixels);
Drawable::translateAll(drawables, -handPosition() / TilePixels);
return drawables;
}
void ConsumableItem::update(float dt, FireMode fireMode, bool shifting, HashSet<MoveControlType> const& moves) {
SwingableItem::update(dt, fireMode, shifting, moves);
if (entityMode() == EntityMode::Master) {
if (m_consuming)
owner()->addEffectEmitters(m_emitters);
if (ready())
maybeConsume();
}
}
void ConsumableItem::fire(FireMode mode, bool shifting, bool edgeTriggered) {
if (canUse())
FireableItem::fire(mode, shifting, edgeTriggered);
}
void ConsumableItem::fireTriggered() {
if (canUse()) {
triggerEffects();
FireableItem::fireTriggered();
}
}
void ConsumableItem::uninit() {
maybeConsume();
FireableItem::uninit();
}
bool ConsumableItem::canUse() const {
if (!count() || m_consuming)
return false;
for (auto pair : owner()->statusController()->activeUniqueStatusEffectSummary()) {
if (m_blockingEffects.contains(pair.first))
return false;
}
return true;
}
void ConsumableItem::triggerEffects() {
auto options = instanceValue("effects", JsonArray()).toArray();
if (options.size()) {
auto option = Random::randFrom(options).toArray().transformed(jsonToEphemeralStatusEffect);
owner()->statusController()->addEphemeralEffects(option);
}
if (m_foodValue) {
owner()->statusController()->giveResource("food", *m_foodValue);
if (owner()->statusController()->resourcePercentage("food") == 1.0f)
owner()->statusController()->addEphemeralEffect(EphemeralStatusEffect{UniqueStatusEffect("wellfed"), {}});
}
if (!m_emote.empty())
owner()->requestEmote(m_emote);
m_consuming = true;
}
void ConsumableItem::maybeConsume() {
if (m_consuming) {
m_consuming = false;
world()->sendEntityMessage(owner()->entityId(), "recordEvent", {"useItem", JsonObject {
{"itemType", name()}
}});
if (count())
setCount(count() - 1);
else
setCount(0);
}
}
}
|