2023-06-20 04:33:09 +00:00
|
|
|
#include "StarItemSlotWidget.hpp"
|
|
|
|
#include "StarRoot.hpp"
|
|
|
|
#include "StarJsonExtra.hpp"
|
|
|
|
#include "StarWidgetParsing.hpp"
|
|
|
|
#include "StarImageMetadataDatabase.hpp"
|
|
|
|
#include "StarItem.hpp"
|
|
|
|
#include "StarDurabilityItem.hpp"
|
|
|
|
#include "StarAssets.hpp"
|
|
|
|
#include "StarGameTypes.hpp"
|
|
|
|
|
|
|
|
namespace Star {
|
|
|
|
|
|
|
|
ItemSlotWidget::ItemSlotWidget(ItemPtr const& item, String const& backingImage)
|
|
|
|
: m_item(item), m_backingImage(backingImage) {
|
|
|
|
m_drawBackingImageWhenFull = false;
|
|
|
|
m_drawBackingImageWhenEmpty = true;
|
|
|
|
m_fontSize = 0;
|
|
|
|
m_progress = 1;
|
|
|
|
|
|
|
|
auto assets = Root::singleton().assets();
|
|
|
|
auto interfaceConfig = assets->json("/interface.config");
|
|
|
|
m_countPosition = TextPositioning(jsonToVec2F(interfaceConfig.get("itemCountRightAnchor")), HorizontalAnchor::RightAnchor);
|
|
|
|
m_countFontMode = FontMode::Normal;
|
|
|
|
m_fontSize = interfaceConfig.query("font.itemSize").toInt();
|
2023-06-21 12:29:40 +00:00
|
|
|
m_font = interfaceConfig.query("font.defaultFont").toString();
|
2023-06-20 04:33:09 +00:00
|
|
|
m_fontColor = Color::rgb(jsonToVec3B(interfaceConfig.query("font.defaultColor")));
|
|
|
|
m_itemDraggableArea = jsonToRectI(interfaceConfig.get("itemDraggableArea"));
|
|
|
|
m_durabilityOffset = jsonToVec2I(interfaceConfig.get("itemIconDurabilityOffset"));
|
|
|
|
|
|
|
|
auto newItemIndicatorConfig = interfaceConfig.get("newItemAnimation");
|
|
|
|
m_newItemIndicator = Animation(newItemIndicatorConfig);
|
|
|
|
// End animation before it begins, only display when triggered
|
|
|
|
m_newItemIndicator.update(newItemIndicatorConfig.getDouble("animationCycle") * newItemIndicatorConfig.getDouble("loops", 1.0f));
|
|
|
|
|
|
|
|
Json highlightAnimationConfig = interfaceConfig.get("highlightAnimation");
|
|
|
|
m_highlightAnimation = Animation(highlightAnimationConfig);
|
|
|
|
m_highlightEnabled = false;
|
|
|
|
|
|
|
|
Vec2I backingImageSize;
|
|
|
|
if (m_backingImage.size()) {
|
|
|
|
auto imgMetadata = Root::singleton().imageMetadataDatabase();
|
|
|
|
backingImageSize = Vec2I(imgMetadata->imageSize(m_backingImage));
|
|
|
|
}
|
|
|
|
setSize(m_itemDraggableArea.max().piecewiseMax(backingImageSize));
|
|
|
|
|
|
|
|
WidgetParser parser;
|
|
|
|
|
|
|
|
parser.construct(assets->json("/interface/itemSlot.config").get("config"), this);
|
|
|
|
m_durabilityBar = fetchChild<ProgressWidget>("durabilityBar");
|
|
|
|
m_durabilityBar->hide();
|
|
|
|
m_showDurability = false;
|
|
|
|
m_showCount = true;
|
|
|
|
m_showRarity = true;
|
|
|
|
m_showLinkIndicator = false;
|
|
|
|
|
|
|
|
disableScissoring();
|
|
|
|
}
|
|
|
|
|
2023-07-20 14:58:49 +00:00
|
|
|
void ItemSlotWidget::update(float dt) {
|
|
|
|
if (m_item)
|
|
|
|
m_newItemIndicator.update(dt);
|
|
|
|
if (m_highlightEnabled)
|
|
|
|
m_highlightAnimation.update(dt);
|
|
|
|
Widget::update(dt);
|
2023-06-20 04:33:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool ItemSlotWidget::sendEvent(InputEvent const& event) {
|
|
|
|
if (m_visible) {
|
|
|
|
if (auto mouseButton = event.ptr<MouseButtonDownEvent>()) {
|
2024-03-27 05:00:13 +00:00
|
|
|
if (mouseButton->mouseButton == MouseButton::Left
|
|
|
|
|| (m_rightClickCallback && mouseButton->mouseButton == MouseButton::Right)
|
|
|
|
|| (m_middleClickCallback && mouseButton->mouseButton == MouseButton::Middle)) {
|
2023-06-20 04:33:09 +00:00
|
|
|
Vec2I mousePos = *context()->mousePosition(event);
|
|
|
|
RectI itemArea = m_itemDraggableArea.translated(screenPosition());
|
|
|
|
if (itemArea.contains(mousePos)) {
|
|
|
|
if (mouseButton->mouseButton == MouseButton::Right)
|
|
|
|
m_rightClickCallback(this);
|
2024-03-27 05:00:13 +00:00
|
|
|
else if (mouseButton->mouseButton == MouseButton::Middle)
|
|
|
|
m_middleClickCallback(this);
|
2023-06-20 04:33:09 +00:00
|
|
|
else
|
|
|
|
m_callback(this);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ItemSlotWidget::setCallback(WidgetCallbackFunc callback) {
|
|
|
|
m_callback = callback;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ItemSlotWidget::setRightClickCallback(WidgetCallbackFunc callback) {
|
|
|
|
m_rightClickCallback = callback;
|
|
|
|
}
|
|
|
|
|
2024-03-27 05:00:13 +00:00
|
|
|
void ItemSlotWidget::setMiddleClickCallback(WidgetCallbackFunc callback) {
|
|
|
|
m_middleClickCallback = callback;
|
|
|
|
}
|
|
|
|
|
2023-06-20 04:33:09 +00:00
|
|
|
void ItemSlotWidget::setItem(ItemPtr const& item) {
|
|
|
|
m_item = item;
|
|
|
|
}
|
|
|
|
|
|
|
|
ItemPtr ItemSlotWidget::item() const {
|
|
|
|
return m_item;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ItemSlotWidget::setProgress(float progress) {
|
|
|
|
m_progress = progress;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ItemSlotWidget::setBackingImageAffinity(bool full, bool empty) {
|
|
|
|
m_drawBackingImageWhenFull = full;
|
|
|
|
m_drawBackingImageWhenEmpty = empty;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ItemSlotWidget::setCountPosition(TextPositioning textPositioning) {
|
|
|
|
m_countPosition = textPositioning;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ItemSlotWidget::setCountFontMode(FontMode fontMode) {
|
|
|
|
m_countFontMode = fontMode;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ItemSlotWidget::showDurability(bool show) {
|
|
|
|
m_showDurability = show;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ItemSlotWidget::showCount(bool show) {
|
|
|
|
m_showCount = show;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ItemSlotWidget::showRarity(bool showRarity) {
|
|
|
|
m_showRarity = showRarity;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ItemSlotWidget::showLinkIndicator(bool showLinkIndicator) {
|
|
|
|
m_showLinkIndicator = showLinkIndicator;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ItemSlotWidget::indicateNew() {
|
|
|
|
m_newItemIndicator.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ItemSlotWidget::setHighlightEnabled(bool highlight) {
|
|
|
|
if (!m_highlightEnabled && highlight)
|
|
|
|
m_highlightAnimation.reset();
|
|
|
|
m_highlightEnabled = highlight;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ItemSlotWidget::renderImpl() {
|
|
|
|
if (m_item) {
|
|
|
|
if (m_drawBackingImageWhenFull && m_backingImage != "")
|
|
|
|
context()->drawInterfaceQuad(m_backingImage, Vec2F(screenPosition()));
|
|
|
|
|
|
|
|
List<Drawable> iconDrawables = m_item->iconDrawables();
|
|
|
|
|
|
|
|
if (m_showRarity) {
|
|
|
|
String border = rarityBorder(m_item->rarity());
|
|
|
|
context()->drawInterfaceQuad(border, Vec2F(screenPosition()));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_showLinkIndicator) {
|
|
|
|
// TODO: Hardcoded
|
2023-06-24 15:16:40 +00:00
|
|
|
context()->drawInterfaceQuad(String("/interface/inventory/itemlinkindicator.png"), Vec2F(screenPosition() - Vec2I(1, 1)));
|
2023-06-20 04:33:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for (auto i : iconDrawables)
|
|
|
|
context()->drawInterfaceDrawable(i, Vec2F(screenPosition() + size() / 2));
|
|
|
|
|
|
|
|
if (!m_newItemIndicator.isComplete())
|
|
|
|
context()->drawInterfaceDrawable(m_newItemIndicator.drawable(1.0), Vec2F(screenPosition() + size() / 2), Color::White.toRgba());
|
|
|
|
|
|
|
|
if (m_showDurability) {
|
|
|
|
if (auto durabilityItem = as<DurabilityItem>(m_item)) {
|
|
|
|
float amount = durabilityItem->durabilityStatus();
|
|
|
|
m_durabilityBar->setCurrentProgressLevel(amount);
|
|
|
|
|
|
|
|
if (amount < 1)
|
|
|
|
m_durabilityBar->show();
|
|
|
|
else
|
|
|
|
m_durabilityBar->hide();
|
|
|
|
} else {
|
|
|
|
m_durabilityBar->hide();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int frame = (int)roundf(m_progress * 18); // TODO: Hardcoded lol
|
2023-06-27 10:23:44 +00:00
|
|
|
context()->drawInterfaceQuad(String(strf("/interface/cooldown.png:{}", frame)), Vec2F(screenPosition()));
|
2023-06-20 04:33:09 +00:00
|
|
|
|
|
|
|
if (m_item->count() > 1 && m_showCount) { // we don't need to tell people that there's only 1 of something
|
2023-06-21 12:29:40 +00:00
|
|
|
context()->setFont(m_font);
|
2023-06-20 04:33:09 +00:00
|
|
|
context()->setFontSize(m_fontSize);
|
|
|
|
context()->setFontColor(m_fontColor.toRgba());
|
|
|
|
context()->setFontMode(m_countFontMode);
|
2023-07-06 09:26:28 +00:00
|
|
|
context()->renderInterfaceText(toString(m_item->count()), m_countPosition.translated(Vec2F(screenPosition())));
|
2023-08-02 09:29:21 +00:00
|
|
|
context()->setFontMode(FontMode::Normal);
|
|
|
|
context()->setDefaultFont();
|
2023-06-20 04:33:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} else if (m_drawBackingImageWhenEmpty && m_backingImage != "") {
|
|
|
|
context()->drawInterfaceQuad(m_backingImage, Vec2F(screenPosition()));
|
|
|
|
int frame = (int)roundf(m_progress * 18); // TODO: Hardcoded lol
|
2023-06-27 10:23:44 +00:00
|
|
|
context()->drawInterfaceQuad(String(strf("/interface/cooldown.png:{}", frame)), Vec2F(screenPosition()));
|
2023-06-20 04:33:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (m_highlightEnabled) {
|
|
|
|
context()->drawInterfaceDrawable(m_highlightAnimation.drawable(1.0), Vec2F(screenPosition() + size() / 2), Color::White.toRgba());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!m_item)
|
|
|
|
m_durabilityBar->hide();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|