Add unequip hotkey to character equipment menu. Implemented mouse inputs displaying on input helper when mouse navigation is used. Release Build 7465.
This commit is contained in:
parent
e2cc0aa90c
commit
63f7062841
@ -136,6 +136,7 @@ InputGroup AiL::KEY_SCROLLVERT_L;
|
|||||||
InputGroup AiL::KEY_SCROLL;
|
InputGroup AiL::KEY_SCROLL;
|
||||||
InputGroup AiL::KEY_SHOULDER;
|
InputGroup AiL::KEY_SHOULDER;
|
||||||
InputGroup AiL::KEY_CHANGE_LOADOUT;
|
InputGroup AiL::KEY_CHANGE_LOADOUT;
|
||||||
|
InputGroup AiL::KEY_MOUSE_RIGHT;
|
||||||
|
|
||||||
#ifndef __EMSCRIPTEN__
|
#ifndef __EMSCRIPTEN__
|
||||||
::discord::Core*Discord{};
|
::discord::Core*Discord{};
|
||||||
@ -2607,6 +2608,8 @@ void AiL::InitializeDefaultKeybinds(){
|
|||||||
KEY_UNEQUIP.AddKeybind({KEY,R});
|
KEY_UNEQUIP.AddKeybind({KEY,R});
|
||||||
KEY_UNEQUIP.AddKeybind({CONTROLLER,static_cast<int>(GPButtons::FACE_U)});
|
KEY_UNEQUIP.AddKeybind({CONTROLLER,static_cast<int>(GPButtons::FACE_U)});
|
||||||
|
|
||||||
|
KEY_MOUSE_RIGHT.AddKeybind({MOUSE,Mouse::RIGHT});
|
||||||
|
|
||||||
#define TieMenuNameToMenuInputGroup(KEY_NAME) \
|
#define TieMenuNameToMenuInputGroup(KEY_NAME) \
|
||||||
InputGroup::menuNamesToInputGroups[DATA["Inputs"][#KEY_NAME].GetString()]=&KEY_NAME; \
|
InputGroup::menuNamesToInputGroups[DATA["Inputs"][#KEY_NAME].GetString()]=&KEY_NAME; \
|
||||||
InputGroup::menuInputGroups.push_back(DATA["Inputs"][#KEY_NAME].GetString());
|
InputGroup::menuInputGroups.push_back(DATA["Inputs"][#KEY_NAME].GetString());
|
||||||
|
@ -108,6 +108,8 @@ public:
|
|||||||
static InputGroup KEY_CHANGE_LOADOUT;
|
static InputGroup KEY_CHANGE_LOADOUT;
|
||||||
static InputGroup KEY_ENTER;
|
static InputGroup KEY_ENTER;
|
||||||
|
|
||||||
|
static InputGroup KEY_MOUSE_RIGHT;
|
||||||
|
|
||||||
static float SIZE_CHANGE_SPEED;
|
static float SIZE_CHANGE_SPEED;
|
||||||
double levelTime;
|
double levelTime;
|
||||||
Camera2D camera;
|
Camera2D camera;
|
||||||
|
@ -305,7 +305,7 @@ void Menu::InitializeCharacterMenuWindow(){
|
|||||||
yOffset+=20;
|
yOffset+=20;
|
||||||
}
|
}
|
||||||
|
|
||||||
characterMenuWindow->ADD("Back button",MenuComponent)(geom2d::rect<float>{{windowSize.x/2-64,windowSize.y},{128,12}},"Back",[](MenuFuncData data){Menu::stack.pop_back();return true;})END;
|
characterMenuWindow->ADD("Back button",MenuComponent)(geom2d::rect<float>{{windowSize.x/2-64,windowSize.y-4.f},{128,12}},"Back",[](MenuFuncData data){Menu::stack.pop_back();return true;})END;
|
||||||
|
|
||||||
auto itemNameDisplay=characterMenuWindow->ADD("Item Name",MenuLabel)(geom2d::rect<float>{{0,28},{120,12}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW|ComponentAttr::FIT_TO_LABEL)END;
|
auto itemNameDisplay=characterMenuWindow->ADD("Item Name",MenuLabel)(geom2d::rect<float>{{0,28},{120,12}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW|ComponentAttr::FIT_TO_LABEL)END;
|
||||||
auto itemDescriptionDisplay=characterMenuWindow->ADD("Item Description",MenuLabel)(geom2d::rect<float>{{0,40},{120,windowSize.y-49}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW)END;
|
auto itemDescriptionDisplay=characterMenuWindow->ADD("Item Description",MenuLabel)(geom2d::rect<float>{{0,40},{120,windowSize.y-49}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW)END;
|
||||||
@ -324,6 +324,40 @@ void Menu::InitializeCharacterMenuWindow(){
|
|||||||
{ //Button Key
|
{ //Button Key
|
||||||
{{game->KEY_SHOULDER,Pressed},{"Scroll",[](MenuType type){}}},
|
{{game->KEY_SHOULDER,Pressed},{"Scroll",[](MenuType type){}}},
|
||||||
{{game->KEY_SCROLL,Analog},{"Scroll",[](MenuType type){}}},
|
{{game->KEY_SCROLL,Analog},{"Scroll",[](MenuType type){}}},
|
||||||
|
{{game->KEY_MOUSE_RIGHT,Pressed},{[](MenuFuncData data){
|
||||||
|
if(!data.menu.GetSelection().expired()&&
|
||||||
|
data.menu.GetSelection().lock()->GetName().starts_with("Equip Slot ")){
|
||||||
|
if(!ISBLANK(Inventory::GetEquip(EquipSlot(data.menu.GetSelection().lock()->I(Attribute::EQUIP_TYPE))))){
|
||||||
|
return "Unequip";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
},[](MenuType type){
|
||||||
|
if(!Menu::menus[type]->GetSelection().expired()&&
|
||||||
|
Menu::menus[type]->GetSelection().lock()->GetName().starts_with("Equip Slot ")){
|
||||||
|
if(!ISBLANK(Inventory::GetEquip(EquipSlot(Menu::menus[type]->GetSelection().lock()->I(Attribute::EQUIP_TYPE))))){
|
||||||
|
Inventory::UnequipItem(EquipSlot(Menu::menus[type]->GetSelection().lock()->I(Attribute::EQUIP_TYPE)));
|
||||||
|
SoundEffect::PlaySFX("Unequip Armor",SoundEffect::CENTERED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}},
|
||||||
|
{{game->KEY_FACELEFT,Pressed},{[](MenuFuncData data){
|
||||||
|
if(!data.menu.GetSelection().expired()&&
|
||||||
|
data.menu.GetSelection().lock()->GetName().starts_with("Equip Slot ")){
|
||||||
|
if(!ISBLANK(Inventory::GetEquip(EquipSlot(data.menu.GetSelection().lock()->I(Attribute::EQUIP_TYPE))))){
|
||||||
|
return "Unequip";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
},[](MenuType type){
|
||||||
|
if(!Menu::menus[type]->GetSelection().expired()&&
|
||||||
|
Menu::menus[type]->GetSelection().lock()->GetName().starts_with("Equip Slot ")){
|
||||||
|
if(!ISBLANK(Inventory::GetEquip(EquipSlot(Menu::menus[type]->GetSelection().lock()->I(Attribute::EQUIP_TYPE))))){
|
||||||
|
Inventory::UnequipItem(EquipSlot(Menu::menus[type]->GetSelection().lock()->I(Attribute::EQUIP_TYPE)));
|
||||||
|
SoundEffect::PlaySFX("Unequip Armor",SoundEffect::CENTERED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}},
|
||||||
{game->KEY_BACK,{"Back",[](MenuType type){
|
{game->KEY_BACK,{"Back",[](MenuType type){
|
||||||
if(!Menu::menus[type]->GetSelection().expired()&&
|
if(!Menu::menus[type]->GetSelection().expired()&&
|
||||||
!Menu::menus[type]->GetSelection().lock()->parentComponent.expired()&&
|
!Menu::menus[type]->GetSelection().lock()->parentComponent.expired()&&
|
||||||
|
@ -49,17 +49,7 @@ InputHelper::InputHelper(){}
|
|||||||
|
|
||||||
void InputHelper::Initialize(MenuInputGroups&inputGroups){
|
void InputHelper::Initialize(MenuInputGroups&inputGroups){
|
||||||
this->inputGroups.clear();
|
this->inputGroups.clear();
|
||||||
for(auto&data:inputGroups){
|
groupData=inputGroups;
|
||||||
if(data.first.GetLabelVisible()){ //If the label is not visible, we don't care to include it in our list.
|
|
||||||
if(std::holds_alternative<ButtonName>(data.second.first)){
|
|
||||||
const ButtonName&name=std::get<ButtonName>(data.second.first);
|
|
||||||
groupedInputs[name].push_back(data.first.GetGroup());
|
|
||||||
|
|
||||||
if(groupedInputs[name].size()>1)continue; //Skip adding to the list of input groups because this input already has been added.
|
|
||||||
}
|
|
||||||
this->inputGroups[data.first.GetGroup()]=data.second.first;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const InputType InputHelper::InputMode()const{
|
const InputType InputHelper::InputMode()const{
|
||||||
@ -79,32 +69,73 @@ void InputHelper::Draw(){
|
|||||||
std::vector<std::vector<std::variant<Decal*,std::string>>>buttonImgs; //Store decals for buttons that actually have images, and strings for buttons that have labels. One button can have multiple icons. Store them all together.
|
std::vector<std::vector<std::variant<Decal*,std::string>>>buttonImgs; //Store decals for buttons that actually have images, and strings for buttons that have labels. One button can have multiple icons. Store them all together.
|
||||||
std::vector<std::string>buttonDescriptions;
|
std::vector<std::string>buttonDescriptions;
|
||||||
#pragma region Populate all buttons to display
|
#pragma region Populate all buttons to display
|
||||||
|
inputGroups.clear();
|
||||||
|
groupedInputs.clear();
|
||||||
|
for(auto&data:groupData){
|
||||||
|
if(data.first.GetLabelVisible()){ //If the label is not visible, we don't care to include it in our list.
|
||||||
|
if(std::holds_alternative<ButtonName>(data.second.first)){
|
||||||
|
const ButtonName&name=std::get<ButtonName>(data.second.first);
|
||||||
|
groupedInputs[name].push_back(data.first.GetGroup());
|
||||||
|
|
||||||
|
if(groupedInputs[name].size()>1)continue; //Skip adding to the list of input groups because this input already has been added.
|
||||||
|
}else
|
||||||
|
if(std::holds_alternative<std::function<std::string(MenuFuncData)>>(data.second.first)){
|
||||||
|
std::weak_ptr<ScrollableWindowComponent>parentComponent;
|
||||||
|
if(!Menu::stack.back()->GetSelection().expired()){
|
||||||
|
parentComponent=Menu::stack.back()->GetSelection().lock()->parentComponent;
|
||||||
|
}
|
||||||
|
std::string name=std::get<std::function<std::string(MenuFuncData)>>(data.second.first)(MenuFuncData{*Menu::stack.back(),game,Menu::stack.back()->GetSelection(),parentComponent});
|
||||||
|
groupedInputs[name].push_back(data.first.GetGroup());
|
||||||
|
|
||||||
|
if(groupedInputs[name].size()>1)continue; //Skip adding to the list of input groups because this input already has been added.
|
||||||
|
}
|
||||||
|
this->inputGroups[data.first.GetGroup()]=data.second.first;
|
||||||
|
}
|
||||||
|
}
|
||||||
for(auto&[group,display]:inputGroups){
|
for(auto&[group,display]:inputGroups){
|
||||||
size_t groupedInputCount=1;
|
std::weak_ptr<ScrollableWindowComponent>parentComponent;
|
||||||
std::vector<InputGroup>inputGroupsToCheck;
|
if(!Menu::stack.back()->GetSelection().expired()){
|
||||||
if(std::holds_alternative<std::string>(display)&&groupedInputs.count(std::get<std::string>(display))){
|
parentComponent=Menu::stack.back()->GetSelection().lock()->parentComponent;
|
||||||
inputGroupsToCheck=groupedInputs.at(std::get<std::string>(display));
|
|
||||||
}else{
|
|
||||||
inputGroupsToCheck.push_back(group);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<InputGroup>inputGroupsToCheck;
|
||||||
std::string displayName;
|
std::string displayName;
|
||||||
|
|
||||||
if(std::holds_alternative<std::string>(display))displayName=std::get<std::string>(display);
|
if(std::holds_alternative<std::string>(display))displayName=std::get<std::string>(display);
|
||||||
else
|
else
|
||||||
if(std::holds_alternative<std::function<std::string(MenuFuncData)>>(display)){
|
if(std::holds_alternative<std::function<std::string(MenuFuncData)>>(display)){
|
||||||
std::weak_ptr<ScrollableWindowComponent>parentComponent;
|
|
||||||
if(!Menu::stack.back()->GetSelection().expired()){
|
|
||||||
parentComponent=Menu::stack.back()->GetSelection().lock()->parentComponent;
|
|
||||||
}
|
|
||||||
displayName=std::get<std::function<std::string(MenuFuncData)>>(display)(MenuFuncData{*Menu::stack.back(),game,Menu::stack.back()->GetSelection(),parentComponent});
|
displayName=std::get<std::function<std::string(MenuFuncData)>>(display)(MenuFuncData{*Menu::stack.back(),game,Menu::stack.back()->GetSelection(),parentComponent});
|
||||||
}
|
}
|
||||||
else ERR("WARNING! display contains a variant alternative that does not exist. THIS SHOULD NOT BE HAPPENING!");
|
else ERR("WARNING! display contains a variant alternative that does not exist. THIS SHOULD NOT BE HAPPENING!");
|
||||||
|
|
||||||
|
if(groupedInputs.count(displayName)){
|
||||||
|
inputGroupsToCheck=groupedInputs.at(displayName);
|
||||||
|
}else{
|
||||||
|
inputGroupsToCheck.push_back(group);
|
||||||
|
}
|
||||||
|
|
||||||
buttonImgs.push_back({});
|
buttonImgs.push_back({});
|
||||||
std::vector<std::variant<Decal*,std::string>>&iconList=buttonImgs.back();
|
std::vector<std::variant<Decal*,std::string>>&iconList=buttonImgs.back();
|
||||||
|
|
||||||
for(InputGroup&group:inputGroupsToCheck){
|
for(InputGroup&group:inputGroupsToCheck){
|
||||||
|
if(Menu::UsingMouseNavigation()){
|
||||||
|
auto&primaryKey=group.GetPrimaryKey(MOUSE);
|
||||||
|
|
||||||
|
if(displayName.length()>0&&primaryKey.has_value()){
|
||||||
|
if(primaryKey.value().HasExtendedIcons()){//This means it follows the specialized icon controller schemes, now pick based on these icons.
|
||||||
|
buttonImgWidth+=primaryKey.value().GetIcon(GameSettings::GetIconType()).Sprite()->width+"Interface.InputHelperSpacing"_I;
|
||||||
|
iconList.push_back(primaryKey.value().GetIcon(GameSettings::GetIconType()).Decal());
|
||||||
|
}else
|
||||||
|
if(primaryKey.value().HasIcon()){
|
||||||
|
buttonImgWidth+=primaryKey.value().GetIcon().Sprite()->width+"Interface.InputHelperSpacing"_I;
|
||||||
|
iconList.push_back(primaryKey.value().GetIcon().Decal());
|
||||||
|
}else{
|
||||||
|
buttonImgWidth+=game->GetTextSizeProp(primaryKey.value().GetDisplayName()).x+"Interface.InputHelperSpacing"_I;
|
||||||
|
iconList.push_back(primaryKey.value().GetDisplayName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto&primaryKey=group.GetPrimaryKey(mode);
|
auto&primaryKey=group.GetPrimaryKey(mode);
|
||||||
|
|
||||||
if(displayName.length()>0&&primaryKey.has_value()){
|
if(displayName.length()>0&&primaryKey.has_value()){
|
||||||
|
@ -46,6 +46,7 @@ All rights reserved.
|
|||||||
class InputHelper{
|
class InputHelper{
|
||||||
std::map<InputGroup,InputGroupActionDisplayName>inputGroups;
|
std::map<InputGroup,InputGroupActionDisplayName>inputGroups;
|
||||||
std::map<ButtonName,std::vector<InputGroup>>groupedInputs;
|
std::map<ButtonName,std::vector<InputGroup>>groupedInputs;
|
||||||
|
MenuInputGroups groupData;
|
||||||
|
|
||||||
const InputType InputMode()const;
|
const InputType InputMode()const;
|
||||||
|
|
||||||
|
@ -328,7 +328,6 @@ void Menu::KeyboardButtonNavigation(AiL*game,vf2d menuPos){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!Menu::UsingMouseNavigation()){
|
|
||||||
for(auto&[input,data]:inputGroups){
|
for(auto&[input,data]:inputGroups){
|
||||||
if(Menu::alreadyClicked)break;
|
if(Menu::alreadyClicked)break;
|
||||||
bool activated=false;
|
bool activated=false;
|
||||||
@ -361,7 +360,7 @@ void Menu::KeyboardButtonNavigation(AiL*game,vf2d menuPos){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if(!selection.expired()){
|
if(!selection.expired()){
|
||||||
const int MAX_ITERATIONS=10; //Skip a maximum amount of items in case everything gets disabled somehow, prevents an infinite loop.
|
const int MAX_ITERATIONS=10; //Skip a maximum amount of items in case everything gets disabled somehow, prevents an infinite loop.
|
||||||
int iterationCount=0;
|
int iterationCount=0;
|
||||||
|
@ -145,7 +145,7 @@ bool Monster::_SetX(float x,const bool monsterInvoked){
|
|||||||
vf2d newPos={x,pos.y};
|
vf2d newPos={x,pos.y};
|
||||||
vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth;
|
vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth;
|
||||||
geom2d::rect<float>collisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel);
|
geom2d::rect<float>collisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel);
|
||||||
if(isBoss||collisionRect==game->NO_COLLISION){
|
if(collisionRect==game->NO_COLLISION){
|
||||||
pos.x=std::clamp(x,game->GetCurrentMapData().tilewidth/2.f*GetSizeMult(),float(game->GetCurrentMapData().width*game->GetCurrentMapData().tilewidth-game->GetCurrentMapData().tilewidth/2.f*GetSizeMult()));
|
pos.x=std::clamp(x,game->GetCurrentMapData().tilewidth/2.f*GetSizeMult(),float(game->GetCurrentMapData().width*game->GetCurrentMapData().tilewidth-game->GetCurrentMapData().tilewidth/2.f*GetSizeMult()));
|
||||||
Moved();
|
Moved();
|
||||||
return true;
|
return true;
|
||||||
@ -175,7 +175,7 @@ bool Monster::_SetY(float y,const bool monsterInvoked){
|
|||||||
vf2d newPos={pos.x,y};
|
vf2d newPos={pos.x,y};
|
||||||
vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth;
|
vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth;
|
||||||
geom2d::rect<float>collisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel);
|
geom2d::rect<float>collisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel);
|
||||||
if(isBoss||collisionRect==game->NO_COLLISION){
|
if(collisionRect==game->NO_COLLISION){
|
||||||
pos.y=std::clamp(y,game->GetCurrentMapData().tilewidth/2.f*GetSizeMult(),float(game->GetCurrentMapData().height*game->GetCurrentMapData().tilewidth-game->GetCurrentMapData().tilewidth/2.f*GetSizeMult()));
|
pos.y=std::clamp(y,game->GetCurrentMapData().tilewidth/2.f*GetSizeMult(),float(game->GetCurrentMapData().height*game->GetCurrentMapData().tilewidth-game->GetCurrentMapData().tilewidth/2.f*GetSizeMult()));
|
||||||
Moved();
|
Moved();
|
||||||
return true;
|
return true;
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
January 1st
|
January 1st
|
||||||
===========
|
===========
|
||||||
- Clamp bosses in boss arenas.
|
|
||||||
|
|
||||||
- Track items used during a stage, on death, restore the loadout item quantities used.
|
- Track items used during a stage, on death, restore the loadout item quantities used.
|
||||||
|
|
||||||
Add Bonus XP when completing a stage
|
Add Bonus XP when completing a stage
|
||||||
@ -24,3 +22,5 @@ January 31st
|
|||||||
- Auto aim causes retreat-type moves to aim away from the auto target, and prefer the direction the player's moving in.
|
- Auto aim causes retreat-type moves to aim away from the auto target, and prefer the direction the player's moving in.
|
||||||
|
|
||||||
- Condense stage track (loading times)
|
- Condense stage track (loading times)
|
||||||
|
|
||||||
|
- Credits/Licensing
|
@ -39,7 +39,7 @@ All rights reserved.
|
|||||||
#define VERSION_MAJOR 0
|
#define VERSION_MAJOR 0
|
||||||
#define VERSION_MINOR 3
|
#define VERSION_MINOR 3
|
||||||
#define VERSION_PATCH 0
|
#define VERSION_PATCH 0
|
||||||
#define VERSION_BUILD 7447
|
#define VERSION_BUILD 7465
|
||||||
|
|
||||||
#define stringify(a) stringify_(a)
|
#define stringify(a) stringify_(a)
|
||||||
#define stringify_(a) #a
|
#define stringify_(a) #a
|
||||||
|
@ -191,6 +191,11 @@ Events
|
|||||||
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
|
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
|
||||||
File[0] = toggle_off.ogg, 100%
|
File[0] = toggle_off.ogg, 100%
|
||||||
}
|
}
|
||||||
|
Unequip Armor
|
||||||
|
{
|
||||||
|
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
|
||||||
|
File[0] = equip2.ogg, 60%
|
||||||
|
}
|
||||||
Ursule Dead
|
Ursule Dead
|
||||||
{
|
{
|
||||||
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
|
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
|
||||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user