Equip Window is now functional.
This commit is contained in:
parent
54677e9263
commit
88a239cd91
@ -37,13 +37,14 @@ All rights reserved.
|
|||||||
#pragma endregion
|
#pragma endregion
|
||||||
#include "Menu.h"
|
#include "Menu.h"
|
||||||
#include "MenuComponent.h"
|
#include "MenuComponent.h"
|
||||||
#include "MenuLabel.h"
|
#include "PopupMenuLabel.h"
|
||||||
|
#include "StatLabel.h"
|
||||||
#include "CharacterRotatingDisplay.h"
|
#include "CharacterRotatingDisplay.h"
|
||||||
#include "Crawler.h"
|
#include "Crawler.h"
|
||||||
#include "ClassInfo.h"
|
#include "ClassInfo.h"
|
||||||
#include "MenuItemItemButton.h"
|
#include "MenuItemItemButton.h"
|
||||||
|
#include "EquipSlotButton.h"
|
||||||
#include "Item.h"
|
#include "Item.h"
|
||||||
#include "PopupMenuLabel.h"
|
|
||||||
#include "ScrollableWindowComponent.h"
|
#include "ScrollableWindowComponent.h"
|
||||||
|
|
||||||
INCLUDE_game
|
INCLUDE_game
|
||||||
@ -62,6 +63,16 @@ void Menu::InitializeCharacterMenuWindow(){
|
|||||||
characterMenuWindow->AddComponent("Equip Slot Outline",equipSlotOutline);
|
characterMenuWindow->AddComponent("Equip Slot Outline",equipSlotOutline);
|
||||||
characterMenuWindow->AddComponent("Character Rotating Display",charDisplay);
|
characterMenuWindow->AddComponent("Character Rotating Display",charDisplay);
|
||||||
|
|
||||||
|
const static std::array<ItemAttribute,7>displayAttrs{
|
||||||
|
ItemAttribute::health,
|
||||||
|
ItemAttribute::attack,
|
||||||
|
ItemAttribute::defense,
|
||||||
|
ItemAttribute::moveSpdPct,
|
||||||
|
ItemAttribute::cdrPct,
|
||||||
|
ItemAttribute::critPct,
|
||||||
|
ItemAttribute::critDmgPct,
|
||||||
|
};
|
||||||
|
|
||||||
MenuComponent*equipSelectionOutline=NEW MenuComponent(CHARACTER_MENU,{{123,36},{120,windowSize.y-37}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE);
|
MenuComponent*equipSelectionOutline=NEW MenuComponent(CHARACTER_MENU,{{123,36},{120,windowSize.y-37}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE);
|
||||||
ScrollableWindowComponent*equipmentList=NEW ScrollableWindowComponent(CHARACTER_MENU,{{123,36},{120,windowSize.y-37-24}});
|
ScrollableWindowComponent*equipmentList=NEW ScrollableWindowComponent(CHARACTER_MENU,{{123,36},{120,windowSize.y-37-24}});
|
||||||
MenuComponent*equipSelectionBottomOutline=NEW MenuComponent(CHARACTER_MENU,{{123,36+(windowSize.y-37-24)},{120,24}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE);
|
MenuComponent*equipSelectionBottomOutline=NEW MenuComponent(CHARACTER_MENU,{{123,36+(windowSize.y-37-24)},{120,24}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE);
|
||||||
@ -71,6 +82,10 @@ void Menu::InitializeCharacterMenuWindow(){
|
|||||||
Component<MenuComponent>(data.component->parentMenu,"Equip Selection Bottom Outline")->Enable(false);
|
Component<MenuComponent>(data.component->parentMenu,"Equip Selection Bottom Outline")->Enable(false);
|
||||||
Component<MenuComponent>(data.component->parentMenu,"Equip Selection Select Button")->Enable(false);
|
Component<MenuComponent>(data.component->parentMenu,"Equip Selection Select Button")->Enable(false);
|
||||||
Component<CharacterRotatingDisplay>(data.component->parentMenu,"Character Rotating Display")->Enable(true);
|
Component<CharacterRotatingDisplay>(data.component->parentMenu,"Character Rotating Display")->Enable(true);
|
||||||
|
for(int counter=0;ItemAttribute attribute:displayAttrs){
|
||||||
|
StatLabel*statDisplayLabel=Component<StatLabel>(CHARACTER_MENU,"Attribute "+ItemAttributable::GetDisplayInfo(attribute).name+" Label");
|
||||||
|
statDisplayLabel->SetStatChangeAmt(0);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -84,14 +99,14 @@ void Menu::InitializeCharacterMenuWindow(){
|
|||||||
characterMenuWindow->AddComponent("Equip Selection Bottom Outline",equipSelectionBottomOutline);
|
characterMenuWindow->AddComponent("Equip Selection Bottom Outline",equipSelectionBottomOutline);
|
||||||
characterMenuWindow->AddComponent("Equip Selection Select Button",equipSelectionSelectButton);
|
characterMenuWindow->AddComponent("Equip Selection Select Button",equipSelectionSelectButton);
|
||||||
|
|
||||||
const static std::array<ItemAttribute,7>displayAttrs{
|
const static auto GetLabelText=[](ItemAttribute attribute){
|
||||||
ItemAttribute::health,
|
AttributeData data=ItemAttributable::GetDisplayInfo(attribute);
|
||||||
ItemAttribute::attack,
|
std::string attrStr=data.name+":\n ";
|
||||||
ItemAttribute::defense,
|
attrStr+=std::to_string(game->GetPlayer()->GetStat(attribute));
|
||||||
ItemAttribute::moveSpdPct,
|
if(data.displayAsPercent){
|
||||||
ItemAttribute::cdrPct,
|
attrStr+="%";
|
||||||
ItemAttribute::critPct,
|
}
|
||||||
ItemAttribute::critDmgPct,
|
return attrStr;
|
||||||
};
|
};
|
||||||
|
|
||||||
int equipSlot=1;
|
int equipSlot=1;
|
||||||
@ -104,10 +119,10 @@ void Menu::InitializeCharacterMenuWindow(){
|
|||||||
y-=8;
|
y-=8;
|
||||||
labelY-=8;
|
labelY-=8;
|
||||||
}
|
}
|
||||||
const std::array<std::string,8>slotNames{"Helmet","Weapon","Armor","Gloves","Pants","Shoes","Ring 1","Ring 2"};
|
const static std::array<std::string,8>slotNames{"Helmet","Weapon","Armor","Gloves","Pants","Shoes","Ring 1","Ring 2"};
|
||||||
EquipSlot slot=EquipSlot(equipSlot);
|
EquipSlot slot=EquipSlot(equipSlot);
|
||||||
|
|
||||||
MenuItemItemButton*equipmentSlot=NEW MenuItemItemButton(CHARACTER_MENU,{{x,y+36},{24,24}},Item::BLANK,MenuType::ENUM_END,
|
EquipSlotButton*equipmentSlot=NEW EquipSlotButton(CHARACTER_MENU,{{x,y+36},{24,24}},slot,MenuType::ENUM_END,
|
||||||
[&](MenuFuncData data){
|
[&](MenuFuncData data){
|
||||||
EquipSlot slot=EquipSlot(data.component->I(Attribute::EQUIP_TYPE));
|
EquipSlot slot=EquipSlot(data.component->I(Attribute::EQUIP_TYPE));
|
||||||
|
|
||||||
@ -129,6 +144,17 @@ void Menu::InitializeCharacterMenuWindow(){
|
|||||||
MenuItemItemButton*equip=NEW MenuItemItemButton(CHARACTER_MENU,{{2+xOffset,2},{24,24}},itemInvRef,MenuType::ENUM_END,[](MenuFuncData data){
|
MenuItemItemButton*equip=NEW MenuItemItemButton(CHARACTER_MENU,{{2+xOffset,2},{24,24}},itemInvRef,MenuType::ENUM_END,[](MenuFuncData data){
|
||||||
MenuItemItemButton*comp=(MenuItemItemButton*)data.component;
|
MenuItemItemButton*comp=(MenuItemItemButton*)data.component;
|
||||||
Inventory::EquipItem(comp->GetItem(),EquipSlot(comp->I(Attribute::EQUIP_TYPE)));
|
Inventory::EquipItem(comp->GetItem(),EquipSlot(comp->I(Attribute::EQUIP_TYPE)));
|
||||||
|
for(MenuComponent*button:((ScrollableWindowComponent*)data.parentComponent)->GetComponents()){
|
||||||
|
MenuItemItemButton*comp=(MenuItemItemButton*)button;
|
||||||
|
comp->SetSelected(false);
|
||||||
|
}
|
||||||
|
comp->SetSelected(true);
|
||||||
|
for(int counter=0;ItemAttribute attribute:displayAttrs){
|
||||||
|
StatLabel*statDisplayLabel=Component<StatLabel>(CHARACTER_MENU,"Attribute "+ItemAttributable::GetDisplayInfo(attribute).name+" Label");
|
||||||
|
statDisplayLabel->SetStatChangeAmt(0);
|
||||||
|
}
|
||||||
|
MenuItemItemButton*equipButton=Component<MenuItemItemButton>(CHARACTER_MENU,"Equip Slot "+slotNames[data.parentComponent->I(A::INDEXED_THEME)]);
|
||||||
|
equipButton->SetItem(comp->GetItem());
|
||||||
return true;
|
return true;
|
||||||
},[&](MenuFuncData data){
|
},[&](MenuFuncData data){
|
||||||
MenuItemItemButton*button=(MenuItemItemButton*)data.component;
|
MenuItemItemButton*button=(MenuItemItemButton*)data.component;
|
||||||
@ -141,16 +167,9 @@ void Menu::InitializeCharacterMenuWindow(){
|
|||||||
Item*equippedItem=Inventory::GetEquip(slot);
|
Item*equippedItem=Inventory::GetEquip(slot);
|
||||||
Inventory::EquipItem(buttonItem,slot);
|
Inventory::EquipItem(buttonItem,slot);
|
||||||
for(int counter=0;ItemAttribute attribute:displayAttrs){
|
for(int counter=0;ItemAttribute attribute:displayAttrs){
|
||||||
MenuLabel*statDisplayLabel=Component<MenuLabel>(CHARACTER_MENU,"Attribute "+ItemAttributable::GetDisplayInfo(attribute).name+" Label");
|
StatLabel*statDisplayLabel=Component<StatLabel>(CHARACTER_MENU,"Attribute "+ItemAttributable::GetDisplayInfo(attribute).name+" Label");
|
||||||
int statChangeAmt=game->GetPlayer()->GetStat(attribute)-statsBeforeEquip[counter];
|
int statChangeAmt=game->GetPlayer()->GetStat(attribute)-statsBeforeEquip[counter];
|
||||||
std::string baseLabel=statDisplayLabel->S(Attribute::BASE_TEXT);
|
statDisplayLabel->SetStatChangeAmt(statChangeAmt);
|
||||||
if(statChangeAmt>0){
|
|
||||||
baseLabel+=Color::Green+"(+"+std::to_string(statChangeAmt)+")";
|
|
||||||
}else
|
|
||||||
if(statChangeAmt<0){
|
|
||||||
baseLabel+=Color::Red+"("+std::to_string(statChangeAmt)+")";
|
|
||||||
}
|
|
||||||
statDisplayLabel->SetLabel(baseLabel);
|
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
Inventory::UnequipItem(slot);
|
Inventory::UnequipItem(slot);
|
||||||
@ -158,32 +177,30 @@ void Menu::InitializeCharacterMenuWindow(){
|
|||||||
Inventory::EquipItem(*equippedItem,slot);
|
Inventory::EquipItem(*equippedItem,slot);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
},[&](MenuFuncData data){
|
},DO_NOTHING);
|
||||||
MenuItemItemButton*button=(MenuItemItemButton*)data.component;
|
|
||||||
Item&buttonItem=button->GetItem();
|
|
||||||
for(ItemAttribute attribute:displayAttrs){
|
|
||||||
MenuLabel*statDisplayLabel=Component<MenuLabel>(CHARACTER_MENU,"Attribute "+ItemAttributable::GetDisplayInfo(attribute).name+" Label");
|
|
||||||
statDisplayLabel->SetLabel(statDisplayLabel->S(Attribute::BASE_TEXT));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
equip->I(Attribute::EQUIP_TYPE)=int(slot);
|
equip->I(Attribute::EQUIP_TYPE)=int(slot);
|
||||||
|
if(Inventory::GetEquip(slot)==&itemInvRef){
|
||||||
|
equip->SetSelected(true);
|
||||||
|
}
|
||||||
equipList->AddComponent(Menu::menus[CHARACTER_MENU],"Equip Item "+std::to_string(counter),equip);
|
equipList->AddComponent(Menu::menus[CHARACTER_MENU],"Equip Item "+std::to_string(counter),equip);
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
|
equipList->I(Attribute::INDEXED_THEME)=data.component->I(Attribute::INDEXED_THEME);
|
||||||
Component<MenuComponent>(data.component->parentMenu,"Equip Selection Outline")->Enable(true);
|
Component<MenuComponent>(data.component->parentMenu,"Equip Selection Outline")->Enable(true);
|
||||||
equipList->Enable(true);
|
equipList->Enable(true);
|
||||||
Component<MenuComponent>(data.component->parentMenu,"Equip Selection Bottom Outline")->Enable(true);
|
Component<MenuComponent>(data.component->parentMenu,"Equip Selection Bottom Outline")->Enable(true);
|
||||||
Component<MenuComponent>(data.component->parentMenu,"Equip Selection Select Button")->Enable(true);
|
Component<MenuComponent>(data.component->parentMenu,"Equip Selection Select Button")->Enable(true);
|
||||||
Component<CharacterRotatingDisplay>(data.component->parentMenu,"Character Rotating Display")->Enable(false);
|
Component<CharacterRotatingDisplay>(data.component->parentMenu,"Character Rotating Display")->Enable(false);
|
||||||
return true;
|
return true;
|
||||||
},MenuType::ENUM_END,"","");
|
},DO_NOTHING,DO_NOTHING);
|
||||||
PopupMenuLabel*equipmentLabel=NEW PopupMenuLabel(CHARACTER_MENU,{{labelX,labelY},{29,24}},slotNames[i],{0.5,1},ComponentAttr::SHADOW);
|
PopupMenuLabel*equipmentLabel=NEW PopupMenuLabel(CHARACTER_MENU,{{labelX,labelY},{29,24}},slotNames[i],{0.5,1},ComponentAttr::SHADOW);
|
||||||
equipmentSlot->I(Attribute::EQUIP_TYPE)=int(slot);
|
equipmentSlot->I(Attribute::EQUIP_TYPE)=int(slot);
|
||||||
|
equipmentSlot->I(Attribute::INDEXED_THEME)=i;
|
||||||
|
equipmentSlot->SetShowQuantity(false);
|
||||||
equipSlot<<=1;
|
equipSlot<<=1;
|
||||||
characterMenuWindow->AddComponent("Equip Slot "+slotNames[i],equipmentSlot);
|
characterMenuWindow->AddComponent("Equip Slot "+slotNames[i],equipmentSlot);
|
||||||
characterMenuWindow->AddComponent("Equip Label "+slotNames[i],equipmentLabel);
|
characterMenuWindow->AddComponent("Equip Label "+slotNames[i],equipmentLabel);
|
||||||
|
Menu::AddEquipStatListener(equipmentSlot);
|
||||||
}
|
}
|
||||||
|
|
||||||
MenuComponent*statDisplayOutline=NEW MenuComponent(CHARACTER_MENU,{{245,36},{62,windowSize.y-37}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE);
|
MenuComponent*statDisplayOutline=NEW MenuComponent(CHARACTER_MENU,{{245,36},{62,windowSize.y-37}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE);
|
||||||
@ -192,15 +209,11 @@ void Menu::InitializeCharacterMenuWindow(){
|
|||||||
|
|
||||||
int yOffset=0;
|
int yOffset=0;
|
||||||
for(ItemAttribute attribute:displayAttrs){
|
for(ItemAttribute attribute:displayAttrs){
|
||||||
AttributeData data=ItemAttributable::GetDisplayInfo(attribute);
|
std::string attrStr=GetLabelText(attribute);
|
||||||
std::string attrStr=data.name+":\n ";
|
StatLabel*attrLabel=NEW StatLabel(CHARACTER_MENU,{{245,36+2+float(yOffset)},{62,18}},attribute,1,ComponentAttr::SHADOW|ComponentAttr::LEFT_ALIGN);
|
||||||
attrStr+=std::to_string(game->GetPlayer()->GetStat(attribute));
|
|
||||||
if(data.displayAsPercent){
|
|
||||||
attrStr+="%";
|
|
||||||
}
|
|
||||||
MenuLabel*attrLabel=NEW MenuLabel(CHARACTER_MENU,{{245,36+2+float(yOffset)},{62,18}},attrStr,1,ComponentAttr::SHADOW|ComponentAttr::LEFT_ALIGN);
|
|
||||||
attrLabel->S(Attribute::BASE_TEXT)=attrStr;
|
|
||||||
yOffset+=20;
|
yOffset+=20;
|
||||||
|
AttributeData data=ItemAttributable::GetDisplayInfo(attribute);
|
||||||
characterMenuWindow->AddComponent("Attribute "+data.name+" Label",attrLabel);
|
characterMenuWindow->AddComponent("Attribute "+data.name+" Label",attrLabel);
|
||||||
|
Menu::AddEquipStatListener(attrLabel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -193,6 +193,13 @@ bool Crawler::OnUserCreate(){
|
|||||||
Inventory::AddItem("Bandages",10);
|
Inventory::AddItem("Bandages",10);
|
||||||
Inventory::AddItem("Blue Slime Remains",22);
|
Inventory::AddItem("Blue Slime Remains",22);
|
||||||
Inventory::AddItem("Copper Armor");
|
Inventory::AddItem("Copper Armor");
|
||||||
|
Inventory::AddItem("Copper Pants");
|
||||||
|
Inventory::AddItem("Shell Helmet");
|
||||||
|
Inventory::AddItem("Shell Armor");
|
||||||
|
Inventory::AddItem("Shell Gloves");
|
||||||
|
Inventory::AddItem("Shell Shoes");
|
||||||
|
Inventory::AddItem("Bone Pants");
|
||||||
|
Inventory::AddItem("Bone Gloves");
|
||||||
|
|
||||||
LoadLevel(LEVEL_NAMES["starting_map"_S]);
|
LoadLevel(LEVEL_NAMES["starting_map"_S]);
|
||||||
ChangePlayerClass(WARRIOR);
|
ChangePlayerClass(WARRIOR);
|
||||||
|
|||||||
@ -303,6 +303,10 @@
|
|||||||
<ClInclude Include="Effect.h" />
|
<ClInclude Include="Effect.h" />
|
||||||
<ClInclude Include="Emitter.h" />
|
<ClInclude Include="Emitter.h" />
|
||||||
<ClInclude Include="EncountersSpawnListScrollableWindowComponent.h" />
|
<ClInclude Include="EncountersSpawnListScrollableWindowComponent.h" />
|
||||||
|
<ClInclude Include="EquipSlotButton.h">
|
||||||
|
<SubType>
|
||||||
|
</SubType>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="Error.h" />
|
<ClInclude Include="Error.h" />
|
||||||
<ClInclude Include="GameState.h" />
|
<ClInclude Include="GameState.h" />
|
||||||
<ClInclude Include="Item.h" />
|
<ClInclude Include="Item.h" />
|
||||||
@ -366,6 +370,10 @@
|
|||||||
<ClInclude Include="State_MainMenu.h" />
|
<ClInclude Include="State_MainMenu.h" />
|
||||||
<ClInclude Include="State_OverworldMap.h" />
|
<ClInclude Include="State_OverworldMap.h" />
|
||||||
<ClInclude Include="State_Story.h" />
|
<ClInclude Include="State_Story.h" />
|
||||||
|
<ClInclude Include="StatLabel.h">
|
||||||
|
<SubType>
|
||||||
|
</SubType>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="VisualNovel.h" />
|
<ClInclude Include="VisualNovel.h" />
|
||||||
<ClInclude Include="Test.h" />
|
<ClInclude Include="Test.h" />
|
||||||
<ClInclude Include="Theme.h" />
|
<ClInclude Include="Theme.h" />
|
||||||
|
|||||||
@ -291,6 +291,12 @@
|
|||||||
<ClInclude Include="BitwiseEnum.h">
|
<ClInclude Include="BitwiseEnum.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="StatLabel.h">
|
||||||
|
<Filter>Header Files\Interface</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="EquipSlotButton.h">
|
||||||
|
<Filter>Header Files\Interface</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Player.cpp">
|
<ClCompile Include="Player.cpp">
|
||||||
|
|||||||
62
Crawler/EquipSlotButton.h
Normal file
62
Crawler/EquipSlotButton.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#pragma region License
|
||||||
|
/*
|
||||||
|
License (OLC-3)
|
||||||
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Copyright 2018 - 2023 OneLoneCoder.com
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions or derivations of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions or derivative works in binary form must reproduce the above
|
||||||
|
copyright notice. This list of conditions and the following disclaimer must be
|
||||||
|
reproduced in the documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the copyright holder nor the names of its contributors may
|
||||||
|
be used to endorse or promote products derived from this software without specific
|
||||||
|
prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||||
|
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGE.
|
||||||
|
|
||||||
|
Portions of this software are copyright © 2023 The FreeType
|
||||||
|
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
|
||||||
|
All rights reserved.
|
||||||
|
*/
|
||||||
|
#pragma endregion
|
||||||
|
#pragma once
|
||||||
|
#include "MenuItemItemButton.h"
|
||||||
|
#include "DEFINES.h"
|
||||||
|
#include "Crawler.h"
|
||||||
|
|
||||||
|
INCLUDE_game
|
||||||
|
INCLUDE_ITEM_DATA
|
||||||
|
|
||||||
|
class EquipSlotButton:public MenuItemItemButton{
|
||||||
|
private:
|
||||||
|
EquipSlot slot;
|
||||||
|
public:
|
||||||
|
inline EquipSlotButton(MenuType parent,geom2d::rect<float>rect,EquipSlot slot,MenuType menuDest,MenuFunc onClick,MenuFunc onHover,MenuFunc onMouseOut)
|
||||||
|
:MenuItemItemButton(parent,rect,Item::BLANK,menuDest,onClick,onHover,onMouseOut),slot(slot){}
|
||||||
|
inline void OnEquipStatsUpdate()override{
|
||||||
|
Item&equip=*Inventory::GetEquip(slot);
|
||||||
|
if(!equip.IsBlank()){
|
||||||
|
icon=equip.Decal();
|
||||||
|
SetItem(equip);
|
||||||
|
}else{
|
||||||
|
icon=nullptr;
|
||||||
|
SetItem(Item::BLANK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -105,6 +105,7 @@ public:
|
|||||||
class Item{
|
class Item{
|
||||||
friend class Inventory;
|
friend class Inventory;
|
||||||
friend class Crawler;
|
friend class Crawler;
|
||||||
|
friend class Menu;
|
||||||
private:
|
private:
|
||||||
//The amount in the current item stack.
|
//The amount in the current item stack.
|
||||||
uint32_t amt;
|
uint32_t amt;
|
||||||
|
|||||||
@ -49,6 +49,7 @@ std::map<MenuType,Menu*>Menu::menus;
|
|||||||
std::string Menu::themeSelection="BlueDefault";
|
std::string Menu::themeSelection="BlueDefault";
|
||||||
safeunorderedmap<std::string,Theme>Menu::themes;
|
safeunorderedmap<std::string,Theme>Menu::themes;
|
||||||
safemap<ITCategory,std::vector<MenuComponent*>>Menu::inventoryListeners;
|
safemap<ITCategory,std::vector<MenuComponent*>>Menu::inventoryListeners;
|
||||||
|
std::vector<MenuComponent*>Menu::equipStatListeners;
|
||||||
const vf2d Menu::CENTERED = {-456,-456};
|
const vf2d Menu::CENTERED = {-456,-456};
|
||||||
std::vector<MenuComponent*>Menu::unhandledComponents;
|
std::vector<MenuComponent*>Menu::unhandledComponents;
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -663,6 +664,13 @@ void Menu::AddInventoryListener(MenuComponent*component,ITCategory category){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Menu::AddEquipStatListener(MenuComponent*component){
|
||||||
|
if(std::find(equipStatListeners.begin(),equipStatListeners.end(),component)!=equipStatListeners.end()){
|
||||||
|
ERR("WARNING! Component "<<component->name<<" has already been added to the Equip Stat listener list! There should not be any duplicates!!")
|
||||||
|
}
|
||||||
|
equipStatListeners.push_back(component);
|
||||||
|
}
|
||||||
|
|
||||||
vf2d Menu::center(){
|
vf2d Menu::center(){
|
||||||
return size/2;
|
return size/2;
|
||||||
}
|
}
|
||||||
@ -716,4 +724,4 @@ void Menu::DrawThemedWindow(vf2d menuPos,vf2d size,Pixel renderColor){
|
|||||||
DrawTiledWindowBackground(game,menuPos,size,renderColor);
|
DrawTiledWindowBackground(game,menuPos,size,renderColor);
|
||||||
DrawTiledWindowBorder(game,menuPos,size,renderColor);
|
DrawTiledWindowBorder(game,menuPos,size,renderColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -68,6 +68,7 @@ class Menu:public IAttributable{
|
|||||||
friend class Crawler;
|
friend class Crawler;
|
||||||
friend struct Player;
|
friend struct Player;
|
||||||
friend class ItemInfo;
|
friend class ItemInfo;
|
||||||
|
friend class PlayerStats;
|
||||||
|
|
||||||
float buttonHoldTime=0;
|
float buttonHoldTime=0;
|
||||||
vi2d selection={-1,-1};
|
vi2d selection={-1,-1};
|
||||||
@ -76,6 +77,7 @@ class Menu:public IAttributable{
|
|||||||
MenuComponent*draggingComponent=nullptr;
|
MenuComponent*draggingComponent=nullptr;
|
||||||
Renderable r,overlay;
|
Renderable r,overlay;
|
||||||
static safemap<ITCategory,std::vector<MenuComponent*>>inventoryListeners; //All menu components that care about inventory updates subscribe to this list indirectly (See Menu::AddInventoryListener()).
|
static safemap<ITCategory,std::vector<MenuComponent*>>inventoryListeners; //All menu components that care about inventory updates subscribe to this list indirectly (See Menu::AddInventoryListener()).
|
||||||
|
static std::vector<MenuComponent*>equipStatListeners; //All menu components that care about stat/equip updates subscribe to this list indirectly (See Menu::AddStatListener()).
|
||||||
public:
|
public:
|
||||||
//The constructor is private. Use CreateMenu() instead!
|
//The constructor is private. Use CreateMenu() instead!
|
||||||
Menu()=default;
|
Menu()=default;
|
||||||
@ -107,6 +109,7 @@ public:
|
|||||||
void SetMouseNavigation(bool mouseNavigation);
|
void SetMouseNavigation(bool mouseNavigation);
|
||||||
static void InventorySlotsUpdated(ITCategory cat); //Called whenever an inventory item gets added to the player's inventory, thus increasing the total number of slots in our bag.
|
static void InventorySlotsUpdated(ITCategory cat); //Called whenever an inventory item gets added to the player's inventory, thus increasing the total number of slots in our bag.
|
||||||
static void AddInventoryListener(MenuComponent*component,ITCategory category); //Adds a component to be in a given listener category.
|
static void AddInventoryListener(MenuComponent*component,ITCategory category); //Adds a component to be in a given listener category.
|
||||||
|
static void AddEquipStatListener(MenuComponent*component); //Adds a component to be in an equip stat listener. Will receive updates whenever stats are updated via equips.
|
||||||
vf2d center();
|
vf2d center();
|
||||||
//Returns the last menu type created and last registered component, in case a component is detected as memory leaking, provides this information to each component for safety.
|
//Returns the last menu type created and last registered component, in case a component is detected as memory leaking, provides this information to each component for safety.
|
||||||
static std::pair<MenuType,std::string>GetMemoryLeakReportInfo();
|
static std::pair<MenuType,std::string>GetMemoryLeakReportInfo();
|
||||||
|
|||||||
@ -93,6 +93,8 @@ void MenuComponent::Draw(Crawler*game,vf2d parentPos){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MenuComponent::OnEquipStatsUpdate(){}
|
||||||
|
|
||||||
void MenuComponent::_Draw(Crawler*game){
|
void MenuComponent::_Draw(Crawler*game){
|
||||||
_Draw(game,{0,0});
|
_Draw(game,{0,0});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -107,6 +107,8 @@ public:
|
|||||||
virtual bool HandleOutsideDisabledButtonSelection(MenuComponent*disabledButton);
|
virtual bool HandleOutsideDisabledButtonSelection(MenuComponent*disabledButton);
|
||||||
//Called whenever an inventory slot gets updated, whether it's adding or removing an item.
|
//Called whenever an inventory slot gets updated, whether it's adding or removing an item.
|
||||||
virtual void OnInventorySlotsUpdate(ITCategory cat);
|
virtual void OnInventorySlotsUpdate(ITCategory cat);
|
||||||
|
//Called whenever equipment and base stats are updated, notifying a component that numbers that may be displayed have changed.
|
||||||
|
virtual void OnEquipStatsUpdate();
|
||||||
std::string GetLabel();
|
std::string GetLabel();
|
||||||
std::string GetName();
|
std::string GetName();
|
||||||
virtual void Enable(bool enabled);
|
virtual void Enable(bool enabled);
|
||||||
|
|||||||
@ -51,7 +51,7 @@ INCLUDE_ITEM_DATA
|
|||||||
|
|
||||||
class MenuItemItemButton:public MenuIconButton{
|
class MenuItemItemButton:public MenuIconButton{
|
||||||
private:
|
private:
|
||||||
Item&itemRef;
|
std::reference_wrapper<Item>itemRef;
|
||||||
MenuType itemDescriptionMenu;
|
MenuType itemDescriptionMenu;
|
||||||
std::string itemNameLabelName;
|
std::string itemNameLabelName;
|
||||||
std::string itemDescriptionLabelName;
|
std::string itemDescriptionLabelName;
|
||||||
@ -59,6 +59,8 @@ private:
|
|||||||
MenuFunc onHover;
|
MenuFunc onHover;
|
||||||
MenuFunc onMouseOut;
|
MenuFunc onMouseOut;
|
||||||
bool hoverState=false;
|
bool hoverState=false;
|
||||||
|
bool selected=false;
|
||||||
|
bool hideQty=false;
|
||||||
public:
|
public:
|
||||||
inline MenuItemItemButton(MenuType parent,geom2d::rect<float>rect,Item&itemRef,MenuType menuDest,MenuFunc onClick,MenuType itemDescriptionMenu,std::string itemNameLabelName,std::string itemDescriptionLabelName)
|
inline MenuItemItemButton(MenuType parent,geom2d::rect<float>rect,Item&itemRef,MenuType menuDest,MenuFunc onClick,MenuType itemDescriptionMenu,std::string itemNameLabelName,std::string itemDescriptionLabelName)
|
||||||
:MenuIconButton(parent,rect,(!itemRef.IsBlank())?itemRef.Decal():nullptr,menuDest,onClick),itemRef(itemRef),itemDescriptionMenu(itemDescriptionMenu),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName),onHover(DO_NOTHING){
|
:MenuIconButton(parent,rect,(!itemRef.IsBlank())?itemRef.Decal():nullptr,menuDest,onClick),itemRef(itemRef),itemDescriptionMenu(itemDescriptionMenu),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName),onHover(DO_NOTHING){
|
||||||
@ -72,18 +74,27 @@ public:
|
|||||||
valid=!itemRef.IsBlank();
|
valid=!itemRef.IsBlank();
|
||||||
}
|
}
|
||||||
inline Item&GetItem(){
|
inline Item&GetItem(){
|
||||||
return itemRef;
|
return itemRef.get();
|
||||||
|
}
|
||||||
|
inline Item&SetItem(Item&newItem){
|
||||||
|
return itemRef=std::reference_wrapper<Item>(newItem);
|
||||||
|
}
|
||||||
|
inline void SetSelected(bool selected){
|
||||||
|
this->selected=selected;
|
||||||
|
}
|
||||||
|
inline void SetShowQuantity(bool show){
|
||||||
|
this->hideQty=!show;
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
virtual inline void Update(Crawler*game)override{
|
virtual inline void Update(Crawler*game)override{
|
||||||
MenuIconButton::Update(game);
|
MenuIconButton::Update(game);
|
||||||
valid=!itemRef.IsBlank();
|
valid=!itemRef.get().IsBlank();
|
||||||
std::string labelNameText;
|
std::string labelNameText;
|
||||||
std::string labelDescriptionText;
|
std::string labelDescriptionText;
|
||||||
if(valid){
|
if(valid){
|
||||||
icon=itemRef.Decal();
|
icon=itemRef.get().Decal();
|
||||||
labelNameText=itemRef.Name();
|
labelNameText=itemRef.get().Name();
|
||||||
labelDescriptionText=itemRef.Description();
|
labelDescriptionText=itemRef.get().Description();
|
||||||
}else{
|
}else{
|
||||||
icon=nullptr;
|
icon=nullptr;
|
||||||
labelNameText="";
|
labelNameText="";
|
||||||
@ -107,11 +118,14 @@ protected:
|
|||||||
}
|
}
|
||||||
virtual inline void Draw(Crawler*game,vf2d parentPos)override{
|
virtual inline void Draw(Crawler*game,vf2d parentPos)override{
|
||||||
MenuIconButton::Draw(game,parentPos);
|
MenuIconButton::Draw(game,parentPos);
|
||||||
|
if(selected){
|
||||||
|
drawutil::DrawCrosshair(game,{parentPos+rect.pos,rect.size},0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
virtual inline void DrawDecal(Crawler*game,vf2d parentPos,bool focused)override{
|
virtual inline void DrawDecal(Crawler*game,vf2d parentPos,bool focused)override{
|
||||||
MenuIconButton::DrawDecal(game,parentPos,focused);
|
MenuIconButton::DrawDecal(game,parentPos,focused);
|
||||||
if(valid){
|
if(valid&&!hideQty){
|
||||||
std::string quantityText="x"+std::to_string(itemRef.Amt());
|
std::string quantityText="x"+std::to_string(itemRef.get().Amt());
|
||||||
vf2d textSize=vf2d(game->GetTextSizeProp(quantityText))*0.5;
|
vf2d textSize=vf2d(game->GetTextSizeProp(quantityText))*0.5;
|
||||||
vf2d drawPos=parentPos+rect.pos+rect.size-textSize;
|
vf2d drawPos=parentPos+rect.pos+rect.size-textSize;
|
||||||
if(PointWithinParent(this,drawPos)){
|
if(PointWithinParent(this,drawPos)){
|
||||||
|
|||||||
@ -56,7 +56,7 @@ public:
|
|||||||
this->background=attributes&ComponentAttr::BACKGROUND;
|
this->background=attributes&ComponentAttr::BACKGROUND;
|
||||||
showDefaultLabel=false;
|
showDefaultLabel=false;
|
||||||
}
|
}
|
||||||
inline void SetLabel(std::string text){
|
inline virtual void SetLabel(std::string text){
|
||||||
label=text;
|
label=text;
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@ -47,6 +47,7 @@ All rights reserved.
|
|||||||
#include "Key.h"
|
#include "Key.h"
|
||||||
#include "Menu.h"
|
#include "Menu.h"
|
||||||
#include "GameState.h"
|
#include "GameState.h"
|
||||||
|
#include "MenuComponent.h"
|
||||||
|
|
||||||
INCLUDE_MONSTER_DATA
|
INCLUDE_MONSTER_DATA
|
||||||
INCLUDE_MONSTER_LIST
|
INCLUDE_MONSTER_LIST
|
||||||
@ -873,6 +874,9 @@ void PlayerStats::RecalculateEquipStats(){
|
|||||||
equipStats.get(a)+=equip->GetStats().A(a);
|
equipStats.get(a)+=equip->GetStats().A(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for(MenuComponent*component:Menu::equipStatListeners){
|
||||||
|
component->OnEquipStatsUpdate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const int PlayerStats::GetStat(ItemAttribute stat){
|
const int PlayerStats::GetStat(ItemAttribute stat){
|
||||||
return equipStats.A(stat);
|
return equipStats.A(stat);
|
||||||
|
|||||||
@ -71,8 +71,8 @@ public:
|
|||||||
Menu::menus[parentMenu]->AddComponent(name+downButton->rect.pos.str()+"_"+downButton->rect.size.str(),downButton);
|
Menu::menus[parentMenu]->AddComponent(name+downButton->rect.pos.str()+"_"+downButton->rect.size.str(),downButton);
|
||||||
}
|
}
|
||||||
virtual inline void RemoveAllComponents(){
|
virtual inline void RemoveAllComponents(){
|
||||||
for(MenuComponent*item:components){
|
while(components.size()>0){
|
||||||
RemoveButton(item);
|
RemoveButton(components.back());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual inline void RemoveButton(MenuComponent*button){
|
virtual inline void RemoveButton(MenuComponent*button){
|
||||||
|
|||||||
89
Crawler/StatLabel.h
Normal file
89
Crawler/StatLabel.h
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
#pragma region License
|
||||||
|
/*
|
||||||
|
License (OLC-3)
|
||||||
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Copyright 2018 - 2023 OneLoneCoder.com
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions or derivations of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions or derivative works in binary form must reproduce the above
|
||||||
|
copyright notice. This list of conditions and the following disclaimer must be
|
||||||
|
reproduced in the documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the copyright holder nor the names of its contributors may
|
||||||
|
be used to endorse or promote products derived from this software without specific
|
||||||
|
prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||||
|
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGE.
|
||||||
|
|
||||||
|
Portions of this software are copyright © 2023 The FreeType
|
||||||
|
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
|
||||||
|
All rights reserved.
|
||||||
|
*/
|
||||||
|
#pragma endregion
|
||||||
|
#pragma once
|
||||||
|
#include "MenuLabel.h"
|
||||||
|
#include "DEFINES.h"
|
||||||
|
#include "Crawler.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
INCLUDE_game
|
||||||
|
|
||||||
|
class StatLabel:public MenuLabel{
|
||||||
|
private:
|
||||||
|
ItemAttribute stat;
|
||||||
|
int value=0;
|
||||||
|
int statChangeAmt=0;
|
||||||
|
public:
|
||||||
|
inline StatLabel(MenuType parent,geom2d::rect<float>rect,ItemAttribute stat,int scale=1,ComponentAttr attributes=ComponentAttr::NONE)
|
||||||
|
:MenuLabel(parent,rect,"",scale,attributes),stat(stat){
|
||||||
|
border=attributes&ComponentAttr::OUTLINE;
|
||||||
|
this->background=attributes&ComponentAttr::BACKGROUND;
|
||||||
|
showDefaultLabel=false;
|
||||||
|
SetValue(game->GetPlayer()->GetStat(stat));
|
||||||
|
}
|
||||||
|
void SetValue(int value){
|
||||||
|
this->value=value;
|
||||||
|
UpdateLabel();
|
||||||
|
}
|
||||||
|
void SetStatChangeAmt(int changeAmt){
|
||||||
|
this->statChangeAmt=changeAmt;
|
||||||
|
UpdateLabel();
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
inline void SetLabel(std::string text)override final{
|
||||||
|
MenuLabel::SetLabel(text);
|
||||||
|
}
|
||||||
|
inline void OnEquipStatsUpdate()override final{
|
||||||
|
SetValue(game->GetPlayer()->GetStat(stat));
|
||||||
|
}
|
||||||
|
inline void UpdateLabel(){
|
||||||
|
AttributeData data=ItemAttributable::GetDisplayInfo(stat);
|
||||||
|
std::string attrStr=data.name+":\n ";
|
||||||
|
attrStr+=std::to_string(value);
|
||||||
|
if(data.displayAsPercent){
|
||||||
|
attrStr+="%";
|
||||||
|
}
|
||||||
|
if(statChangeAmt>0){
|
||||||
|
attrStr+=Color::Green+"(+"+std::to_string(statChangeAmt)+")";
|
||||||
|
}else
|
||||||
|
if(statChangeAmt<0){
|
||||||
|
attrStr+=Color::Red+"("+std::to_string(statChangeAmt)+")";
|
||||||
|
}
|
||||||
|
SetLabel(attrStr);
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -39,7 +39,7 @@ All rights reserved.
|
|||||||
#define VERSION_MAJOR 0
|
#define VERSION_MAJOR 0
|
||||||
#define VERSION_MINOR 2
|
#define VERSION_MINOR 2
|
||||||
#define VERSION_PATCH 1
|
#define VERSION_PATCH 1
|
||||||
#define VERSION_BUILD 3534
|
#define VERSION_BUILD 3570
|
||||||
|
|
||||||
#define stringify(a) stringify_(a)
|
#define stringify(a) stringify_(a)
|
||||||
#define stringify_(a) #a
|
#define stringify_(a) #a
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user