diff --git a/C++/scripts/debug.sh b/C++/scripts/debug.sh index 3d84b84..12892f8 100755 --- a/C++/scripts/debug.sh +++ b/C++/scripts/debug.sh @@ -1,7 +1,15 @@ -#Compiles the entire program with debug flags then runs it in gdb. +#Compiles the entire program with debug flags then runs it in gdb. If the "test" argument is included, will try and run tests too (in the test folder) #C++ printf "Running program...\n\n\n" -if g++ $(find . -type f -name "*.cpp") -g ${CUSTOM_PARAMS} -o ${PROJECT_NAME}; then - gdb ./${PROJECT_NAME} "$@" +if [ "$1" = "test" ] +then + printf "Running tests...\n" + if g++ $(find . -type f -name "*.cpp") -g ${CUSTOM_PARAMS} -o ${PROJECT_NAME}; then + gdb ./${PROJECT_NAME} "$@" + fi +else + if g++ $(find . -type f -name "*.cpp" -not -path "./test/*") -g ${CUSTOM_PARAMS} -o ${PROJECT_NAME}; then + gdb ./${PROJECT_NAME} "$@" + fi fi printf "\n\n" diff --git a/C++/scripts/md5 b/C++/scripts/md5 index 0dfebb2..9bf810b 100644 --- a/C++/scripts/md5 +++ b/C++/scripts/md5 @@ -1,7 +1,7 @@ build.sh:ca58f10d4e30d807987ea0105930ae51 - commit.sh:d03a46e721060c22ccb146e19d27e70a - -debug.sh:abbbb0c6d9f2409f3a90738ab3d9d44f - +debug.sh:cd1190f874a6f85a7ac7631ef0a00490 - lines.sh:3b907786f7fc9204025993016c9080de - -release.sh:a54e2002be80814cc1293a11dff4d116 - +release.sh:0a525311cc14b9c8aefc6f2b816129a1 - temp:d41d8cd98f00b204e9800998ecf8427e - -web.sh:3dcc2fe7e036359eedd257a864e9a1e1 - +web.sh:96f2c316536011a3defac50aecae487d - diff --git a/C++/scripts/release.sh b/C++/scripts/release.sh index b1620e8..807a40b 100644 --- a/C++/scripts/release.sh +++ b/C++/scripts/release.sh @@ -1,7 +1,7 @@ #Creates a release build that focuses on high runtime performance. #C++ printf "Running program...\n\n\n" -if g++ $(find . -type f -name "*.cpp") ${CUSTOM_PARAMS} -O3 -s -DNDEBUG -o ${PROJECT_NAME}; then +if g++ $(find . -type f -name "*.cpp" -not -path "./test/*") ${CUSTOM_PARAMS} -O3 -s -DNDEBUG -o ${PROJECT_NAME}; then ./${PROJECT_NAME} "$@" fi printf "\n\n" diff --git a/C++/scripts/web.sh b/C++/scripts/web.sh index 2e1a1f3..991d44f 100755 --- a/C++/scripts/web.sh +++ b/C++/scripts/web.sh @@ -1,9 +1,9 @@ #Compiles emscripten instance of this project for the web. #C++ if [ -d "assets" ]; then - em++ -std=c++17 -O2 -s ALLOW_MEMORY_GROWTH=1 -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s USE_SDL_MIXER=2 -s USE_LIBPNG=1 $(find . -type f -name "*.cpp") -o ${PROJECT_NAME}.html -I pixelGameEngine.h --preload-file ./assets + em++ -std=c++17 -O2 -s ALLOW_MEMORY_GROWTH=1 -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s USE_SDL_MIXER=2 -s USE_LIBPNG=1 $(find . -type f -name "*.cpp" -not -path "./test/*") -o ${PROJECT_NAME}.html -I pixelGameEngine.h --preload-file ./assets else - em++ -std=c++17 -O2 -s ALLOW_MEMORY_GROWTH=1 -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s USE_SDL_MIXER=2 -s USE_LIBPNG=1 $(find . -type f -name "*.cpp") -o ${PROJECT_NAME}.html -I pixelGameEngine.h + em++ -std=c++17 -O2 -s ALLOW_MEMORY_GROWTH=1 -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s USE_SDL_MIXER=2 -s USE_LIBPNG=1 $(find . -type f -name "*.cpp" -not -path "./test/*") -o ${PROJECT_NAME}.html -I pixelGameEngine.h fi cp buildtemplate.html ${PROJECT_NAME}.html diff --git a/C++ProjectTemplate b/C++ProjectTemplate index 42015d3..46f2545 100755 Binary files a/C++ProjectTemplate and b/C++ProjectTemplate differ diff --git a/SeasonI.h b/SeasonI.h index 995a51f..90f00a5 100644 --- a/SeasonI.h +++ b/SeasonI.h @@ -89,7 +89,7 @@ class SeasonI:public PixelGameEngine{ void PopulateEquipMenuItems(); void CursorControl(int&cursor,int max); //Returns a version of str with a/an and a space prepended to it followed by the str itself. - std::string A_An(std::string str); + std::string A_An(std::string str,bool capitalized=false); void DrawTargetRangeGrid(vd2d pos,int range,Pixel outlinecol,Pixel box1col,Pixel box2col,bool connectedborder); void DrawTargetRangeGrid(vd2d pos,int range); void DrawMovementGrid(Pixel outlinecol,Pixel box1col,Pixel box2col); @@ -123,6 +123,8 @@ class SeasonI:public PixelGameEngine{ void OnTextEntryComplete(const std::string&text)override; void GetAnyKeyPress(olc::Key keypress)override; bool Collision(vd2d pos); + void DrawInventory(); + void ChoiceMade(int choice); }; extern SeasonI*GAME; #endif \ No newline at end of file diff --git a/entity.h b/entity.h index 3536459..e46ccea 100644 --- a/entity.h +++ b/entity.h @@ -2,13 +2,15 @@ #define ENTITY_H #include "pixelGameEngine.h" -#include "object.h" +#include "item.h" #include extern std::vectorPARTY_INVENTORY; using namespace olc; +class Object; + namespace boost{ enum{ ATK, diff --git a/flags.h b/flags.h index 94a4c91..d6904bb 100644 --- a/flags.h +++ b/flags.h @@ -16,13 +16,6 @@ enum class Flag:int{ HAS_POO, SHOPKEER_BRANCH1, SHOPKEER_BRANCH2, + SHOPKEEPER_PREP_SELL_MENU, }; - - - -template -auto toint(Enumeration const value) -> typename std::underlying_type::type -{ - return static_cast::type>(value); -} #endif \ No newline at end of file diff --git a/item.h b/item.h index e0e304a..112616b 100644 --- a/item.h +++ b/item.h @@ -65,6 +65,7 @@ struct ItemStatsStruct{ EquipSlot::Equip equip=EquipSlot::NONE; //Whether or not this is equipment. bool important=false; //If an item's important it can't be discarded. int consumable=Consumable::NOT_A_CONSUMABLE; //Whether or not this item is consumed when used. + int sellPrice=0; }; struct CustomItemMessage{ diff --git a/main.cpp b/main.cpp index 2273c86..f0cb2c4 100644 --- a/main.cpp +++ b/main.cpp @@ -16,7 +16,7 @@ #include "map.h" #include "SeasonI.h" -#include "test/test.h" +//#include "test/test.h" #ifndef TEST_SUITE #define OLC_PGE_APPLICATION @@ -372,19 +372,19 @@ void SeasonI::SetupMoveList() { } void SeasonI::SetupItemList() { //hpRecovery,ppRecovery,attack,dmgReduction,equip,important,consumable - ITEMLIST[ItemName::COOKIE]=new Item("Cookie","A delightful little treat. Restores 40 HP.",2,{hpRecovery:40,consumable:Consumable::FRIENDLY}); - ITEMLIST[ItemName::EGG]=new Item("Egg","Did it come before or after the chicken? Restores 60 HP.",3,{hpRecovery:60,consumable:Consumable::FRIENDLY}); - ITEMLIST[ItemName::PIZZA]=new Item("Pizza","A scrumptious meal filled with lots of cheese. Restores 200 HP.",4,{hpRecovery:200,consumable:Consumable::FRIENDLY}); - ITEMLIST[ItemName::MIRACLE_FOOD_LUNCH]=new Item("Miracle Food Lunch","It doesn't taste very good, but it's said to have miraculous powers when consumed.",16,{hpRecovery:30,ppRecovery:10,atkIncrease:30,spdIncrease:6,hpIncrease:150,ppIncrease:100,learnAbility:MOVELIST[BattleMoveName::PKFIRE_O],consumable:Consumable::FRIENDLY_PERMANENT}); - ITEMLIST[ItemName::BOMB]=new Item("Bomb","A small explosive device. Deals around 120 damage.",256,{damage:110,rollDmg:30,consumable:Consumable::ENEMY}); - ITEMLIST[ItemName::CRACKED_BAT]=new Item("Cracked Bat","Has some dents in it, but you can probably still dent things with it yourself.",256,{attack:10,equip:EquipSlot::WEAPON}); - ITEMLIST[ItemName::TEE_BALL_BAT]=new Item("Tee Ball Bat","Great for playing some ball! Also great for beating your foes!",256,{attack:40,equip:EquipSlot::WEAPON}); - ITEMLIST[ItemName::LIGHT_JACKET]=new Item("Light Jacket","Fits just fine.",256,{defense:10,equip:EquipSlot::ARMOR}); - ITEMLIST[ItemName::HEAVY_JACKET]=new Item("Heavy Jacket","Are you sure this is good for your shoulders?",256,{defense:25,equip:EquipSlot::ARMOR}); - ITEMLIST[ItemName::COPPER_BRACELET]=new Item("Copper Bracelet","It's not quite as shiny as a diamond, but it still makes you look good.",256,{defense:5,equip:EquipSlot::ACCESSORY}); + ITEMLIST[ItemName::COOKIE]=new Item("Cookie","A delightful little treat. Restores 40 HP.",2,{hpRecovery:40,consumable:Consumable::FRIENDLY,sellPrice:2}); + ITEMLIST[ItemName::EGG]=new Item("Egg","Did it come before or after the chicken? Restores 60 HP.",3,{hpRecovery:60,consumable:Consumable::FRIENDLY,sellPrice:6}); + ITEMLIST[ItemName::PIZZA]=new Item("Pizza","A scrumptious meal filled with lots of cheese. Restores 200 HP.",4,{hpRecovery:200,consumable:Consumable::FRIENDLY,sellPrice:12}); + ITEMLIST[ItemName::MIRACLE_FOOD_LUNCH]=new Item("Miracle Food Lunch","It doesn't taste very good, but it's said to have miraculous powers when consumed.",16,{hpRecovery:30,ppRecovery:10,atkIncrease:30,spdIncrease:6,hpIncrease:150,ppIncrease:100,learnAbility:MOVELIST[BattleMoveName::PKFIRE_O],consumable:Consumable::FRIENDLY_PERMANENT,sellPrice:180}); + ITEMLIST[ItemName::BOMB]=new Item("Bomb","A small explosive device. Deals around 120 damage.",256,{damage:110,rollDmg:30,consumable:Consumable::ENEMY,sellPrice:30}); + ITEMLIST[ItemName::CRACKED_BAT]=new Item("Cracked Bat","Has some dents in it, but you can probably still dent things with it yourself.",256,{attack:10,equip:EquipSlot::WEAPON,sellPrice:4}); + ITEMLIST[ItemName::TEE_BALL_BAT]=new Item("Tee Ball Bat","Great for playing some ball! Also great for beating your foes!",256,{attack:40,equip:EquipSlot::WEAPON,sellPrice:36}); + ITEMLIST[ItemName::LIGHT_JACKET]=new Item("Light Jacket","Fits just fine.",256,{defense:10,equip:EquipSlot::ARMOR,sellPrice:25}); + ITEMLIST[ItemName::HEAVY_JACKET]=new Item("Heavy Jacket","Are you sure this is good for your shoulders?",256,{defense:25,equip:EquipSlot::ARMOR,sellPrice:79}); + ITEMLIST[ItemName::COPPER_BRACELET]=new Item("Copper Bracelet","It's not quite as shiny as a diamond, but it still makes you look good.",256,{defense:5,equip:EquipSlot::ACCESSORY,sellPrice:64}); ITEMLIST[ItemName::KEY_TO_THE_PALACE]=new Item("Key to the Palace","Lets you access a Palace.",256,{important:true}); - ITEMLIST[ItemName::FREEZE_PACKET]=new Item("Freeze Packet","Lets out some blistering cold weather.",256,{consumable:Consumable::ENEMY},MOVELIST[BattleMoveName::FREEZE_PACKET]); - ITEMLIST[ItemName::SOME_STUPIDLY_LONG_FEATHER]=new Item("Some Stupidly Long Feather","Yeah, we don't know why this feather is so long either.",256,{attack:2,defense:3,equip:EquipSlot::ACCESSORY}); + ITEMLIST[ItemName::FREEZE_PACKET]=new Item("Freeze Packet","Lets out some blistering cold weather.",256,{consumable:Consumable::ENEMY,sellPrice:36},MOVELIST[BattleMoveName::FREEZE_PACKET]); + ITEMLIST[ItemName::SOME_STUPIDLY_LONG_FEATHER]=new Item("Some Stupidly Long Feather","Yeah, we don't know why this feather is so long either.",256,{attack:2,defense:3,equip:EquipSlot::ACCESSORY,sellPrice:36}); } Entity::pstats_t partyMemberDefaultStats{HP:120,maxHP:120,PP:30,maxPP:30,baseAtk:8,speed:8,resistances:{0,0,0,0}}; @@ -754,7 +754,7 @@ void SeasonI::SetupBattleProperties() { } void SeasonI::SetGameFlag(Flag flag,bool val) { - GAME_FLAGS[toint(flag)]=val; + GAME_FLAGS[(int)flag]=val; } void SeasonI::LoadMap(Map*map) { @@ -1014,7 +1014,7 @@ bool SeasonI::GetGameFlag(int flag) { } bool SeasonI::GetGameFlag(Flag flag) { - return GAME_FLAGS[toint(flag)]; + return GAME_FLAGS[(int)flag]; } Object*SeasonI::CreateObject(int id,vd2d pos) { @@ -1028,11 +1028,11 @@ Object*SeasonI::AddObjectToWorld(Object*obj) { PARTY_MEMBER_ID[0]=0; PARTY_MEMBER_OBJ[0]->name="PLAYER"; PARTY_MEMBER_STATS[PARTY_MEMBER_ID[0]]->obj=PARTY_MEMBER_OBJ[0]; - for (int i=toint(Flag::HAS_MAIN)+1;i<=toint(Flag::HAS_POO);i++) { + for (int i=(int)Flag::HAS_MAIN+1;i<=(int)Flag::HAS_POO;i++) { if (GetGameFlag(i)) { - PARTY_MEMBER_ID[PARTY_MEMBER_COUNT]=toint(PLAYER)+i-toint(Flag::HAS_MAIN); - PARTY_MEMBER_OBJ[PARTY_MEMBER_COUNT]=AddObjectToWorld(CreateObject(toint(PLAYER)+i-toint(Flag::HAS_MAIN),PARTY_MEMBER_OBJ[0]->GetPos())); - switch (toint(PLAYER)+i-toint(Flag::HAS_MAIN)) { + PARTY_MEMBER_ID[PARTY_MEMBER_COUNT]=(int)PLAYER+i-(int)Flag::HAS_MAIN; + PARTY_MEMBER_OBJ[PARTY_MEMBER_COUNT]=AddObjectToWorld(CreateObject((int)PLAYER+i-(int)Flag::HAS_MAIN,PARTY_MEMBER_OBJ[0]->GetPos())); + switch ((int)PLAYER+i-(int)Flag::HAS_MAIN) { case 0:{PARTY_MEMBER_OBJ[PARTY_MEMBER_COUNT]->name="PLAYER";}break; case 1:{PARTY_MEMBER_OBJ[PARTY_MEMBER_COUNT]->name="NESS";}break; case 2:{PARTY_MEMBER_OBJ[PARTY_MEMBER_COUNT]->name="PAULA";}break; @@ -1401,6 +1401,7 @@ void SeasonI::keyUpdates() { if (INTERACTING_WITH!=nullptr) { INTERACTING_WITH->ChoiceMade(MESSAGE_BOX_DIALOG_CHOICE_CURSOR); } + ChoiceMade(MESSAGE_BOX_DIALOG_CHOICE_CURSOR); DisplayMessageBox(""); targetText=responseText; } @@ -2392,6 +2393,23 @@ void SeasonI::keyUpdates() { } } }break; + case GameState::SHOPKEEPER_SELL_MENU:{ + if (LeftPressed()&&!(ITEM_SELECTION_CURSOR&1)) { + GAME_STATE=GameState::GAME_WORLD; + SHOPKEEPER_INTERACTING_WITH->ShoppingCompleted(); + } else { + HandleInventoryNavigation(); + } + if (ACTIONKEYPRESSED) { + if (PARTY_INVENTORY[ITEM_SELECTION_CURSOR]->stats.important) { + DisplayMessageBox("You shouldn't get rid of that!"); + } else { + GAME_STATE=GameState::SHOPKEEPER_CONFIRM_SELL_MENU; + Item*item=PARTY_INVENTORY[ITEM_SELECTION_CURSOR]; + DisplayMessageBox(A_An(PARTY_INVENTORY[ITEM_SELECTION_CURSOR]->name,true)+" sells for $"+std::to_string(PARTY_INVENTORY[ITEM_SELECTION_CURSOR]->stats.sellPrice)+". Would you like to sell it? [Yes,No]>0:You sell "+A_An(item->name)+" for $"+std::to_string(item->stats.sellPrice)+".>1:You decide against selling "+A_An(item->name)+".<"); + } + } + }break; } reset: ANYKEYPRESSED=ACTIONKEYPRESSED=false; @@ -2486,7 +2504,7 @@ void SeasonI::drawGame(){ vd2d textOffset=GetTextSize(label)*0.6; textOffset.y+=10; vd2d barPos = {(float)(box.x+4),(float)(box.y+5+8+2)}; - DrawStringDecal(barPos-textOffset/2,label,Pixel(0,0,0,boxAlpha),{std::min((float)54/GetTextSize(label).x,(float)1),0.6}); + DrawStringDecal(barPos-textOffset/2,label,Pixel(0,0,0,boxAlpha),{std::min((float)50/GetTextSize(label).x,(float)1),0.6}); } const vi2d hpTextPos = {box.x+5,box.y+25}; for (int x=-1;x<=1;x++) { @@ -2682,6 +2700,12 @@ void SeasonI::drawGame(){ DrawStringPropDecal({(int)(WIDTH/2)+6,6},Wrap(SHOP_ITEMS[SHOP_MENU_CURSOR].first->description,(int)(WIDTH/2)-6,true,{1,1})); } }break; + case GameState::SHOPKEEPER_SELL_MENU: + case GameState::SHOPKEEPER_CONFIRM_SELL_MENU:{ + DrawGameWorld(); + DrawInventory(); + DrawMoneyBox({WIDTH-WIDTH/4-4,HEIGHT*(3.f/4)+4}); + }break; case GameState::EDITOR:{ DrawGameWorld(); SetDrawTarget(nullptr); @@ -2811,39 +2835,7 @@ void SeasonI::drawGame(){ } if (BATTLE_ENCOUNTER!=nullptr&&BATTLE_STATE==BattleState::ITEM_SELECT||GAME_STATE==GameState::OVERWORLD_ITEMS_MENU&&!messageBoxVisible) { - SetDrawTarget(layer::INTERFACE); - DrawDialogBox({4,4},{(int)(WIDTH-8),(int)(HEIGHT/2)},Pixel(70, 33, 105,220),Pixel(62, 54, 69,220),Pixel(185, 148, 255,220)); - DrawDialogBox({(int)(WIDTH*(3.0F/8)),HEIGHT/2+4},{(int)(WIDTH*(5.0F/8)-4),(int)(HEIGHT/4)},Pixel(70, 33, 105,220),Pixel(62, 54, 69,220),Pixel(185, 148, 255,220)); - if (PARTY_INVENTORY[ITEM_SELECTION_CURSOR]->stats.equip!=EquipSlot::NONE) { - DrawDialogBox({(int)4,HEIGHT/2+4},{(int)(WIDTH*(3.0F/8)-4),(int)(HEIGHT/4)},Pixel(70, 33, 105,220),Pixel(62, 54, 69,220),Pixel(185, 148, 255,220)); - DrawStringPropDecal({(float)4+WIDTH*(1.0F/8),(float)(HEIGHT/2+8)},"ATK",WHITE,{1,1}); - DrawStringPropDecal({(float)4+WIDTH*(1.0F/4),(float)(HEIGHT/2+8)},"DEF",WHITE,{1,1}); - for (int i=0;iname,WHITE,{0.5,1}); - int equipAttack=0; - int equipDefense=0; - int newAttack=0; - int newDefense=0; - CalculateChangeInEquipmentStats(i,ITEM_SELECTION_CURSOR,equipAttack,equipDefense,newAttack,newDefense); - DrawStringPropDecal({(float)4+WIDTH*(1.0F/8),(float)(HEIGHT/2+4+12+i*10)},std::to_string(PARTY_MEMBER_STATS[PARTY_MEMBER_ID[i]]->stats.baseAtk+newAttack),(newAttack>equipAttack)?GREEN:(newAttackequipDefense)?GREEN:(newDefenseequipAttack?-M_PI_2:M_PI_2,{4,4},{0.5,0.5},newAttack>equipAttack?GREEN:RED);} - if (newDefense!=equipDefense) {DrawRotatedDecal({(float)4+WIDTH*(3.0F/8)-14,(float)(HEIGHT/2+4+12+i*10+2+((newDefenseequipDefense?-M_PI_2:M_PI_2,{4,4},{0.5,0.5},newDefense>equipDefense?GREEN:RED);} - } - } - DrawDecal({static_cast(8+(ITEM_SELECTION_CURSOR)%2*(WIDTH-8)/2),static_cast(12*((ITEM_SELECTION_CURSOR-ITEM_SELECTION_OFFSET)/2)+8)},SPRITES["cursor.png"]); - DrawStringPropDecal({(int)(WIDTH*(3.0F/8))+4,HEIGHT/2+8},Wrap(PARTY_INVENTORY[ITEM_SELECTION_CURSOR]->description,(int)(WIDTH*(5.0F/8))-4,true,{1,1})); - for (int i=0;i<18;i++) { - if (ITEM_SELECTION_OFFSET+i(16+i%2*(WIDTH-8)/2),static_cast(12*(i/2)+8)},PARTY_INVENTORY[ITEM_SELECTION_OFFSET+i]->name,WHITE,{std::clamp((float)(WIDTH-48)/2/GetTextSizeProp(PARTY_INVENTORY[ITEM_SELECTION_OFFSET+i]->name).x,0.0F,1.0F),1.0F}); - } - } - if (ITEM_SELECTION_OFFSET>0) { - DrawRotatedDecal({WIDTH-20,8},SPRITES["cursor.png"],-M_PI_2,{4,4}); - } - if (ITEM_SELECTION_OFFSET+18stats.equip!=EquipSlot::NONE) { + DrawDialogBox({(int)4,HEIGHT/2+4},{(int)(WIDTH*(3.0F/8)-4),(int)(HEIGHT/4)},Pixel(70, 33, 105,220),Pixel(62, 54, 69,220),Pixel(185, 148, 255,220)); + DrawStringPropDecal({(float)4+WIDTH*(1.0F/8),(float)(HEIGHT/2+8)},"ATK",WHITE,{1,1}); + DrawStringPropDecal({(float)4+WIDTH*(1.0F/4),(float)(HEIGHT/2+8)},"DEF",WHITE,{1,1}); + for (int i=0;iname,WHITE,{0.5,1}); + int equipAttack=0; + int equipDefense=0; + int newAttack=0; + int newDefense=0; + CalculateChangeInEquipmentStats(i,ITEM_SELECTION_CURSOR,equipAttack,equipDefense,newAttack,newDefense); + DrawStringPropDecal({(float)4+WIDTH*(1.0F/8),(float)(HEIGHT/2+4+12+i*10)},std::to_string(PARTY_MEMBER_STATS[PARTY_MEMBER_ID[i]]->stats.baseAtk+newAttack),(newAttack>equipAttack)?GREEN:(newAttackequipDefense)?GREEN:(newDefenseequipAttack?-M_PI_2:M_PI_2,{4,4},{0.5,0.5},newAttack>equipAttack?GREEN:RED);} + if (newDefense!=equipDefense) {DrawRotatedDecal({(float)4+WIDTH*(3.0F/8)-14,(float)(HEIGHT/2+4+12+i*10+2+((newDefenseequipDefense?-M_PI_2:M_PI_2,{4,4},{0.5,0.5},newDefense>equipDefense?GREEN:RED);} + } + } + DrawDecal({static_cast(8+(ITEM_SELECTION_CURSOR)%2*(WIDTH-8)/2),static_cast(12*((ITEM_SELECTION_CURSOR-ITEM_SELECTION_OFFSET)/2)+8)},SPRITES["cursor.png"]); + DrawStringPropDecal({(int)(WIDTH*(3.0F/8))+4,HEIGHT/2+8},Wrap(PARTY_INVENTORY[ITEM_SELECTION_CURSOR]->description,(int)(WIDTH*(5.0F/8))-4,true,{1,1})); + for (int i=0;i<18;i++) { + if (ITEM_SELECTION_OFFSET+i(16+i%2*(WIDTH-8)/2),static_cast(12*(i/2)+8)},PARTY_INVENTORY[ITEM_SELECTION_OFFSET+i]->name,WHITE,{std::clamp((float)(WIDTH-48)/2/GetTextSizeProp(PARTY_INVENTORY[ITEM_SELECTION_OFFSET+i]->name).x,0.0F,1.0F),1.0F}); + } + } + if (ITEM_SELECTION_OFFSET>0) { + DrawRotatedDecal({WIDTH-20,8},SPRITES["cursor.png"],-M_PI_2,{4,4}); + } + if (ITEM_SELECTION_OFFSET+18stats.sellPrice; + PARTY_MEMBER_STATS[PARTY_MEMBER_ID[0]]->RemoveItem(ITEM_SELECTION_CURSOR); + if (ITEM_SELECTION_CURSOR>=PARTY_INVENTORY.size()) { + ITEM_SELECTION_CURSOR--; + } + } else { + Item*item=PARTY_INVENTORY[ITEM_SELECTION_CURSOR]; + } + GAME_STATE=GameState::SHOPKEEPER_SELL_MENU; + }break; + } +} + #ifndef TEST_SUITE int main() { diff --git a/object.h b/object.h index e234df6..688a67a 100644 --- a/object.h +++ b/object.h @@ -7,6 +7,7 @@ #include "layers.h" #include "item.h" #include "states.h" +#include "entity.h" #include "SeasonI.h" using namespace olc; @@ -198,6 +199,16 @@ extern int GAME_STATE; extern void SetupShop(Object*shopkeeper,std::vector> shopItems); extern std::mapITEMLIST; extern void DisplayMessageBox(std::string targetT); +extern int MESSAGE_BOX_DIALOG_ANSWER; +extern std::vector PARTY_INVENTORY; +extern int ITEM_SELECTION_CURSOR; +extern int MONEY; +extern std::array PARTY_MEMBER_STATS; +extern std::array PARTY_MEMBER_ID; +extern std::string A_An(std::string str); +extern int GAME_STATE; +extern SeasonI*GAME; +extern Object*SHOPKEEPER_INTERACTING_WITH; class Shopkeeper_Obj : public Object{ DynamicObject(Shopkeeper_Obj) @@ -207,7 +218,7 @@ class Shopkeeper_Obj : public Object{ >1:What would you like to sell?\ >2:Are you okay?<"; Interaction Interact()override{ - if (GAME_FLAGS[(int)Flag::SHOPKEER_BRANCH1]) { + if (GAME->GetGameFlag(Flag::SHOPKEER_BRANCH1)) { GAME_FLAGS[(int)Flag::SHOPKEER_BRANCH1]=false; switch (MESSAGE_BOX_DIALOG_ANSWER) { case 2:{ @@ -221,23 +232,32 @@ class Shopkeeper_Obj : public Object{ } } void ChoiceMade(int choice)override{ - if (GAME_FLAGS[(int)Flag::SHOPKEER_BRANCH1]) { + if (GAME->GetGameFlag(Flag::SHOPKEER_BRANCH1)) { if (choice!=2) { - GAME_FLAGS[(int)Flag::SHOPKEER_BRANCH1]=false; + GAME->SetGameFlag(Flag::SHOPKEER_BRANCH1,false); } } } void DialogClosed()override{ - GAME_STATE = GameState::SHOPKEEPER_MENU; - SetupShop( - this, - { - {ITEMLIST[ItemName::EGG],8}, - {ITEMLIST[ItemName::COOKIE],4}, - {ITEMLIST[ItemName::PIZZA],36}, - {ITEMLIST[ItemName::SOME_STUPIDLY_LONG_FEATHER],46}, - } - ); + switch (MESSAGE_BOX_DIALOG_ANSWER) { + case 0:{ + GAME_STATE = GameState::SHOPKEEPER_MENU; + SetupShop( + this, + { + {ITEMLIST[ItemName::EGG],8}, + {ITEMLIST[ItemName::COOKIE],4}, + {ITEMLIST[ItemName::PIZZA],36}, + {ITEMLIST[ItemName::SOME_STUPIDLY_LONG_FEATHER],46}, + } + ); + }break; + case 1:{ + GAME_STATE = GameState::SHOPKEEPER_SELL_MENU; + SHOPKEEPER_INTERACTING_WITH=this; + }break; + default:{} + } } void ShoppingCompleted()override{ DisplayMessageBox("Thanks for shopping with us! Have a great day."); diff --git a/states.h b/states.h index 4078eb7..180dbcb 100644 --- a/states.h +++ b/states.h @@ -18,6 +18,8 @@ namespace GameState{ OVERWORLD_STATUS_MENU, OVERWORLD_TARGET_MENU, SHOPKEEPER_MENU, + SHOPKEEPER_SELL_MENU, + SHOPKEEPER_CONFIRM_SELL_MENU, }; }