diff --git a/Adventures in Lestoria/AdventuresInLestoria.cpp b/Adventures in Lestoria/AdventuresInLestoria.cpp index cd7a96cf..531a552b 100644 --- a/Adventures in Lestoria/AdventuresInLestoria.cpp +++ b/Adventures in Lestoria/AdventuresInLestoria.cpp @@ -136,6 +136,7 @@ InputGroup AiL::KEY_SCROLLVERT_L; InputGroup AiL::KEY_SCROLL; InputGroup AiL::KEY_SHOULDER; InputGroup AiL::KEY_CHANGE_LOADOUT; +InputGroup AiL::KEY_MOUSE_RIGHT; #ifndef __EMSCRIPTEN__ ::discord::Core*Discord{}; @@ -2607,6 +2608,8 @@ void AiL::InitializeDefaultKeybinds(){ KEY_UNEQUIP.AddKeybind({KEY,R}); KEY_UNEQUIP.AddKeybind({CONTROLLER,static_cast(GPButtons::FACE_U)}); + KEY_MOUSE_RIGHT.AddKeybind({MOUSE,Mouse::RIGHT}); + #define TieMenuNameToMenuInputGroup(KEY_NAME) \ InputGroup::menuNamesToInputGroups[DATA["Inputs"][#KEY_NAME].GetString()]=&KEY_NAME; \ InputGroup::menuInputGroups.push_back(DATA["Inputs"][#KEY_NAME].GetString()); diff --git a/Adventures in Lestoria/AdventuresInLestoria.h b/Adventures in Lestoria/AdventuresInLestoria.h index 77c285e6..d8d54cc3 100644 --- a/Adventures in Lestoria/AdventuresInLestoria.h +++ b/Adventures in Lestoria/AdventuresInLestoria.h @@ -108,6 +108,8 @@ public: static InputGroup KEY_CHANGE_LOADOUT; static InputGroup KEY_ENTER; + static InputGroup KEY_MOUSE_RIGHT; + static float SIZE_CHANGE_SPEED; double levelTime; Camera2D camera; diff --git a/Adventures in Lestoria/CharacterMenuWindow.cpp b/Adventures in Lestoria/CharacterMenuWindow.cpp index ef93c1b4..7c04b04e 100644 --- a/Adventures in Lestoria/CharacterMenuWindow.cpp +++ b/Adventures in Lestoria/CharacterMenuWindow.cpp @@ -305,7 +305,7 @@ void Menu::InitializeCharacterMenuWindow(){ yOffset+=20; } - characterMenuWindow->ADD("Back button",MenuComponent)(geom2d::rect{{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{{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{{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{{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 {{game->KEY_SHOULDER,Pressed},{"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){ if(!Menu::menus[type]->GetSelection().expired()&& !Menu::menus[type]->GetSelection().lock()->parentComponent.expired()&& diff --git a/Adventures in Lestoria/InputHelper.cpp b/Adventures in Lestoria/InputHelper.cpp index d78e9ae1..8081deeb 100644 --- a/Adventures in Lestoria/InputHelper.cpp +++ b/Adventures in Lestoria/InputHelper.cpp @@ -49,17 +49,7 @@ InputHelper::InputHelper(){} void InputHelper::Initialize(MenuInputGroups&inputGroups){ this->inputGroups.clear(); - for(auto&data: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(data.second.first)){ - const ButtonName&name=std::get(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; - } - } + groupData=inputGroups; } const InputType InputHelper::InputMode()const{ @@ -79,32 +69,73 @@ void InputHelper::Draw(){ std::vector>>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::vectorbuttonDescriptions; #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(data.second.first)){ + const ButtonName&name=std::get(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>(data.second.first)){ + std::weak_ptrparentComponent; + if(!Menu::stack.back()->GetSelection().expired()){ + parentComponent=Menu::stack.back()->GetSelection().lock()->parentComponent; + } + std::string name=std::get>(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){ - size_t groupedInputCount=1; - std::vectorinputGroupsToCheck; - if(std::holds_alternative(display)&&groupedInputs.count(std::get(display))){ - inputGroupsToCheck=groupedInputs.at(std::get(display)); - }else{ - inputGroupsToCheck.push_back(group); + std::weak_ptrparentComponent; + if(!Menu::stack.back()->GetSelection().expired()){ + parentComponent=Menu::stack.back()->GetSelection().lock()->parentComponent; } + std::vectorinputGroupsToCheck; std::string displayName; if(std::holds_alternative(display))displayName=std::get(display); else if(std::holds_alternative>(display)){ - std::weak_ptrparentComponent; - if(!Menu::stack.back()->GetSelection().expired()){ - parentComponent=Menu::stack.back()->GetSelection().lock()->parentComponent; - } displayName=std::get>(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!"); + + if(groupedInputs.count(displayName)){ + inputGroupsToCheck=groupedInputs.at(displayName); + }else{ + inputGroupsToCheck.push_back(group); + } buttonImgs.push_back({}); std::vector>&iconList=buttonImgs.back(); 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); if(displayName.length()>0&&primaryKey.has_value()){ diff --git a/Adventures in Lestoria/InputHelper.h b/Adventures in Lestoria/InputHelper.h index 8e08801b..e7fb1106 100644 --- a/Adventures in Lestoria/InputHelper.h +++ b/Adventures in Lestoria/InputHelper.h @@ -46,6 +46,7 @@ All rights reserved. class InputHelper{ std::mapinputGroups; std::map>groupedInputs; + MenuInputGroups groupData; const InputType InputMode()const; diff --git a/Adventures in Lestoria/Menu.cpp b/Adventures in Lestoria/Menu.cpp index a00ff3a2..c87342d1 100644 --- a/Adventures in Lestoria/Menu.cpp +++ b/Adventures in Lestoria/Menu.cpp @@ -328,40 +328,39 @@ void Menu::KeyboardButtonNavigation(AiL*game,vf2d menuPos){ } } - if(!Menu::UsingMouseNavigation()){ - for(auto&[input,data]:inputGroups){ - if(Menu::alreadyClicked)break; - bool activated=false; - switch(input.GetEngageType()){ - case Released:{ - activated=input.GetGroup().Released(); - }break; - case Pressed:{ - activated=input.GetGroup().Pressed(); - }break; - case PressedDAS:{ - activated=input.GetGroup().PressedDAS(); - }break; - case Held:{ - activated=input.GetGroup().Held(); - }break; - case Analog:{ - activated=input.GetGroup().Analog()!=0.f; - }break; - [[unlikely]]default:ERR(std::format("WARNING! Unhandled input engage type {}! THIS SHOULD NOT BE HAPPENING!",int(input.GetEngageType()))); - } + for(auto&[input,data]:inputGroups){ + if(Menu::alreadyClicked)break; + bool activated=false; + switch(input.GetEngageType()){ + case Released:{ + activated=input.GetGroup().Released(); + }break; + case Pressed:{ + activated=input.GetGroup().Pressed(); + }break; + case PressedDAS:{ + activated=input.GetGroup().PressedDAS(); + }break; + case Held:{ + activated=input.GetGroup().Held(); + }break; + case Analog:{ + activated=input.GetGroup().Analog()!=0.f; + }break; + [[unlikely]]default:ERR(std::format("WARNING! Unhandled input engage type {}! THIS SHOULD NOT BE HAPPENING!",int(input.GetEngageType()))); + } - if(activated){ - auto&action=data.second; - if(std::holds_alternative(action))Component(type,std::get(action))->Click(); - else - if(std::holds_alternative>(action))std::get>(action)(type); - else{ - ERR("WARNING! Navigation data has an unrecognized type or is empty! This should not be happening!") - } + if(activated){ + auto&action=data.second; + if(std::holds_alternative(action))Component(type,std::get(action))->Click(); + else + if(std::holds_alternative>(action))std::get>(action)(type); + else{ + ERR("WARNING! Navigation data has an unrecognized type or is empty! This should not be happening!") } } } + if(!selection.expired()){ const int MAX_ITERATIONS=10; //Skip a maximum amount of items in case everything gets disabled somehow, prevents an infinite loop. int iterationCount=0; diff --git a/Adventures in Lestoria/Monster.cpp b/Adventures in Lestoria/Monster.cpp index 06fadbf5..7b363461 100644 --- a/Adventures in Lestoria/Monster.cpp +++ b/Adventures in Lestoria/Monster.cpp @@ -145,7 +145,7 @@ bool Monster::_SetX(float x,const bool monsterInvoked){ vf2d newPos={x,pos.y}; vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth; geom2d::rectcollisionRect=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())); Moved(); return true; @@ -175,7 +175,7 @@ bool Monster::_SetY(float y,const bool monsterInvoked){ vf2d newPos={pos.x,y}; vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth; geom2d::rectcollisionRect=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())); Moved(); return true; diff --git a/Adventures in Lestoria/TODO.txt b/Adventures in Lestoria/TODO.txt index 533bb6a7..be3795a2 100644 --- a/Adventures in Lestoria/TODO.txt +++ b/Adventures in Lestoria/TODO.txt @@ -1,7 +1,5 @@ January 1st =========== -- Clamp bosses in boss arenas. - - Track items used during a stage, on death, restore the loadout item quantities used. Add Bonus XP when completing a stage @@ -23,4 +21,6 @@ January 31st - 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) \ No newline at end of file +- Condense stage track (loading times) + +- Credits/Licensing \ No newline at end of file diff --git a/Adventures in Lestoria/Version.h b/Adventures in Lestoria/Version.h index 93ae82b5..822ea06a 100644 --- a/Adventures in Lestoria/Version.h +++ b/Adventures in Lestoria/Version.h @@ -39,7 +39,7 @@ All rights reserved. #define VERSION_MAJOR 0 #define VERSION_MINOR 3 #define VERSION_PATCH 0 -#define VERSION_BUILD 7447 +#define VERSION_BUILD 7465 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Adventures in Lestoria/assets/config/audio/events.txt b/Adventures in Lestoria/assets/config/audio/events.txt index 052da250..708de2d5 100644 --- a/Adventures in Lestoria/assets/config/audio/events.txt +++ b/Adventures in Lestoria/assets/config/audio/events.txt @@ -191,6 +191,11 @@ Events # Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%) 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 { # Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%) diff --git a/x64/Release/Adventures in Lestoria.exe b/x64/Release/Adventures in Lestoria.exe index ed601a22..e558b914 100644 Binary files a/x64/Release/Adventures in Lestoria.exe and b/x64/Release/Adventures in Lestoria.exe differ