Character Info Window layouts setup

pull/28/head
sigonasr2 1 year ago
parent 298b0c4ca7
commit a659bf7924
  1. 33
      Crawler/AttributableStat.h
  2. 14
      Crawler/BitwiseEnum.h
  3. 72
      Crawler/CharacterMenuWindow.cpp
  4. 4
      Crawler/Crawler.cpp
  5. 2
      Crawler/Item.cpp
  6. 2
      Crawler/MenuComponent.h
  7. 4
      Crawler/MenuItemItemButton.h
  8. 20
      Crawler/Player.cpp
  9. 7
      Crawler/Player.h
  10. 15
      Crawler/PopupMenuLabel.h
  11. 8
      Crawler/ScrollableWindowComponent.h
  12. 2
      Crawler/Version.h

@ -45,7 +45,7 @@ enum class ItemAttribute{
/*////////////////////////////////////////////*/
/*//////*/ENUM_START,/*///////////////////////*/
/*////////////////////////////////////////////*/
//////////////
defense,
health,
attack,
@ -56,18 +56,49 @@ enum class ItemAttribute{
healthPct, //Percentage of health boost
healthPctRecoveryPer6sec, //Percentage of health recovered every 6 seconds.
/////////NOTE: When adding a new item stat, provide its display name in the map below.
/*////////////////////////////////////////////*/
/*//////*/ENUM_END/*//////////////////////////*/
/*////////////////////////////////////////////*/
};
namespace DisplayType{
enum DisplayType{
DISPLAY_AS_NUMBER=0,
DISPLAY_AS_PERCENT=1,
};
}
struct AttributeData{
std::string name;
DisplayType::DisplayType displayAsPercent;
};
class ItemAttributable{
std::map<ItemAttribute,int>attributes;
private:
inline static std::map<ItemAttribute,AttributeData>data{
{ItemAttribute::defense,{"Defense",DisplayType::DISPLAY_AS_NUMBER}},
{ItemAttribute::health,{"Health",DisplayType::DISPLAY_AS_NUMBER}},
{ItemAttribute::attack,{"Attack",DisplayType::DISPLAY_AS_NUMBER}},
{ItemAttribute::moveSpdPct,{"Move Spd",DisplayType::DISPLAY_AS_PERCENT}},
{ItemAttribute::cdrPct,{"CDR",DisplayType::DISPLAY_AS_PERCENT}},
{ItemAttribute::critPct,{"Crit Rate",DisplayType::DISPLAY_AS_PERCENT}},
{ItemAttribute::critDmgPct,{"Crit Dmg",DisplayType::DISPLAY_AS_PERCENT}},
{ItemAttribute::healthPct,{"Health %",DisplayType::DISPLAY_AS_PERCENT}}, //Percentage of health boost
{ItemAttribute::healthPctRecoveryPer6sec,{"HP Recovery",DisplayType::DISPLAY_AS_NUMBER}} //Percentage of health recovered every 6 seconds.}
};
public:
//Returns a copy of all the attributes to be passed to a new instance easily / to sync values between both.
inline void copyTo(ItemAttributable&target){
target.attributes=attributes;
}
inline int&get(ItemAttribute a){
return attributes[a];
}
inline const int get_readOnly(ItemAttribute a)const{
return attributes.at(a);
}
inline static AttributeData GetDisplayInfo(ItemAttribute a){
return data[a];
}
};

@ -48,3 +48,17 @@ constexpr auto operator&(T attribute,T attribute2) noexcept
{
return static_cast<std::underlying_type_t<T>>(attribute)&static_cast<std::underlying_type_t<T>>(attribute2);
}
template<typename T>
constexpr auto operator|=(T&lhs,const T&rhs) noexcept
{
lhs=T(static_cast<std::underlying_type_t<T>>(lhs)|static_cast<std::underlying_type_t<T>>(rhs));
return lhs;
}
template<typename T>
constexpr auto operator&=(T&lhs,const T&rhs) noexcept
{
lhs=T(static_cast<std::underlying_type_t<T>>(lhs)&static_cast<std::underlying_type_t<T>>(rhs));
return lhs;
}

@ -41,6 +41,10 @@ All rights reserved.
#include "CharacterRotatingDisplay.h"
#include "Crawler.h"
#include "ClassInfo.h"
#include "MenuItemItemButton.h"
#include "Item.h"
#include "PopupMenuLabel.h"
#include "ScrollableWindowComponent.h"
INCLUDE_game
INCLUDE_GFX
@ -57,4 +61,72 @@ void Menu::InitializeCharacterMenuWindow(){
characterMenuWindow->AddComponent("Character Label",characterLabel);
characterMenuWindow->AddComponent("Equip Slot Outline",equipSlotOutline);
characterMenuWindow->AddComponent("Character Rotating Display",charDisplay);
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}});
MenuComponent*equipSelectionBottomOutline=NEW MenuComponent(CHARACTER_MENU,{{123,36+(windowSize.y-37-24)},{120,24}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE);
MenuComponent*equipSelectionSelectButton=NEW MenuComponent(CHARACTER_MENU,{{123+12,36+(windowSize.y-37-24)+6},{96,12}},"Select",DO_NOTHING);
equipSelectionOutline->Enable(false);
equipmentList->Enable(false);
equipSelectionBottomOutline->Enable(false);
equipSelectionSelectButton->Enable(false);
characterMenuWindow->AddComponent("Equip Selection Outline",equipSelectionOutline);
characterMenuWindow->AddComponent("Equip List",equipmentList);
characterMenuWindow->AddComponent("Equip Selection Bottom Outline",equipSelectionBottomOutline);
characterMenuWindow->AddComponent("Equip Selection Select Button",equipSelectionSelectButton);
int equipSlot=1;
for(int i=0;i<8;i++){
float x=31+(i%2)*33;
float y=24+(i/2)*28;
float labelX=2+(i%2)*90;
float labelY=24+(i/2)*28+36;
if(i<6){
y-=8;
labelY-=8;
}
const std::array<std::string,8>slotNames{"Helmet","Weapon","Armor","Gloves","Pants","Shoes","Ring 1","Ring 2"};
EquipSlot slot=EquipSlot(equipSlot);
MenuItemItemButton*equipmentSlot=NEW MenuItemItemButton(CHARACTER_MENU,{{x,y+36},{24,24}},Item::BLANK,MenuType::ENUM_END,
[](MenuFuncData data){
Component<MenuComponent>(data.component->parentMenu,"Equip Selection Outline")->Enable(true);
Component<ScrollableWindowComponent>(data.component->parentMenu,"Equip List")->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<CharacterRotatingDisplay>(data.component->parentMenu,"Character Rotating Display")->Enable(false);
return true;
},MenuType::ENUM_END,"","");
PopupMenuLabel*equipmentLabel=NEW PopupMenuLabel(CHARACTER_MENU,{{labelX,labelY},{29,24}},slotNames[i],{0.5,1},ComponentAttr::SHADOW);
equipSlot<<=1;
characterMenuWindow->AddComponent("Equip Slot "+slotNames[i],equipmentSlot);
characterMenuWindow->AddComponent("Equip Label "+slotNames[i],equipmentLabel);
}
MenuComponent*statDisplayOutline=NEW MenuComponent(CHARACTER_MENU,{{245,36},{62,windowSize.y-37}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE);
const std::array<ItemAttribute,7>displayAttrs{
ItemAttribute::health,
ItemAttribute::attack,
ItemAttribute::defense,
ItemAttribute::moveSpdPct,
ItemAttribute::cdrPct,
ItemAttribute::critPct,
ItemAttribute::critDmgPct,
};
characterMenuWindow->AddComponent("Stat Display Outline",statDisplayOutline);
int yOffset=0;
for(ItemAttribute attribute:displayAttrs){
AttributeData data=ItemAttributable::GetDisplayInfo(attribute);
std::string attrStr=data.name+":\n ";
attrStr+=std::to_string(game->GetPlayer()->A(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);
yOffset+=20;
characterMenuWindow->AddComponent("Attribute "+data.name+" Label",attrLabel);
}
}

@ -1702,8 +1702,8 @@ void Crawler::ChangePlayerClass(Class cl){
player.reset(NEW Witch(player.get()));
}break;
}
player->hp=player->maxhp=DATA.GetProperty(player->GetClassName()+".BaseHealth").GetInt();
player->atk=DATA.GetProperty(player->GetClassName()+".BaseAtk").GetInt();
player->hp=player->A(ItemAttribute::health)=DATA.GetProperty(player->GetClassName()+".BaseHealth").GetInt();
player->A(ItemAttribute::attack)=DATA.GetProperty(player->GetClassName()+".BaseAtk").GetInt();
player->hpGrowthRate=float(DATA.GetProperty(player->GetClassName()+".HealthGrowthRate").GetReal());
player->atkGrowthRate=float(DATA.GetProperty(player->GetClassName()+".AtkGrowthRate").GetReal());
sig::Animation::SetupPlayerAnimations();

@ -131,7 +131,7 @@ void ItemInfo::InitializeItems(){
if(slot.size()>0){
for(std::string&s:slot){
if(!nameToEquipSlot.count(s))ERR("WARNING! Tried to add item "<<it.name<<" to slot "<<s<<" which doesn't exist!");
it.slot=it.slot|nameToEquipSlot[s];
it.slot|=nameToEquipSlot[s];
}
}
if(!ITEM_CATEGORIES.count(it.category)){

@ -109,6 +109,6 @@ public:
virtual void OnInventorySlotsUpdate(ITCategory cat);
std::string GetLabel();
std::string GetName();
void Enable(bool enabled);
virtual void Enable(bool enabled);
virtual void Cleanup();
};

@ -67,13 +67,13 @@ protected:
valid=!itemRef.IsBlank();
if(valid){
icon=itemRef.Decal();
if(hovered){
if(hovered&&itemDescriptionMenu!=MenuType::ENUM_END){
Component<MenuLabel>(itemDescriptionMenu,itemNameLabelName)->label=itemRef.Name();
Component<MenuLabel>(itemDescriptionMenu,itemDescriptionLabelName)->label=itemRef.Description();
}
}else{
icon=nullptr;
if(hovered){
if(hovered&&itemDescriptionMenu!=MenuType::ENUM_END){
Component<MenuLabel>(itemDescriptionMenu,itemNameLabelName)->label="";
Component<MenuLabel>(itemDescriptionMenu,itemDescriptionLabelName)->label="";
}

@ -76,11 +76,21 @@ Player::Player()
Player::Player(Player*player)
:pos(player->GetPos()),vel(player->GetVelocity()),iframe_time(player->iframe_time),lastReleasedMovementKey(DOWN),
facingDirection(DOWN),state(State::NORMAL){
player->copyTo(*this);
Initialize();
}
void Player::Initialize(){
Player::GROUND_SLAM_SPIN_TIME="Warrior.Ability 2.SpinTime"_F;
A(ItemAttribute::health)=hp;
A(ItemAttribute::defense)=0;
A(ItemAttribute::attack)="Warrior.BaseAtk"_I;
A(ItemAttribute::moveSpdPct)=100;
A(ItemAttribute::cdrPct)=0;
A(ItemAttribute::critPct)=0;
A(ItemAttribute::critDmgPct)=0;
A(ItemAttribute::healthPct)=0;
A(ItemAttribute::healthPctRecoveryPer6sec)=0;
}
bool Player::SetX(float x){
@ -169,7 +179,7 @@ int Player::GetHealth(){
}
int Player::GetMaxHealth(){
return maxhp;
return A(ItemAttribute::health);
}
int Player::GetMana(){
@ -181,15 +191,15 @@ int Player::GetMaxMana() {
}
int Player::GetAttack(){
float mod_atk=float(atk);
float mod_atk=float(A(ItemAttribute::attack));
for(Buff&b:GetBuffs(BuffType::ATTACK_UP)){
mod_atk+=atk*b.intensity;
mod_atk+=A(ItemAttribute::attack)*b.intensity;
}
return int(mod_atk);
}
float Player::GetMoveSpdMult(){
float mod_moveSpd=moveSpd;
float mod_moveSpd=A(ItemAttribute::moveSpdPct)/100.f;
for(Buff&b:GetBuffs(BuffType::SLOWDOWN)){
mod_moveSpd-=mod_moveSpd*b.intensity;
}
@ -779,7 +789,7 @@ void Player::SetIframes(float duration){
}
bool Player::Heal(int damage){
hp=std::clamp(hp+damage,0,maxhp);
hp=std::clamp(hp+damage,0,A(ItemAttribute::health));
if(damage>0){
DAMAGENUMBER_LIST.push_back(std::make_shared<DamageNumber>(GetPos(),damage,true,HEALTH_GAIN));
}

@ -47,6 +47,7 @@ All rights reserved.
#include "Key.h"
#include "Class.h"
#include "Item.h"
#include "AttributableStat.h"
#undef GetClassName
struct DamageNumber;
@ -58,7 +59,7 @@ struct CastInfo{
vf2d castPos;
};
struct Player{
struct Player:ItemAttributable{
friend class Crawler;
friend class sig::Animation;
friend struct Warrior;
@ -69,14 +70,12 @@ struct Player{
friend struct Witch;
friend class State_GameRun;
private:
int hp="Warrior.BaseHealth"_I,maxhp=hp;
int hp="Warrior.BaseHealth"_I;
int mana="Player.BaseMana"_I,maxmana=mana;
int atk="Warrior.BaseAtk"_I;
float hpGrowthRate="Warrior.HealthGrowthRate"_F;
float atkGrowthRate="Warrior.AtkGrowthRate"_F;
vf2d pos;
float z=0;
float moveSpd=1.0f;
float size=1.0f;
float spin_attack_timer=0;
float spin_spd=0;

@ -45,10 +45,13 @@ INCLUDE_game
class PopupMenuLabel:public MenuLabel{
private:
float scale;
vf2d scale;
public:
inline PopupMenuLabel(MenuType parent,geom2d::rect<float>rect,std::string label,float scale=1,ComponentAttr attributes=ComponentAttr::NONE)
:MenuLabel(parent,rect,label,int(scale),attributes),scale(scale){
:MenuLabel(parent,rect,label,1,attributes),scale({scale,scale}){
}
inline PopupMenuLabel(MenuType parent,geom2d::rect<float>rect,std::string label,vf2d scale={1,1},ComponentAttr attributes=ComponentAttr::NONE)
:MenuLabel(parent,rect,label,1,attributes),scale(scale){
}
protected:
virtual void inline Update(Crawler*game)override{
@ -58,8 +61,8 @@ protected:
virtual void inline DrawDecal(Crawler*game,vf2d parentPos,bool focused)override{
if(label.length()>0){
MenuLabel::DrawDecal(game,parentPos,focused);
std::string wrappedText=util::WrapText(game,label,int(rect.size.x-1),true,{scale,scale});
vf2d drawPos=Menu::menus.at(parentMenu)->pos+parentPos+rect.middle()-vf2d{game->GetTextSizeProp(wrappedText)}*float(scale)/2; //Assume centered.
std::string wrappedText=util::WrapText(game,label,int(rect.size.x-1),true,scale);
vf2d drawPos=Menu::menus.at(parentMenu)->pos+parentPos+rect.middle()-vf2d{game->GetTextSizeProp(wrappedText)}*scale/2; //Assume centered.
if(!centered){
drawPos=Menu::menus.at(parentMenu)->pos+vf2d{rect.pos.x+2,rect.middle().y-game->GetTextSizeProp(wrappedText).y/2}+parentPos; //We should at least vertically align here.
}
@ -73,9 +76,9 @@ protected:
game->DrawStringPropDecal(Menu::menus.at(parentMenu)->pos+rect.pos+parentPos+rect.size/2-game->GetTextSizeProp(label)/2,label);
}
if(shadow){
game->DrawShadowStringPropDecal(drawPos,wrappedText,WHITE,BLACK,{scale,scale});
game->DrawShadowStringPropDecal(drawPos,wrappedText,WHITE,BLACK,scale);
}else{
game->DrawStringPropDecal(drawPos,wrappedText,WHITE,{scale,scale});
game->DrawStringPropDecal(drawPos,wrappedText,WHITE,scale);
}
}
}

@ -64,9 +64,6 @@ public:
background=attributes&ComponentAttr::BACKGROUND;
border=attributes&ComponentAttr::OUTLINE;
r.Create(uint32_t(rect.size.x),uint32_t(rect.size.y));
}
protected:
virtual inline void AfterCreate()override{
upButton=NEW MenuComponent(parentMenu,{rect.pos+vf2d{rect.size.x-12,0},{12,12}},"^",[&](MenuFuncData dat){V(A::SCROLL_OFFSET).y+="ThemeGlobal.MenuButtonScrollSpeed"_I;return true;},ButtonAttr::UNSELECTABLE_VIA_KEYBOARD);
downButton=NEW MenuComponent(parentMenu,{rect.pos+rect.size-vf2d{12,12},{12,12}},"v",[&](MenuFuncData dat){V(A::SCROLL_OFFSET).y-="ThemeGlobal.MenuButtonScrollSpeed"_I;return true;},ButtonAttr::UNSELECTABLE_VIA_KEYBOARD);
//Let's use the internal name of this component to add unique names for sub-components.
@ -236,4 +233,9 @@ public:
inline std::vector<MenuComponent*>&GetComponents(){
return components;
}
virtual inline void Enable(bool enabled)override final{
disabled=!enabled;
upButton->Enable(enabled);
downButton->Enable(enabled);
};
};

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 0
#define VERSION_MINOR 2
#define VERSION_PATCH 1
#define VERSION_BUILD 3365
#define VERSION_BUILD 3441
#define stringify(a) stringify_(a)
#define stringify_(a) #a

Loading…
Cancel
Save