#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(); m_font = interfaceConfig.query("font.defaultFont").toString(); 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("durabilityBar"); m_durabilityBar->hide(); m_showDurability = false; m_showCount = true; m_showRarity = true; m_showLinkIndicator = false; disableScissoring(); } void ItemSlotWidget::update() { Widget::update(); } bool ItemSlotWidget::sendEvent(InputEvent const& event) { if (m_visible) { if (auto mouseButton = event.ptr()) { if (mouseButton->mouseButton == MouseButton::Left || (m_rightClickCallback && mouseButton->mouseButton == MouseButton::Right)) { Vec2I mousePos = *context()->mousePosition(event); RectI itemArea = m_itemDraggableArea.translated(screenPosition()); if (itemArea.contains(mousePos)) { if (mouseButton->mouseButton == MouseButton::Right) m_rightClickCallback(this); else m_callback(this); return true; } } } } return false; } void ItemSlotWidget::setCallback(WidgetCallbackFunc callback) { m_callback = callback; } void ItemSlotWidget::setRightClickCallback(WidgetCallbackFunc callback) { m_rightClickCallback = callback; } 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 iconDrawables = m_item->iconDrawables(); if (m_showRarity) { String border = rarityBorder(m_item->rarity()); context()->drawInterfaceQuad(border, Vec2F(screenPosition())); } if (m_showLinkIndicator) { // TODO: Hardcoded context()->drawInterfaceQuad("/interface/inventory/itemlinkindicator.png", Vec2F(screenPosition() - Vec2I(1, 1))); } for (auto i : iconDrawables) context()->drawInterfaceDrawable(i, Vec2F(screenPosition() + size() / 2)); m_newItemIndicator.update(WorldTimestep); 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(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 context()->drawInterfaceQuad(strf("/interface/cooldown.png:%d", frame), Vec2F(screenPosition())); if (m_item->count() > 1 && m_showCount) { // we don't need to tell people that there's only 1 of something context()->setFont(m_font); context()->setFontSize(m_fontSize); context()->setFontColor(m_fontColor.toRgba()); context()->setFontMode(m_countFontMode); context()->renderInterfaceText(strf("%d", m_item->count()), m_countPosition.translated(Vec2F(screenPosition()))); } } else if (m_drawBackingImageWhenEmpty && m_backingImage != "") { context()->drawInterfaceQuad(m_backingImage, Vec2F(screenPosition())); int frame = (int)roundf(m_progress * 18); // TODO: Hardcoded lol context()->drawInterfaceQuad(strf("/interface/cooldown.png:%d", frame), Vec2F(screenPosition())); } if (m_highlightEnabled) { m_highlightAnimation.update(WorldTimestep); context()->drawInterfaceDrawable(m_highlightAnimation.drawable(1.0), Vec2F(screenPosition() + size() / 2), Color::White.toRgba()); } if (!m_item) m_durabilityBar->hide(); } }