Shop sell features implemented

Co-authored-by: sigonasr2 <sigonasr2@gmail.com>
master
sigonasr2 2 years ago
parent ddb9c04e86
commit 3d5d1a126e
  1. 10
      C++/scripts/debug.sh
  2. 6
      C++/scripts/md5
  3. 2
      C++/scripts/release.sh
  4. 4
      C++/scripts/web.sh
  5. BIN
      C++ProjectTemplate
  6. 4
      SeasonI.h
  7. 4
      entity.h
  8. 9
      flags.h
  9. 1
      item.h
  10. 156
      main.cpp
  11. 26
      object.h
  12. 2
      states.h

@ -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 [ "$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"

@ -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 -

@ -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"

@ -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

Binary file not shown.

@ -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

@ -2,13 +2,15 @@
#define ENTITY_H
#include "pixelGameEngine.h"
#include "object.h"
#include "item.h"
#include <cassert>
extern std::vector<Item*>PARTY_INVENTORY;
using namespace olc;
class Object;
namespace boost{
enum{
ATK,

@ -16,13 +16,6 @@ enum class Flag:int{
HAS_POO,
SHOPKEER_BRANCH1,
SHOPKEER_BRANCH2,
SHOPKEEPER_PREP_SELL_MENU,
};
template <typename Enumeration>
auto toint(Enumeration const value) -> typename std::underlying_type<Enumeration>::type
{
return static_cast<typename std::underlying_type<Enumeration>::type>(value);
}
#endif

@ -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{

@ -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;i<PARTY_MEMBER_COUNT;i++) {
DrawStringPropDecal({(float)4+4,(float)(HEIGHT/2+4+12+i*10)},PARTY_MEMBER_OBJ[i]->name,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:(newAttack<equipAttack)?RED:WHITE,{0.5,1});
DrawStringPropDecal({(float)4+WIDTH*(1.0F/4),(float)(HEIGHT/2+4+12+i*10)},std::to_string(newDefense),(newDefense>equipDefense)?GREEN:(newDefense<equipDefense)?RED:WHITE,{0.5,1});
if (newAttack!=equipAttack) {DrawRotatedDecal({(float)4+WIDTH*(1.0F/4)-14,(float)(HEIGHT/2+4+12+i*10+2+((newAttack<equipAttack)?4:0))},SPRITES["cursor.png"],newAttack>equipAttack?-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+((newDefense<equipDefense)?4:0))},SPRITES["cursor.png"],newDefense>equipDefense?-M_PI_2:M_PI_2,{4,4},{0.5,0.5},newDefense>equipDefense?GREEN:RED);}
}
}
DrawDecal({static_cast<float>(8+(ITEM_SELECTION_CURSOR)%2*(WIDTH-8)/2),static_cast<float>(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<PARTY_INVENTORY.size()) {
DrawStringPropDecal({static_cast<float>(16+i%2*(WIDTH-8)/2),static_cast<float>(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+18<PARTY_INVENTORY.size()) {
DrawRotatedDecal({WIDTH-20,4+HEIGHT/2-4},SPRITES["cursor.png"],M_PI_2,{4,4});
}
DrawInventory();
}
if (BATTLE_ENCOUNTER!=nullptr) {
@ -4053,8 +4045,8 @@ void SeasonI::CursorControl(int&cursor,int max) {
}
}
std::string SeasonI::A_An(std::string str) {
return startsWithVowel(str)?"an "+str:"a "+str;
std::string SeasonI::A_An(std::string str,bool capitalized) {
return startsWithVowel(str)?(capitalized?"An ":"an ")+str:(capitalized?"A ":"a ")+str;
}
void SeasonI::DrawTargetRangeGrid(vd2d pos,int range) {
@ -4844,6 +4836,60 @@ bool SeasonI::Collision(vd2d pos) {
return collisionData!=MAGENTA;
}
void SeasonI::DrawInventory() {
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;i<PARTY_MEMBER_COUNT;i++) {
DrawStringPropDecal({(float)4+4,(float)(HEIGHT/2+4+12+i*10)},PARTY_MEMBER_OBJ[i]->name,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:(newAttack<equipAttack)?RED:WHITE,{0.5,1});
DrawStringPropDecal({(float)4+WIDTH*(1.0F/4),(float)(HEIGHT/2+4+12+i*10)},std::to_string(newDefense),(newDefense>equipDefense)?GREEN:(newDefense<equipDefense)?RED:WHITE,{0.5,1});
if (newAttack!=equipAttack) {DrawRotatedDecal({(float)4+WIDTH*(1.0F/4)-14,(float)(HEIGHT/2+4+12+i*10+2+((newAttack<equipAttack)?4:0))},SPRITES["cursor.png"],newAttack>equipAttack?-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+((newDefense<equipDefense)?4:0))},SPRITES["cursor.png"],newDefense>equipDefense?-M_PI_2:M_PI_2,{4,4},{0.5,0.5},newDefense>equipDefense?GREEN:RED);}
}
}
DrawDecal({static_cast<float>(8+(ITEM_SELECTION_CURSOR)%2*(WIDTH-8)/2),static_cast<float>(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<PARTY_INVENTORY.size()) {
DrawStringPropDecal({static_cast<float>(16+i%2*(WIDTH-8)/2),static_cast<float>(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+18<PARTY_INVENTORY.size()) {
DrawRotatedDecal({WIDTH-20,4+HEIGHT/2-4},SPRITES["cursor.png"],M_PI_2,{4,4});
}
}
void SeasonI::ChoiceMade(int choice) {
switch (GAME_STATE) {
case GameState::SHOPKEEPER_CONFIRM_SELL_MENU:{
if (!choice) {
Item*item=PARTY_INVENTORY[ITEM_SELECTION_CURSOR];
MONEY+=item->stats.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()
{

@ -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<std::pair<Item*,int>> shopItems);
extern std::map<ItemName,Item*>ITEMLIST;
extern void DisplayMessageBox(std::string targetT);
extern int MESSAGE_BOX_DIALOG_ANSWER;
extern std::vector<Item*> PARTY_INVENTORY;
extern int ITEM_SELECTION_CURSOR;
extern int MONEY;
extern std::array<Entity*,7> PARTY_MEMBER_STATS;
extern std::array<int,4> 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,13 +232,15 @@ 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{
switch (MESSAGE_BOX_DIALOG_ANSWER) {
case 0:{
GAME_STATE = GameState::SHOPKEEPER_MENU;
SetupShop(
this,
@ -238,6 +251,13 @@ class Shopkeeper_Obj : public Object{
{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.");

@ -18,6 +18,8 @@ namespace GameState{
OVERWORLD_STATUS_MENU,
OVERWORLD_TARGET_MENU,
SHOPKEEPER_MENU,
SHOPKEEPER_SELL_MENU,
SHOPKEEPER_CONFIRM_SELL_MENU,
};
}

Loading…
Cancel
Save