diff --git a/Adventures in Lestoria/Adventures in Lestoria.vcxproj b/Adventures in Lestoria/Adventures in Lestoria.vcxproj index 936e6179..235b12f9 100644 --- a/Adventures in Lestoria/Adventures in Lestoria.vcxproj +++ b/Adventures in Lestoria/Adventures in Lestoria.vcxproj @@ -521,6 +521,10 @@ + + + + diff --git a/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters b/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters index 050e266e..9dbc9295 100644 --- a/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters +++ b/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters @@ -693,6 +693,9 @@ Header Files + + Header Files\Interface + diff --git a/Adventures in Lestoria/AdventuresInLestoria.cpp b/Adventures in Lestoria/AdventuresInLestoria.cpp index 10ce9607..554d86ed 100644 --- a/Adventures in Lestoria/AdventuresInLestoria.cpp +++ b/Adventures in Lestoria/AdventuresInLestoria.cpp @@ -427,8 +427,8 @@ bool AiL::OnConsoleCommand(const std::string& sCommand){ }else if(args[0]=="/give"){ if(args.size()<2)ConsoleOut()<<"Usage: /give [Amount]"<=3)itemAmt=std::stoi(args[2]); + uint32_t itemAmt{1}; + if(args.size()>=3)itemAmt=std::stoul(args[2]); Inventory::AddItem(args[1],itemAmt); ConsoleOut()<<"Added x"<GetScreenSize()-vi2d{52,52}); + + const auto ResetDisassemblyDisplay=[artificerDisassembleWindow](){ + MenuType menuType{artificerDisassembleWindow->GetType()}; + Component(menuType,"Down Arrow")->Disable(); + Component(menuType,"Disassembly Result")->Disable(); + Component(menuType,"Disassembly Result Title")->Disable(); + Component(menuType,"Fragment Total Count")->Disable(); + Component(menuType,"Disassemble Button")->Disable(); + }; + const auto EnableDisassemblyDisplay=[artificerDisassembleWindow](){ + MenuType menuType{artificerDisassembleWindow->GetType()}; + Component(menuType,"Down Arrow")->Enable(); + Component(menuType,"Disassembly Result")->Enable(); + Component(menuType,"Disassembly Result Title")->Enable(); + Component(menuType,"Fragment Total Count")->Enable(); + Component(menuType,"Disassemble Button")->Enable(); + }; auto disassemblyTitleLabel{artificerDisassembleWindow->ADD("Disassembly Title Label",MenuLabel)(geom2d::rect{{},{artificerDisassembleWindow->size.x,24.f}},"Accessory Disassembly",2.f,ComponentAttr::SHADOW|ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND)END}; auto inventoryLabel=artificerDisassembleWindow->ADD("Accessory List Label",MenuLabel)(geom2d::rect{{0.f,28.f},{180.f,12.f}},"Choose Accessory:",1.f,ComponentAttr::SHADOW|ComponentAttr::LEFT_ALIGN)END; + auto itemIcon{artificerDisassembleWindow->ADD("Item Icon",MenuItemItemButton)(geom2d::rect({artificerDisassembleWindow->size.x/2+4.f,44.f},{48,48}),Item::BLANK,DO_NOTHING,"","Item Description",IconButtonAttr::NOT_SELECTABLE)END}; + itemIcon->SetIconScale({2.f,2.f}); + itemIcon->SetCompactDescriptions(true); + + auto accessoryDescription{artificerDisassembleWindow->ADD("Item Description",MenuLabel)(geom2d::rect{{artificerDisassembleWindow->size.x/2+56.f,44.f},{artificerDisassembleWindow->size.x/2-56.f,72.f}},"",0.5f,ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE|ComponentAttr::SHADOW|ComponentAttr::LEFT_ALIGN)END}; + + auto downArrow{artificerDisassembleWindow->ADD("Down Arrow",MenuDecal)(geom2d::rect{{artificerDisassembleWindow->size.x/2+4.f,92.f},{48,48}},GFX.at("downarrow.png"),DO_NOTHING,DO_NOTHING)END}; + + auto disassemblyResult{artificerDisassembleWindow->ADD("Disassembly Result",MenuIconButton)(geom2d::rect{{artificerDisassembleWindow->size.x/2+4.f,141.f},{48,48}},nullptr,DO_NOTHING,IconButtonAttr::NOT_SELECTABLE)END}; + + auto disassemblyResultTitle{artificerDisassembleWindow->ADD("Disassembly Result Title",MenuLabel)(geom2d::rect{{artificerDisassembleWindow->size.x/2+56.f,141.f},{artificerDisassembleWindow->size.x/2-56.f,24.f}},"",2.f,ComponentAttr::BACKGROUND|ComponentAttr::SHADOW|ComponentAttr::OUTLINE|ComponentAttr::FIT_TO_LABEL)END}; + + auto disassemblyTotalCount{artificerDisassembleWindow->ADD("Fragment Total Count",MenuLabel)(geom2d::rect{{artificerDisassembleWindow->size.x/2+56.f,127.f},{artificerDisassembleWindow->size.x/2-56.f,12.f}},"",0.85f,ComponentAttr::RIGHT_ALIGN|ComponentAttr::SHADOW|ComponentAttr::FIT_TO_LABEL)END}; + + auto disassembleButton{artificerDisassembleWindow->ADD("Disassemble Button",MenuComponent)(geom2d::rect{{artificerDisassembleWindow->size.x/2+72.f,171.f},{artificerDisassembleWindow->size.x/2-72.f,16.f}},"Disassemble",[ResetDisassemblyDisplay](MenuFuncData data){ + auto it{Component(data.menu.type,"Item Icon")->GetItem()}; + if(Inventory::Disassemble(it)==Inventory::DisassembleResult::SUCCESS){ + SoundEffect::PlaySFX("Disassemble Item",SoundEffect::CENTERED); + Component(data.menu.type,"Item Icon")->SetItem(Item::BLANK); + Component(data.menu.type,"Disassembly Result")->SetIcon(nullptr); + Component(data.menu.type,"Disassembly Result Title")->SetLabel(""); + Component(data.menu.type,"Fragment Total Count")->SetLabel(""); + ResetDisassemblyDisplay(); + }else{ + SoundEffect::PlaySFX("Locked Item",SoundEffect::CENTERED); + game->AddNotification(AiL::Notification{"Cannot disassemble locked accessory!",5.f,RED}); + } + return true; + })END}; + auto inventoryDisplay=artificerDisassembleWindow->ADD("Accessory List",RowInventoryScrollableWindowComponent)(geom2d::rect{{0.f,44.f},{artificerDisassembleWindow->size.x/2-4.f,artificerDisassembleWindow->size.y-60}},"","",[](MenuFuncData data){ + RowItemDisplay&item{*DYNAMIC_POINTER_CAST(data.component)}; + DYNAMIC_POINTER_CAST(data.parentComponent.lock())->SelectChild(DYNAMIC_POINTER_CAST(data.component)); return true; - },[](MenuFuncData data){ + },[EnableDisassemblyDisplay](MenuFuncData data){ + EnableDisassemblyDisplay(); RowItemDisplay&item{*DYNAMIC_POINTER_CAST(data.component)}; Component(data.menu.type,"Item Icon")->SetItem(item.GetItem().lock()); + Component(data.menu.type,"Disassembly Result")->SetIcon(GFX.at(item.GetItem().lock()->FragmentName()).Decal()); + Component(data.menu.type,"Disassembly Result Title")->SetLabel(item.GetItem().lock()->FragmentName()); + Component(data.menu.type,"Fragment Total Count")->SetLabel(std::format("Currently Owned: {}",Inventory::GetItemCount(item.GetItem().lock()->FragmentName()))); return true; - },DO_NOTHING, + },[ResetDisassemblyDisplay,EnableDisassemblyDisplay](MenuFuncData data){ + ResetDisassemblyDisplay(); + auto childComponent{DYNAMIC_POINTER_CAST(data.parentComponent.lock())->GetSelectedChild()}; + if(childComponent){ + RowItemDisplay&item{childComponent.value().get()}; + Component(data.menu.type,"Item Icon")->SetItem(item.GetItem().lock()); + Component(data.menu.type,"Disassembly Result")->SetIcon(GFX.at(item.GetItem().lock()->FragmentName()).Decal()); + Component(data.menu.type,"Disassembly Result Title")->SetLabel(item.GetItem().lock()->FragmentName()); + Component(data.menu.type,"Fragment Total Count")->SetLabel(std::format("Currently Owned: {}",Inventory::GetItemCount(item.GetItem().lock()->FragmentName()))); + EnableDisassemblyDisplay(); + } + return true; + }, InventoryCreator::RowPlayer_InventoryUpdate, InventoryWindowOptions{.padding=1,.size={artificerDisassembleWindow->size.x/2-5.f-12.f,28}})END; - auto itemIcon{artificerDisassembleWindow->ADD("Item Icon",MenuItemItemButton)(geom2d::rect({artificerDisassembleWindow->size.x/2+4.f,44.f},{48,48}),Item::BLANK,DO_NOTHING,"","Item Description",IconButtonAttr::NOT_SELECTABLE)END}; - itemIcon->SetIconScale({2.f,2.f}); - itemIcon->SetCompactDescriptions(true); - - auto accessoryDescription{artificerDisassembleWindow->ADD("Item Description",MenuLabel)(geom2d::rect({artificerDisassembleWindow->size.x/2+56.f,44.f},{artificerDisassembleWindow->size.x/2-56.f,72.f}),"",0.5f,ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE|ComponentAttr::SHADOW|ComponentAttr::LEFT_ALIGN)END}; - auto backButton=artificerDisassembleWindow->ADD("Back",MenuComponent)(geom2d::rect{{0.f,artificerDisassembleWindow->size.y-12.f},{96.f,16.f}},"Back",[](MenuFuncData data){ Menu::CloseMenu(); return true; diff --git a/Adventures in Lestoria/Crawler_Artificer.txt b/Adventures in Lestoria/Crawler_Artificer.txt index 9b25e9eb..283afe1d 100644 --- a/Adventures in Lestoria/Crawler_Artificer.txt +++ b/Adventures in Lestoria/Crawler_Artificer.txt @@ -36,7 +36,7 @@ Artificer has 4 Dialog Options -Enhancing Gear +Refining Gear - increases the stats of an item. - Increases a random stat by a random amount that did not reach its cap. (cant go higher then 20% of its current amount in on Enhance attempt and cant go higher then the max stat value of the item) - Costs 1 piece of the Ring you want to enhance + 20g diff --git a/Adventures in Lestoria/Item.cpp b/Adventures in Lestoria/Item.cpp index 3c5e9942..fad5d490 100644 --- a/Adventures in Lestoria/Item.cpp +++ b/Adventures in Lestoria/Item.cpp @@ -1414,12 +1414,14 @@ const EquipSlot ItemInfo::StringToEquipSlot(std::string_view slotName){ return nameToEquipSlot[std::string(slotName)]; } -void Inventory::Disassemble(std::weak_ptritemRef){ +[[nodiscard]]const Inventory::DisassembleResult Inventory::Disassemble(std::weak_ptritemRef){ if(ISBLANK(itemRef))ERR(std::format("WARNING! Trying to feed a blank item into the Disassemble function! THIS SHOULD NOT BE HAPPENING!")); const std::shared_ptr¤tItem{itemRef.lock()}; if(!currentItem->IsAccessory())ERR(std::format("WARNING! Trying to disassemble Item {} which is not an accessory! THIS SHOULD NOT BE HAPPENING!",currentItem->ActualName())); + if(currentItem->IsLocked())return DisassembleResult::FAILED; Inventory::RemoveItem(itemRef); Inventory::AddItem(currentItem->FragmentName(),"Fragment Disassemble Gain Amount"_I); + return DisassembleResult::SUCCESS; } const std::string&Item::FragmentName()const{ diff --git a/Adventures in Lestoria/Item.h b/Adventures in Lestoria/Item.h index a4cfac6c..6ca0117d 100644 --- a/Adventures in Lestoria/Item.h +++ b/Adventures in Lestoria/Item.h @@ -274,6 +274,12 @@ class Inventory{ friend class InventoryCreator; friend class ItemTests::ItemTest; public: + + enum class DisassembleResult{ + SUCCESS, + FAILED, //Failure is due to an item being locked. + }; + static std::weak_ptrAddItem(IT it,uint32_t amt=1,bool monsterDrop=false); //Returns the actual amount available in your main inventory. [[nodiscard]] static uint32_t GetItemCount(IT it); @@ -302,7 +308,7 @@ public: static void ResetLoadoutItemsUsed(); static void GivePlayerLoadoutItemsUsed(); static const bool EquipsFullyMaxedOut(int maxWeaponLevel=10,int maxArmorLevel=10); - static void Disassemble(std::weak_ptritemRef); + static const Inventory::DisassembleResult Disassemble(std::weak_ptritemRef); static bool SwapItems(ITCategory itemCategory,uint32_t slot1,uint32_t slot2); //Makes sure this is a valid category. Will error out if it doesn't exist! Use for ERROR HANDLING! diff --git a/Adventures in Lestoria/MenuDecal.h b/Adventures in Lestoria/MenuDecal.h new file mode 100644 index 00000000..76d92c7c --- /dev/null +++ b/Adventures in Lestoria/MenuDecal.h @@ -0,0 +1,54 @@ +#pragma region License +/* +License (OLC-3) +~~~~~~~~~~~~~~~ + +Copyright 2024 Joshua Sigona + +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 © 2024 The FreeType +Project (www.freetype.org). Please see LICENSE_FT.txt for more information. +All rights reserved. +*/ +#pragma endregion +#pragma once + +#include "MenuComponent.h" + +class MenuDecal:public MenuComponent{ +public: + inline MenuDecal(geom2d::rectrect,Renderable&image,MenuFunc onClick,MenuFunc onHover) + :image(image),MenuComponent(rect,"",onClick,ButtonAttr::NONE){ + SetHoverFunc(onHover); + } + inline void DrawDecal(ViewPort&window,bool focused)override{ + window.DrawDecal(rect.pos,image.Decal(),rect.size/image.Sprite()->Size()); + } + +private: + const Renderableℑ +}; \ No newline at end of file diff --git a/Adventures in Lestoria/MenuLabel.h b/Adventures in Lestoria/MenuLabel.h index bf97afe0..32d6bc5d 100644 --- a/Adventures in Lestoria/MenuLabel.h +++ b/Adventures in Lestoria/MenuLabel.h @@ -105,7 +105,7 @@ protected: proportional? vf2d(game->GetTextSizeProp(finalLabel)*adjustedScale): vf2d(game->GetTextSize(finalLabel)*adjustedScale); - float sizeRatio=(labelTextSize.x)/(rect.size.x-8); + float sizeRatio=(labelTextSize.x)/(rect.size.x-6); if(sizeRatio>1){ adjustedScale.x/=sizeRatio; adjustedShadowScale.x/=sizeRatio; @@ -116,7 +116,7 @@ protected: vf2d drawPos=vf2d{-1,0}+rect.middle()-vf2d{labelTextSize}/2; //Assume centered. if(!centered){ if(rightAlign){ - drawPos=vf2d{rect.pos.x+rect.size.x-labelTextSize.x-8,rect.middle().y-labelTextSize.y/2}; //We should at least vertically align here. + drawPos=vf2d{rect.pos.x+rect.size.x-labelTextSize.x,rect.middle().y-labelTextSize.y/2}; //We should at least vertically align here. }else{ //Left Align drawPos=vf2d{rect.pos.x+2,rect.middle().y-labelTextSize.y/2}; //We should at least vertically align here. } diff --git a/Adventures in Lestoria/RowInventoryScrollableWindowComponent.h b/Adventures in Lestoria/RowInventoryScrollableWindowComponent.h index 6492a66e..a26e21ac 100644 --- a/Adventures in Lestoria/RowInventoryScrollableWindowComponent.h +++ b/Adventures in Lestoria/RowInventoryScrollableWindowComponent.h @@ -43,6 +43,7 @@ All rights reserved. class RowInventoryScrollableWindowComponent:public InventoryScrollableWindowComponent{ friend class InventoryCreator; friend class Menu; + std::weak_ptrselectedComponent; protected: PriceLabel::PriceLabel priceLabel=PriceLabel::NONE; public: @@ -67,4 +68,19 @@ public: itemButton.lock()->SetPriceLabelType(labelType); } } + + virtual inline void SelectChild(std::weak_ptrchildComponent){ + selectedComponent=childComponent; + for(std::weak_ptrchild:components){ + RowItemDisplay&rowItem{*DYNAMIC_POINTER_CAST(child)}; + rowItem.itemIsSelected=false; + } + selectedComponent.lock()->itemIsSelected=true; + } + virtual inline std::optional>GetSelectedChild()const{ + if(!selectedComponent.expired()){ + return *selectedComponent.lock(); + } + return {}; + } }; \ No newline at end of file diff --git a/Adventures in Lestoria/RowItemDisplay.h b/Adventures in Lestoria/RowItemDisplay.h index a2ef3096..9ad9b95a 100644 --- a/Adventures in Lestoria/RowItemDisplay.h +++ b/Adventures in Lestoria/RowItemDisplay.h @@ -54,6 +54,7 @@ namespace PriceLabel{ } class RowItemDisplay:public MenuComponent{ + friend class RowInventoryScrollableWindowComponent; std::string itemNameLabelName; std::string itemDescriptionLabelName; CompactText compact=NON_COMPACT; @@ -61,6 +62,7 @@ class RowItemDisplay:public MenuComponent{ PriceLabel::PriceLabel priceLabel=PriceLabel::NONE; bool fadeOutIfMissingRequirements=false; bool hideLabelWhileLocked=false; + bool itemIsSelected=false; protected: std::weak_ptritemRef; public: @@ -96,6 +98,13 @@ public: window.DrawDecal(rect.pos+vf2d{2,2},const_cast(itemRef.lock()->Decal()),{scaleFactor,scaleFactor},tint); window.DrawRectDecal(rect.pos+vf2d{2,2},iconSize,borderCol); + if(itemIsSelected){ + window.FillRectDecal(rect.pos+V(A::DRAW_OFFSET)+vf2d{0.f,1.f},{rect.size.x+1,1},YELLOW); + window.FillRectDecal(rect.pos+V(A::DRAW_OFFSET)+vf2d{1.f,0.f},{1,rect.size.y+1},YELLOW); + window.FillRectDecal(rect.pos+V(A::DRAW_OFFSET)+vf2d{-1.f,0.f}+vf2d{rect.size.x-1+1,0},{1,rect.size.y+1},YELLOW); + window.FillRectDecal(rect.pos+V(A::DRAW_OFFSET)+vf2d{0.f,-1.f}+vf2d{0,rect.size.y-1+1},{rect.size.x+1,1},YELLOW); + } + #pragma region Item Name Display std::string itemName=itemRef.lock()->DisplayName(); vf2d scaledSize={std::min(1.f,(rect.size.x-6-iconSize.x)/game->GetTextSizeProp(itemName).x),1}; diff --git a/Adventures in Lestoria/SaveFile.cpp b/Adventures in Lestoria/SaveFile.cpp index 0c320f9a..43de34f3 100644 --- a/Adventures in Lestoria/SaveFile.cpp +++ b/Adventures in Lestoria/SaveFile.cpp @@ -219,8 +219,8 @@ const void SaveFile::SaveGame(){ fileHashWrittenSuccessfully=utils::datafile::Write(saveFile,"save_file_path"_S+std::format("save.{:04}",saveFileID)); //Once the hash has been computed and added, save the file a second time. } std::error_code result; - std::filesystem::remove("save_file_path"_S+std::format("save.{:04}",saveFileID)+".tmp",result); - if(!result)LOG(std::format("WARNING! Could not delete temporary save file. Error: {}",result.message())); + const bool succeeded{std::filesystem::remove("save_file_path"_S+std::format("save.{:04}",saveFileID)+".tmp",result)}; + if(!succeeded)LOG(std::format("WARNING! Could not delete temporary save file. Error: {}",result.message())); #pragma endregion //WARNING! DO NOT WRITE ANY CODE BELOW HERE!!!!! THE HASH HAS ALREADY BEEN WRITTEN. //FILES BECOME CORRUPTED IF THE SAVE FILE IS MODIFIED FROM HERE ONWARDS. @@ -366,8 +366,8 @@ void SaveFile::LoadFile(){ } std::error_code result; - std::filesystem::remove("save_file_path"_S+std::format("save.{:04}",saveFileID)+".tmp",result); - if(!result)LOG(std::format("WARNING! Could not delete temporary save file. Error: {}",result.message())); + const bool succeeded{std::filesystem::remove("save_file_path"_S+std::format("save.{:04}",saveFileID)+".tmp",result)}; + if(!succeeded)LOG(std::format("WARNING! Could not delete temporary save file. Error: {}",result.message())); } } game->ResetGame(); diff --git a/Adventures in Lestoria/Version.h b/Adventures in Lestoria/Version.h index 7e557bd4..0a836662 100644 --- a/Adventures in Lestoria/Version.h +++ b/Adventures in Lestoria/Version.h @@ -39,7 +39,7 @@ All rights reserved. #define VERSION_MAJOR 1 #define VERSION_MINOR 2 #define VERSION_PATCH 5 -#define VERSION_BUILD 11382 +#define VERSION_BUILD 11414 #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 18a5f6db..0e052b81 100644 --- a/Adventures in Lestoria/assets/config/audio/events.txt +++ b/Adventures in Lestoria/assets/config/audio/events.txt @@ -132,6 +132,11 @@ Events # Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%) File[0] = dig.ogg, 100% } + Disassemble Item + { + # Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%) + File[0] = disassemble.ogg, 70% + } Equip Armor { # Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%) diff --git a/Adventures in Lestoria/assets/config/gfx/gfx.txt b/Adventures in Lestoria/assets/config/gfx/gfx.txt index 2d91f1ec..af9eaf57 100644 --- a/Adventures in Lestoria/assets/config/gfx/gfx.txt +++ b/Adventures in Lestoria/assets/config/gfx/gfx.txt @@ -130,6 +130,7 @@ Images GFX_Flames = FlamesTexture.png GFX_Comet = comet.png GFX_CometFlare = comet_flare.png + GFX_DownArrow = downarrow.png GFX_Thief_Sheet = nico-thief.png GFX_Trapper_Sheet = nico-trapper.png diff --git a/Adventures in Lestoria/assets/downarrow.png b/Adventures in Lestoria/assets/downarrow.png new file mode 100644 index 00000000..4cf82793 Binary files /dev/null and b/Adventures in Lestoria/assets/downarrow.png differ diff --git a/Adventures in Lestoria/assets/gamepack.pak b/Adventures in Lestoria/assets/gamepack.pak index 9b2038e6..65411c7b 100644 Binary files a/Adventures in Lestoria/assets/gamepack.pak and b/Adventures in Lestoria/assets/gamepack.pak differ diff --git a/Adventures in Lestoria/assets/sounds/disassemble.ogg b/Adventures in Lestoria/assets/sounds/disassemble.ogg new file mode 100644 index 00000000..bfc90d84 Binary files /dev/null and b/Adventures in Lestoria/assets/sounds/disassemble.ogg differ diff --git a/x64/Release/Adventures in Lestoria.exe b/x64/Release/Adventures in Lestoria.exe index 9477709a..37fa46ec 100644 Binary files a/x64/Release/Adventures in Lestoria.exe and b/x64/Release/Adventures in Lestoria.exe differ