Implemented unlocking of areas via clearing stages. Game fade in/out for state transitions. Asset loading for visual novel assets. Visual Novel command execution code implemented. Visual Novel basic rendering and input handling enabled.

pull/28/head
sigonasr2 1 year ago
parent 3601e8b83a
commit a7f13e0077
  1. 47
      Crawler/Crawler.cpp
  2. 9
      Crawler/Crawler.h
  3. 1
      Crawler/Crawler.vcxproj
  4. 3
      Crawler/Crawler.vcxproj.filters
  5. 11
      Crawler/GameState.cpp
  6. 7
      Crawler/GameState.h
  7. 10
      Crawler/LevelCompleteWindow.cpp
  8. 67
      Crawler/Menu.cpp
  9. 10
      Crawler/Menu.h
  10. 9
      Crawler/OverworldMapLevelWindow.cpp
  11. 8
      Crawler/State_OverworldMap.cpp
  12. 9
      Crawler/State_Story.cpp
  13. 14
      Crawler/Unlock.cpp
  14. 7
      Crawler/Unlock.h
  15. 2
      Crawler/Version.h
  16. 120
      Crawler/VisualNovel.cpp
  17. 23
      Crawler/VisualNovel.h
  18. 0
      Crawler/assets/characters/Red Stone.png
  19. 9
      Crawler/assets/config/configuration.txt
  20. 8
      Crawler/assets/config/gfx/themes.txt
  21. 10
      Crawler/assets/config/story/characters.txt

@ -59,6 +59,7 @@ SUCH DAMAGE.
#include "Test.h" #include "Test.h"
#include "ItemDrop.h" #include "ItemDrop.h"
#include "VisualNovel.h" #include "VisualNovel.h"
#include "util.h"
INCLUDE_EMITTER_LIST INCLUDE_EMITTER_LIST
@ -79,6 +80,7 @@ InputGroup Crawler::KEY_RIGHT;
InputGroup Crawler::KEY_UP; InputGroup Crawler::KEY_UP;
InputGroup Crawler::KEY_DOWN; InputGroup Crawler::KEY_DOWN;
InputGroup Crawler::KEY_ATTACK; InputGroup Crawler::KEY_ATTACK;
InputGroup Crawler::KEY_CONFIRM;
float Crawler::SIZE_CHANGE_SPEED=1; float Crawler::SIZE_CHANGE_SPEED=1;
@ -132,6 +134,9 @@ Crawler::Crawler()
bool Crawler::OnUserCreate(){ bool Crawler::OnUserCreate(){
InitializeDefaultKeybinds(); InitializeDefaultKeybinds();
VisualNovel::Initialize();
InitializeLevels(); InitializeLevels();
player=std::make_unique<Warrior>(); player=std::make_unique<Warrior>();
@ -185,8 +190,6 @@ bool Crawler::OnUserCreate(){
Unlock::Initialize(); Unlock::Initialize();
ItemDrop::Initialize(); ItemDrop::Initialize();
VisualNovel::Initialize();
ValidateGameStatus(); //Checks to make sure everything has been initialized properly. ValidateGameStatus(); //Checks to make sure everything has been initialized properly.
return true; return true;
@ -195,10 +198,13 @@ bool Crawler::OnUserCreate(){
bool Crawler::OnUserUpdate(float fElapsedTime){ bool Crawler::OnUserUpdate(float fElapsedTime){
fElapsedTime=std::clamp(fElapsedTime,0.f,1/30.f); //HACK fix. We can't have a negative time. Although using a more precise system clock should make this never occur. Also make sure if the game is too slow we advance by only 1/30th of a second. fElapsedTime=std::clamp(fElapsedTime,0.f,1/30.f); //HACK fix. We can't have a negative time. Although using a more precise system clock should make this never occur. Also make sure if the game is too slow we advance by only 1/30th of a second.
levelTime+=fElapsedTime; levelTime+=fElapsedTime;
if(!GamePaused()){
GameState::STATE->OnUserUpdate(this); GameState::STATE->OnUserUpdate(this);
}
RenderWorld(GetElapsedTime()); RenderWorld(GetElapsedTime());
GameState::STATE->Draw(this); GameState::STATE->Draw(this);
RenderMenu(); RenderMenu();
RenderFadeout();
RenderVersionInfo(); RenderVersionInfo();
return true; return true;
} }
@ -1390,6 +1396,10 @@ void Crawler::InitializeLevel(std::string mapFile,MapName map){
} }
for(ConnectionPoint&cp:State_OverworldMap::connections){ for(ConnectionPoint&cp:State_OverworldMap::connections){
if(VisualNovel::storyLevelData.count(cp.map)){ //Visual novel story data for story levels.
cp.levelDataExists=true;
break;
}
if(LEVEL_NAMES.count(cp.map)&&&MapHelper::MapFromString(cp.map)==&MAP_DATA[map]){ if(LEVEL_NAMES.count(cp.map)&&&MapHelper::MapFromString(cp.map)==&MAP_DATA[map]){
MAP_DATA[map].name=cp.name; MAP_DATA[map].name=cp.name;
for(int spawn:MAP_DATA[map].spawns){ for(int spawn:MAP_DATA[map].spawns){
@ -1914,6 +1924,8 @@ void Crawler::InitializeDefaultKeybinds(){
KEY_UP.AddKeybind({KEY,W}); KEY_UP.AddKeybind({KEY,W});
KEY_DOWN.AddKeybind({KEY,DOWN}); KEY_DOWN.AddKeybind({KEY,DOWN});
KEY_DOWN.AddKeybind({KEY,S}); KEY_DOWN.AddKeybind({KEY,S});
KEY_CONFIRM.AddKeybind({MOUSE,Mouse::LEFT});
KEY_CONFIRM.AddKeybind({KEY,ENTER});
} }
void Crawler::SetBossNameDisplay(std::string name,float time){ void Crawler::SetBossNameDisplay(std::string name,float time){
@ -1977,7 +1989,7 @@ void Crawler::ReduceBossEncounterMobCount(){
} }
void Crawler::RenderMenu(){ void Crawler::RenderMenu(){
if(Menu::stack.size()>0){ if(!GamePaused()&&Menu::stack.size()>0){
Menu::stack.back()->Update(this); Menu::stack.back()->Update(this);
} }
if(Menu::stack.size()>0){ if(Menu::stack.size()>0){
@ -2029,7 +2041,7 @@ void Crawler::InitializeGraphics(){
std::sort(mappedKeys.begin(),mappedKeys.end(),[](std::pair<std::string,size_t>&key1,std::pair<std::string,size_t>&key2){return key1.second<key2.second;}); std::sort(mappedKeys.begin(),mappedKeys.end(),[](std::pair<std::string,size_t>&key1,std::pair<std::string,size_t>&key2){return key1.second<key2.second;});
for(auto&key:mappedKeys){ for(auto&key:mappedKeys){
std::string themeName=key.first; std::string themeName=key.first;
std::string imgPath=DATA["Themes"][themeName]["Name"].GetString(); std::string imgPath=DATA["Themes"][themeName]["filename"].GetString();
Renderable&img=GFX["theme_img_directory"_S+imgPath+".png"]; Renderable&img=GFX["theme_img_directory"_S+imgPath+".png"];
img.Load("GFX_Prefix"_S+"theme_img_directory"_S+imgPath+".png"); img.Load("GFX_Prefix"_S+"theme_img_directory"_S+imgPath+".png");
Renderable&sourceImg=img; Renderable&sourceImg=img;
@ -2064,6 +2076,12 @@ void Crawler::InitializeGraphics(){
} }
} }
for(std::string img:VisualNovel::graphicsToLoad){
Renderable&image=GFX[img];
image.Load("GFX_Prefix"_S+img);
}
std::cout<<VisualNovel::graphicsToLoad.size()<<" images for visual novel engine have been loaded."<<std::endl;
Menu::themes.SetInitialized(); Menu::themes.SetInitialized();
std::cout<<Menu::themes.size()<<" themes have been loaded."<<std::endl; std::cout<<Menu::themes.size()<<" themes have been loaded."<<std::endl;
GFX.SetInitialized(); GFX.SetInitialized();
@ -2170,6 +2188,25 @@ bool Crawler::UseLoadoutItem(int slot){
void Crawler::ClearLoadoutItem(int slot){ void Crawler::ClearLoadoutItem(int slot){
if(slot<0||slot>loadout.size()-1)ERR("Invalid inventory slot "+std::to_string(slot)+", please choose a slot in range (0-"+std::to_string(loadout.size()-1)+")."); if(slot<0||slot>loadout.size()-1)ERR("Invalid inventory slot "+std::to_string(slot)+", please choose a slot in range (0-"+std::to_string(loadout.size()-1)+").");
loadout[slot].amt=0;
loadout[slot].it=nullptr; loadout[slot].it=nullptr;
} }
void Crawler::RenderFadeout(){
uint8_t alpha=0;
if(fadeOutDuration>0){
fadeOutDuration=std::max(0.f,fadeOutDuration-GetElapsedTime());
if(fadeOutDuration==0){
GameState::_ChangeState(transitionState);
}
alpha=uint8_t(util::lerp(0,255,1-(fadeOutDuration/fadeOutTotalTime)));
}else
if(fadeInDuration>0){
fadeInDuration=std::max(0.f,fadeInDuration-GetElapsedTime());
alpha=uint8_t(util::lerp(255,0,1-(fadeInDuration/fadeOutTotalTime)));
}
FillRectDecal({0,0},GetScreenSize(),{0,0,0,alpha});
}
bool Crawler::GamePaused(){
return fadeOutDuration>0;
}

@ -45,14 +45,17 @@ SUCH DAMAGE.
#include "TMXParser.h" #include "TMXParser.h"
#include "olcUTIL_DataFile.h" #include "olcUTIL_DataFile.h"
#include "Key.h" #include "Key.h"
#include "GameState.h"
class Crawler : public olc::PixelGameEngine class Crawler : public olc::PixelGameEngine
{ {
friend class GameState;
friend class State_GameRun; friend class State_GameRun;
friend class sig::Animation; friend class sig::Animation;
std::unique_ptr<Player>player; std::unique_ptr<Player>player;
public: public:
Pathfinding pathfinder; Pathfinding pathfinder;
static InputGroup KEY_CONFIRM;
static InputGroup KEY_ATTACK; static InputGroup KEY_ATTACK;
static InputGroup KEY_LEFT; static InputGroup KEY_LEFT;
static InputGroup KEY_RIGHT; static InputGroup KEY_RIGHT;
@ -96,6 +99,10 @@ private:
int totalBossEncounterMobs=0; int totalBossEncounterMobs=0;
int chapter=1; //We start at chapter 1. int chapter=1; //We start at chapter 1.
std::array<Item,3>loadout; std::array<Item,3>loadout;
float fadeOutDuration=0;
float fadeOutTotalTime=0;
float fadeInDuration=0;
States::State transitionState=States::State::GAME_RUN;
std::vector<Monster>monstersToBeSpawned; std::vector<Monster>monstersToBeSpawned;
@ -182,6 +189,8 @@ public:
bool UseLoadoutItem(int slot); bool UseLoadoutItem(int slot);
//Blanks out this loadout item. //Blanks out this loadout item.
void ClearLoadoutItem(int slot); void ClearLoadoutItem(int slot);
void RenderFadeout();
bool GamePaused();
struct TileGroupData{ struct TileGroupData{
vi2d tilePos; vi2d tilePos;

@ -429,7 +429,6 @@
<Text Include="assets\config\MonsterStrategies.txt" /> <Text Include="assets\config\MonsterStrategies.txt" />
<Text Include="assets\config\Player.txt" /> <Text Include="assets\config\Player.txt" />
<Text Include="assets\config\story\Chapter 1.txt" /> <Text Include="assets\config\story\Chapter 1.txt" />
<Text Include="assets\config\story\characters.txt" />
<Text Include="Crawler_Story_Chapter_1 (2).txt" /> <Text Include="Crawler_Story_Chapter_1 (2).txt" />
<Text Include="Crawler_System_Overview.txt" /> <Text Include="Crawler_System_Overview.txt" />
<Text Include="NewClasses.txt" /> <Text Include="NewClasses.txt" />

@ -533,9 +533,6 @@
<Text Include="Crawler_Story_Chapter_1 (2).txt"> <Text Include="Crawler_Story_Chapter_1 (2).txt">
<Filter>Documentation\Story</Filter> <Filter>Documentation\Story</Filter>
</Text> </Text>
<Text Include="assets\config\story\characters.txt">
<Filter>Configurations\Story</Filter>
</Text>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Image Include="assets\heart.ico"> <Image Include="assets\heart.ico">

@ -53,7 +53,7 @@ void GameState::Initialize(){
GameState::ChangeState(States::OVERWORLD_MAP); GameState::ChangeState(States::OVERWORLD_MAP);
} }
void GameState::ChangeState(States::State newState){ void GameState::_ChangeState(States::State newState){
GameState*prevState=STATE; GameState*prevState=STATE;
if(!states.count(newState)){ if(!states.count(newState)){
ERR("WARNING! State not defined for state "<<newState<<"!") ERR("WARNING! State not defined for state "<<newState<<"!")
@ -61,6 +61,15 @@ void GameState::ChangeState(States::State newState){
STATE=states.at(newState); STATE=states.at(newState);
game->camera.SetTarget(game->GetPlayer()->GetPos()); game->camera.SetTarget(game->GetPlayer()->GetPos());
STATE->OnStateChange(prevState); STATE->OnStateChange(prevState);
}
void GameState::ChangeState(States::State newState,float fadeOutDuration){
if(fadeOutDuration>0){
game->fadeOutDuration=game->fadeOutTotalTime=game->fadeInDuration=fadeOutDuration;
game->transitionState=newState;
}else{
_ChangeState(newState);
} }
}
GameState::~GameState(){} GameState::~GameState(){}

@ -1,3 +1,4 @@
#pragma region License
/* /*
License (OLC-3) License (OLC-3)
~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
@ -29,6 +30,7 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE. SUCH DAMAGE.
*/ */
#pragma endregion
#pragma once #pragma once
#include <map> #include <map>
#include <iostream> #include <iostream>
@ -47,6 +49,9 @@ namespace States{
}; };
class GameState{ class GameState{
friend class Crawler;
private:
static void _ChangeState(States::State newState);
public: public:
inline static GameState*STATE=nullptr; inline static GameState*STATE=nullptr;
inline static std::map<States::State,GameState*>states; inline static std::map<States::State,GameState*>states;
@ -55,5 +60,5 @@ public:
virtual void OnStateChange(GameState*prevState)=0; virtual void OnStateChange(GameState*prevState)=0;
virtual void OnUserUpdate(Crawler*game)=0; virtual void OnUserUpdate(Crawler*game)=0;
virtual void Draw(Crawler*game)=0; virtual void Draw(Crawler*game)=0;
static void ChangeState(States::State newState); static void ChangeState(States::State newState,float fadeOutDuration=0);
}; };

@ -37,6 +37,8 @@ SUCH DAMAGE.
#include "MenuComponent.h" #include "MenuComponent.h"
#include "InventoryScrollableWindowComponent.h" #include "InventoryScrollableWindowComponent.h"
#include "PopupMenuLabel.h" #include "PopupMenuLabel.h"
#include "Unlock.h"
#include "State_OverworldMap.h"
INCLUDE_game INCLUDE_game
@ -65,9 +67,15 @@ void Menu::InitializeLevelCompleteWindow(){
levelCompleteWindow->AddComponent("Stage Loot Label",stageLootLabel); levelCompleteWindow->AddComponent("Stage Loot Label",stageLootLabel);
levelCompleteWindow->AddComponent("Stage Loot Window",stageLootWindow); levelCompleteWindow->AddComponent("Stage Loot Window",stageLootWindow);
auto nextButtonAction=[](MenuFuncData data){
Unlock::UnlockArea(State_OverworldMap::GetCurrentConnectionPoint().map);
GameState::ChangeState(States::OVERWORLD_MAP,0.5f);
return true;
};
MenuComponent*detailsOutline=NEW MenuComponent(LEVEL_COMPLETE,{{windowSize.size.x-72.f,32},{71,72}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE); MenuComponent*detailsOutline=NEW MenuComponent(LEVEL_COMPLETE,{{windowSize.size.x-72.f,32},{71,72}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE);
MenuLabel*detailsExpGain=NEW MenuLabel(LEVEL_COMPLETE,{{windowSize.size.x-72.f,104},{71,36}},"+ Exp",1,ComponentAttr::SHADOW|ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND); MenuLabel*detailsExpGain=NEW MenuLabel(LEVEL_COMPLETE,{{windowSize.size.x-72.f,104},{71,36}},"+ Exp",1,ComponentAttr::SHADOW|ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND);
MenuComponent*nextButton=NEW MenuComponent(LEVEL_COMPLETE,{{windowSize.size.x-72.f,144},{71,32}},"Next",DO_NOTHING); MenuComponent*nextButton=NEW MenuComponent(LEVEL_COMPLETE,{{windowSize.size.x-72.f,144},{71,32}},"Next",nextButtonAction);
levelCompleteWindow->AddComponent("Level Details Outline",detailsOutline); levelCompleteWindow->AddComponent("Level Details Outline",detailsOutline);
levelCompleteWindow->AddComponent("Level EXP Gain Outline",detailsExpGain); levelCompleteWindow->AddComponent("Level EXP Gain Outline",detailsExpGain);

@ -63,6 +63,7 @@ MenuType Menu::lastMenuTypeCreated;
std::string Menu::lastRegisteredComponent; std::string Menu::lastRegisteredComponent;
bool Menu::cover; bool Menu::cover;
INCLUDE_game
INCLUDE_GFX INCLUDE_GFX
extern vi2d WINDOW_SIZE; extern vi2d WINDOW_SIZE;
@ -301,9 +302,9 @@ void Menu::Update(Crawler*game){
void Menu::Draw(Crawler*game){ void Menu::Draw(Crawler*game){
if(GetCurrentTheme().IsScaled()){ if(GetCurrentTheme().IsScaled()){
DrawScaledWindowBackground(game,pos); DrawScaledWindowBackground(game,pos,size,GetRenderColor());
}else{ }else{
DrawTiledWindowBackground(game,pos); DrawTiledWindowBackground(game,pos,size,GetRenderColor());
} }
game->SetDrawTarget(r.Sprite()); game->SetDrawTarget(r.Sprite());
@ -340,9 +341,9 @@ void Menu::Draw(Crawler*game){
} }
if(GetCurrentTheme().IsScaled()){ if(GetCurrentTheme().IsScaled()){
DrawScaledWindowBorder(game,pos); DrawScaledWindowBorder(game,pos,size,GetRenderColor());
}else{ }else{
DrawTiledWindowBorder(game,pos); DrawTiledWindowBorder(game,pos,size,GetRenderColor());
} }
if(draggingComponent!=nullptr){ if(draggingComponent!=nullptr){
@ -535,69 +536,69 @@ void Menu::KeyboardButtonNavigation(Crawler*game,vf2d menuPos){
} }
} }
void Menu::DrawScaledWindowBorder(Crawler*game,vf2d menuPos){ void Menu::DrawScaledWindowBorder(Crawler*game,vf2d menuPos,vf2d size,Pixel renderColor){
vf2d patchSize={"Interface.9PatchSize"_f[0],"Interface.9PatchSize"_f[1]}; vf2d patchSize={"Interface.9PatchSize"_f[0],"Interface.9PatchSize"_f[1]};
//Upper-Left //Upper-Left
game->DrawPartialDecal(menuPos-patchSize,patchSize,GetPatchPart(0,0).Decal(),{patchSize.x*0,patchSize.y*0},patchSize,GetRenderColor()); game->DrawPartialDecal(menuPos-patchSize,patchSize,GetPatchPart(0,0).Decal(),{patchSize.x*0,patchSize.y*0},patchSize,renderColor);
//Upper-Right //Upper-Right
game->DrawPartialDecal(menuPos+vf2d{size.x,-patchSize.y},patchSize,GetPatchPart(2,0).Decal(),{patchSize.x*2,patchSize.y*0},patchSize,GetRenderColor()); game->DrawPartialDecal(menuPos+vf2d{size.x,-patchSize.y},patchSize,GetPatchPart(2,0).Decal(),{patchSize.x*2,patchSize.y*0},patchSize,renderColor);
//Bottom-Left //Bottom-Left
game->DrawPartialDecal(menuPos+vf2d{-patchSize.x,size.y},patchSize,GetPatchPart(0,2).Decal(),{patchSize.x*0,patchSize.y*2},patchSize,GetRenderColor()); game->DrawPartialDecal(menuPos+vf2d{-patchSize.x,size.y},patchSize,GetPatchPart(0,2).Decal(),{patchSize.x*0,patchSize.y*2},patchSize,renderColor);
//Bottom-Right //Bottom-Right
game->DrawPartialDecal(menuPos+vf2d{size.x,size.y},patchSize,GetPatchPart(2,2).Decal(),{patchSize.x*2,patchSize.y*2},patchSize,GetRenderColor()); game->DrawPartialDecal(menuPos+vf2d{size.x,size.y},patchSize,GetPatchPart(2,2).Decal(),{patchSize.x*2,patchSize.y*2},patchSize,renderColor);
//Top //Top
game->DrawPartialDecal(menuPos+vf2d{0,-patchSize.y},vf2d{size.x,patchSize.y},GetPatchPart(1,0).Decal(),{patchSize.x*1,patchSize.y*0},patchSize,GetRenderColor()); game->DrawPartialDecal(menuPos+vf2d{0,-patchSize.y},vf2d{size.x,patchSize.y},GetPatchPart(1,0).Decal(),{patchSize.x*1,patchSize.y*0},patchSize,renderColor);
//Left //Left
game->DrawPartialDecal(menuPos+vf2d{-patchSize.x,0},vf2d{patchSize.x,size.y},GetPatchPart(0,1).Decal(),{patchSize.x*0,patchSize.y*1},patchSize,GetRenderColor()); game->DrawPartialDecal(menuPos+vf2d{-patchSize.x,0},vf2d{patchSize.x,size.y},GetPatchPart(0,1).Decal(),{patchSize.x*0,patchSize.y*1},patchSize,renderColor);
//Right //Right
game->DrawPartialDecal(menuPos+vf2d{size.x,0},vf2d{patchSize.x,size.y},GetPatchPart(2,1).Decal(),{patchSize.x*2,patchSize.y*1},patchSize,GetRenderColor()); game->DrawPartialDecal(menuPos+vf2d{size.x,0},vf2d{patchSize.x,size.y},GetPatchPart(2,1).Decal(),{patchSize.x*2,patchSize.y*1},patchSize,renderColor);
//Bottom //Bottom
game->DrawPartialDecal(menuPos+vf2d{0,size.y},vf2d{size.x,patchSize.y},GetPatchPart(1,2).Decal(),{patchSize.x*1,patchSize.y*2},patchSize,GetRenderColor()); game->DrawPartialDecal(menuPos+vf2d{0,size.y},vf2d{size.x,patchSize.y},GetPatchPart(1,2).Decal(),{patchSize.x*1,patchSize.y*2},patchSize,renderColor);
} }
void Menu::DrawTiledWindowBorder(Crawler*game,vf2d menuPos){ void Menu::DrawTiledWindowBorder(Crawler*game,vf2d menuPos,vf2d size,Pixel renderColor){
vf2d patchSize={"Interface.9PatchSize"_f[0],"Interface.9PatchSize"_f[1]}; vf2d patchSize={"Interface.9PatchSize"_f[0],"Interface.9PatchSize"_f[1]};
//Upper-Left //Upper-Left
game->DrawPartialDecal(menuPos-patchSize,patchSize,GetPatchPart(0,0).Decal(),{0,0},patchSize,GetRenderColor()); game->DrawPartialDecal(menuPos-patchSize,patchSize,GetPatchPart(0,0).Decal(),{0,0},patchSize,renderColor);
//Upper-Right //Upper-Right
game->DrawPartialDecal(menuPos+vf2d{size.x,-patchSize.y},patchSize,GetPatchPart(2,0).Decal(),{0,0},patchSize,GetRenderColor()); game->DrawPartialDecal(menuPos+vf2d{size.x,-patchSize.y},patchSize,GetPatchPart(2,0).Decal(),{0,0},patchSize,renderColor);
//Bottom-Left //Bottom-Left
game->DrawPartialDecal(menuPos+vf2d{-patchSize.x,size.y},patchSize,GetPatchPart(0,2).Decal(),{0,0},patchSize,GetRenderColor()); game->DrawPartialDecal(menuPos+vf2d{-patchSize.x,size.y},patchSize,GetPatchPart(0,2).Decal(),{0,0},patchSize,renderColor);
//Bottom-Right //Bottom-Right
game->DrawPartialDecal(menuPos+vf2d{size.x,size.y},patchSize,GetPatchPart(2,2).Decal(),{0,0},patchSize,GetRenderColor()); game->DrawPartialDecal(menuPos+vf2d{size.x,size.y},patchSize,GetPatchPart(2,2).Decal(),{0,0},patchSize,renderColor);
//Top //Top
game->DrawPartialDecal(menuPos+vf2d{0,-patchSize.y},vf2d{size.x,patchSize.y},GetPatchPart(1,0).Decal(),{0,0},vf2d{size.x,patchSize.y},GetRenderColor()); game->DrawPartialDecal(menuPos+vf2d{0,-patchSize.y},vf2d{size.x,patchSize.y},GetPatchPart(1,0).Decal(),{0,0},vf2d{size.x,patchSize.y},renderColor);
//Left //Left
game->DrawPartialDecal(menuPos+vf2d{-patchSize.x,0},vf2d{patchSize.x,size.y},GetPatchPart(0,1).Decal(),{0,0},vf2d{patchSize.x,size.y},GetRenderColor()); game->DrawPartialDecal(menuPos+vf2d{-patchSize.x,0},vf2d{patchSize.x,size.y},GetPatchPart(0,1).Decal(),{0,0},vf2d{patchSize.x,size.y},renderColor);
//Right //Right
game->DrawPartialDecal(menuPos+vf2d{size.x,0},vf2d{patchSize.x,size.y},GetPatchPart(2,1).Decal(),{0,0},vf2d{patchSize.x,size.y},GetRenderColor()); game->DrawPartialDecal(menuPos+vf2d{size.x,0},vf2d{patchSize.x,size.y},GetPatchPart(2,1).Decal(),{0,0},vf2d{patchSize.x,size.y},renderColor);
//Bottom //Bottom
game->DrawPartialDecal(menuPos+vf2d{0,size.y},vf2d{size.x,patchSize.y},GetPatchPart(1,2).Decal(),{0,0},vf2d{size.x,patchSize.y},GetRenderColor()); game->DrawPartialDecal(menuPos+vf2d{0,size.y},vf2d{size.x,patchSize.y},GetPatchPart(1,2).Decal(),{0,0},vf2d{size.x,patchSize.y},renderColor);
} }
void Menu::DrawScaledWindowBackground(Crawler*game,vf2d menuPos){ void Menu::DrawScaledWindowBackground(Crawler*game,vf2d menuPos,vf2d size,Pixel renderColor){
vf2d patchSize={"Interface.9PatchSize"_f[0],"Interface.9PatchSize"_f[1]}; vf2d patchSize={"Interface.9PatchSize"_f[0],"Interface.9PatchSize"_f[1]};
//Center //Center
if(GetCurrentTheme().HasBackground()){ if(GetCurrentTheme().HasBackground()){
Decal*back=GetCurrentTheme().GetBackground(); Decal*back=GetCurrentTheme().GetBackground();
game->DrawPartialDecal(menuPos,size,back,{0,0},back->sprite->Size(),GetRenderColor()); game->DrawPartialDecal(menuPos,size,back,{0,0},back->sprite->Size(),renderColor);
}else{ }else{
game->DrawPartialDecal(menuPos,size,GetPatchPart(1,1).Decal(),{patchSize.x*1,patchSize.y*1},patchSize,GetRenderColor()); game->DrawPartialDecal(menuPos,size,GetPatchPart(1,1).Decal(),{patchSize.x*1,patchSize.y*1},patchSize,renderColor);
} }
} }
void Menu::DrawTiledWindowBackground(Crawler*game,vf2d menuPos){ void Menu::DrawTiledWindowBackground(Crawler*game,vf2d menuPos,vf2d size,Pixel renderColor){
vf2d patchSize={"Interface.9PatchSize"_f[0],"Interface.9PatchSize"_f[1]}; vf2d patchSize={"Interface.9PatchSize"_f[0],"Interface.9PatchSize"_f[1]};
//Center //Center
if(GetCurrentTheme().HasBackground()){ if(GetCurrentTheme().HasBackground()){
Decal*back=GetCurrentTheme().GetBackground(); Decal*back=GetCurrentTheme().GetBackground();
game->DrawPartialDecal(menuPos,size,back,{0,0},size,GetRenderColor()); game->DrawPartialDecal(menuPos,size,back,{0,0},size,renderColor);
}else{ }else{
game->DrawPartialDecal(menuPos,size,GetPatchPart(1,1).Decal(),{0,0},patchSize,GetRenderColor()); game->DrawPartialDecal(menuPos,size,GetPatchPart(1,1).Decal(),{0,0},patchSize,renderColor);
} }
} }
@ -702,3 +703,13 @@ void Menu::CleanupAllMenus(){
} }
void Menu::Cleanup(){} void Menu::Cleanup(){}
void Menu::DrawThemedWindow(vf2d menuPos,vf2d size,Pixel renderColor){
if(GetCurrentTheme().IsScaled()){
DrawScaledWindowBackground(game,menuPos,size,renderColor);
DrawScaledWindowBorder(game,menuPos,size,renderColor);
}else{
DrawTiledWindowBackground(game,menuPos,size,renderColor);
DrawTiledWindowBorder(game,menuPos,size,renderColor);
}
}

@ -105,6 +105,8 @@ public:
//Returns the last menu type created and last registered component, in case a component is detected as memory leaking, provides this information to each component for safety. //Returns the last menu type created and last registered component, in case a component is detected as memory leaking, provides this information to each component for safety.
static std::pair<MenuType,std::string>GetMemoryLeakReportInfo(); static std::pair<MenuType,std::string>GetMemoryLeakReportInfo();
virtual void Cleanup(); virtual void Cleanup();
static void DrawThemedWindow(vf2d menuPos,vf2d size,Pixel renderColor=WHITE);
private: private:
Menu(vf2d pos,vf2d size); Menu(vf2d pos,vf2d size);
static MenuType lastMenuTypeCreated; static MenuType lastMenuTypeCreated;
@ -128,10 +130,10 @@ private:
static Renderable&GetPatchPart(int x,int y); static Renderable&GetPatchPart(int x,int y);
void KeyboardButtonNavigation(Crawler*game,vf2d menuPos); void KeyboardButtonNavigation(Crawler*game,vf2d menuPos);
void DrawScaledWindowBackground(Crawler*game,vf2d menuPos); static void DrawScaledWindowBackground(Crawler*game,vf2d menuPos,vf2d size,Pixel renderColor);
void DrawTiledWindowBackground(Crawler*game,vf2d menuPos); static void DrawTiledWindowBackground(Crawler*game,vf2d menuPos,vf2d size,Pixel renderColor);
void DrawScaledWindowBorder(Crawler*game,vf2d menuPos); static void DrawScaledWindowBorder(Crawler*game,vf2d menuPos,vf2d size,Pixel renderColor);
void DrawTiledWindowBorder(Crawler*game,vf2d menuPos); static void DrawTiledWindowBorder(Crawler*game,vf2d menuPos,vf2d size,Pixel renderColor);
//This triggers if we use a keyboard/controller input to try and select some off-screen menu item. We should ideally follow the menu cursor. //This triggers if we use a keyboard/controller input to try and select some off-screen menu item. We should ideally follow the menu cursor.
bool HandleOutsideDisabledButtonSelection(MenuComponent*disabledButton); bool HandleOutsideDisabledButtonSelection(MenuComponent*disabledButton);

@ -51,15 +51,6 @@ void Menu::InitializeOverworldMapLevelWindow(){
State_OverworldMap*overworldMap=(State_OverworldMap*)GameState::states[States::OVERWORLD_MAP]; //HACK ALERT!! We're going to make an assumption that we are in the overworld map state. State_OverworldMap*overworldMap=(State_OverworldMap*)GameState::states[States::OVERWORLD_MAP]; //HACK ALERT!! We're going to make an assumption that we are in the overworld map state.
//Map&loadedMap=MapHelper::MapFromString(overworldMap->GetCurrentConnectionPoint().map);
//std::set<int>&spawns=loadedMap.spawns;
/*int yOffset=40;
for(int key:spawns){
MenuLabel*testLabel=new MenuLabel(OVERWORLD_LEVEL_SELECT,{{0,float(yOffset)},{windowSize.x,24}},MONSTER_DATA[key].GetDisplayName());
yOffset+=28;
levelSelectWindow->AddComponent(MONSTER_DATA[key].GetDisplayName()+" Display Label",testLabel);
}*/
MenuLabel*chapterLabel=NEW MenuLabel(OVERWORLD_LEVEL_SELECT,{{0,4},{windowSize.x,16}},"Chapter",1,ComponentAttr::SHADOW|ComponentAttr::LEFT_ALIGN); MenuLabel*chapterLabel=NEW MenuLabel(OVERWORLD_LEVEL_SELECT,{{0,4},{windowSize.x,16}},"Chapter",1,ComponentAttr::SHADOW|ComponentAttr::LEFT_ALIGN);
MenuLabel*stageLabel=NEW MenuLabel(OVERWORLD_LEVEL_SELECT,{{0,24},{windowSize.x,16}},"Stage",1,ComponentAttr::SHADOW|ComponentAttr::LEFT_ALIGN); MenuLabel*stageLabel=NEW MenuLabel(OVERWORLD_LEVEL_SELECT,{{0,24},{windowSize.x,16}},"Stage",1,ComponentAttr::SHADOW|ComponentAttr::LEFT_ALIGN);
MenuLabel*panel1Back=NEW MenuLabel(OVERWORLD_LEVEL_SELECT,{{0,0},{windowSize.x-1,44}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE); MenuLabel*panel1Back=NEW MenuLabel(OVERWORLD_LEVEL_SELECT,{{0,0},{windowSize.x-1,44}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE);

@ -41,6 +41,7 @@ SUCH DAMAGE.
#include "drawutil.h" #include "drawutil.h"
#include "MenuLabel.h" #include "MenuLabel.h"
#include "EncountersSpawnListScrollableWindowComponent.h" #include "EncountersSpawnListScrollableWindowComponent.h"
#include "VisualNovel.h"
INCLUDE_MONSTER_LIST INCLUDE_MONSTER_LIST
INCLUDE_game INCLUDE_game
@ -51,6 +52,7 @@ State_OverworldMap::State_OverworldMap(){
SetStageMarker("Stage I-I"); //Eventually we will load the game from a file and this will not be necessary. We just set it to this for now. SetStageMarker("Stage I-I"); //Eventually we will load the game from a file and this will not be necessary. We just set it to this for now.
} }
void State_OverworldMap::OnStateChange(GameState*prevState){ void State_OverworldMap::OnStateChange(GameState*prevState){
game->LoadLevel(WORLD_MAP);
if(Menu::IsMenuOpen()){ if(Menu::IsMenuOpen()){
Menu::CloseAllMenus(); Menu::CloseAllMenus();
} }
@ -84,7 +86,7 @@ void State_OverworldMap::OnUserUpdate(Crawler*game){
for(int neighborInd:currentConnectionPoint->neighbors){ for(int neighborInd:currentConnectionPoint->neighbors){
if(neighborInd==-1)continue; if(neighborInd==-1)continue;
ConnectionPoint&neighbor=ConnectionPointFromIndex(neighborInd); ConnectionPoint&neighbor=ConnectionPointFromIndex(neighborInd);
if(Unlock::IsUnlocked(neighbor.name)&&&cp==&neighbor){ if(Unlock::IsUnlocked(neighbor.unlockCondition)&&&cp==&neighbor){
currentConnectionPoint=&neighbor; currentConnectionPoint=&neighbor;
playerTargetPos=currentConnectionPoint->rect.pos+currentConnectionPoint->rect.size/2+vf2d{0,16}; playerTargetPos=currentConnectionPoint->rect.pos+currentConnectionPoint->rect.size/2+vf2d{0,16};
float angleTo=util::angleTo(game->GetPlayer()->GetPos(),playerTargetPos); float angleTo=util::angleTo(game->GetPlayer()->GetPos(),playerTargetPos);
@ -141,6 +143,10 @@ ConnectionPoint&State_OverworldMap::GetCurrentConnectionPoint(){
} }
void State_OverworldMap::StartLevel(){ void State_OverworldMap::StartLevel(){
if(State_OverworldMap::GetCurrentConnectionPoint().map.starts_with("STORY")){
VisualNovel::LoadVisualNovel(State_OverworldMap::GetCurrentConnectionPoint().map);
}else{
game->LoadLevel(LEVEL_NAMES.at(State_OverworldMap::GetCurrentConnectionPoint().map)); game->LoadLevel(LEVEL_NAMES.at(State_OverworldMap::GetCurrentConnectionPoint().map));
GameState::ChangeState(States::GAME_RUN); GameState::ChangeState(States::GAME_RUN);
}
} }

@ -33,11 +33,14 @@ SUCH DAMAGE.
#pragma endregion #pragma endregion
#include "State_Story.h" #include "State_Story.h"
#include "VisualNovel.h" #include "VisualNovel.h"
#include "Menu.h"
void State_Story::OnStateChange(GameState*prevState){}; void State_Story::OnStateChange(GameState*prevState){
Menu::CloseAllMenus();
};
void State_Story::OnUserUpdate(Crawler*game){ void State_Story::OnUserUpdate(Crawler*game){
VisualNovel::Update(); VisualNovel::novel.Update();
}; };
void State_Story::Draw(Crawler*game){ void State_Story::Draw(Crawler*game){
VisualNovel::Draw(); VisualNovel::novel.Draw();
}; };

@ -32,20 +32,26 @@ SUCH DAMAGE.
*/ */
#pragma endregion #pragma endregion
#include "Unlock.h" #include "Unlock.h"
#include "State_OverworldMap.h"
std::set<std::string>Unlock::unlocks; std::set<std::string>Unlock::unlocks;
void Unlock::Initialize(){ void Unlock::Initialize(){
UnlockArea("WORLD_MAP"); UnlockArea("WORLD_MAP");
UnlockArea("CAMPAIGN_1_1");
} }
void Unlock::UnlockArea(std::string unlock){ void Unlock::UnlockArea(std::string mapName){
unlocks.insert(unlock); unlocks.insert(mapName);
} }
bool Unlock::IsUnlocked(std::string unlock){ bool Unlock::IsUnlocked(std::string mapName){
return unlocks.count(unlock); return unlocks.count(mapName);
} }
bool Unlock::IsUnlocked(ConnectionPoint&cp){ bool Unlock::IsUnlocked(ConnectionPoint&cp){
return unlocks.count(cp.unlockCondition); return unlocks.count(cp.unlockCondition);
} }
void Unlock::UnlockCurrentMap(){
UnlockArea(State_OverworldMap::GetCurrentConnectionPoint().map);
}

@ -41,7 +41,10 @@ class Unlock{
static std::set<std::string>unlocks; static std::set<std::string>unlocks;
static void Initialize(); static void Initialize();
public: public:
static void UnlockArea(std::string unlock); //Provide a map's actual name to trigger unlocks for all connected areas. You can get the current map you are on via State_OverworlMap::GetCurrentConnectionPoint().map
static bool IsUnlocked(std::string unlock); static void UnlockArea(std::string mapName);
//Uses the current map as the unlock criteria.
static void UnlockCurrentMap();
static bool IsUnlocked(std::string mapName);
static bool IsUnlocked(ConnectionPoint&cp); static bool IsUnlocked(ConnectionPoint&cp);
}; };

@ -35,7 +35,7 @@ SUCH DAMAGE.
#define VERSION_MAJOR 0 #define VERSION_MAJOR 0
#define VERSION_MINOR 2 #define VERSION_MINOR 2
#define VERSION_PATCH 1 #define VERSION_PATCH 1
#define VERSION_BUILD 3172 #define VERSION_BUILD 3212
#define stringify(a) stringify_(a) #define stringify(a) stringify_(a)
#define stringify_(a) #a #define stringify_(a) #a

@ -35,9 +35,16 @@ SUCH DAMAGE.
#include "GameState.h" #include "GameState.h"
#include "Crawler.h" #include "Crawler.h"
#include <fstream> #include <fstream>
#include "DEFINES.h"
#include "Unlock.h"
#include "Menu.h"
INCLUDE_game
INCLUDE_GFX
VisualNovel VisualNovel::novel; VisualNovel VisualNovel::novel;
safemap<std::string,std::vector<std::unique_ptr<Command>>>VisualNovel::storyLevelData; safemap<std::string,std::vector<std::unique_ptr<Command>>>VisualNovel::storyLevelData;
std::set<std::string>VisualNovel::graphicsToLoad;
void VisualNovel::Initialize(){ void VisualNovel::Initialize(){
for(int chapter=1;chapter<=6;chapter++){ for(int chapter=1;chapter<=6;chapter++){
@ -80,6 +87,17 @@ void VisualNovel::Initialize(){
case '{':{ //Start of a command. case '{':{ //Start of a command.
auto&data=storyLevelData.at(currentStory); auto&data=storyLevelData.at(currentStory);
auto AddImagesForLoading=[](std::vector<std::string>&arguments){
for(std::string&arg:arguments){
if(arg=="story_player_name"_S){
graphicsToLoad.insert("character_image_location"_S+"Player_F.png");
graphicsToLoad.insert("character_image_location"_S+"Player_M.png");
}else{
graphicsToLoad.insert("character_image_location"_S+arg+".png");
}
}
};
size_t spacePos=line.find(' '); size_t spacePos=line.find(' ');
std::vector<std::string>arguments; std::vector<std::string>arguments;
@ -97,12 +115,15 @@ void VisualNovel::Initialize(){
}else }else
if(line.find("{BACKGROUND")!=std::string::npos){//Background command if(line.find("{BACKGROUND")!=std::string::npos){//Background command
if(arguments.size()!=1)ERR("Arguments size is "<<arguments.size()<<". Expecting only 1 argument.") if(arguments.size()!=1)ERR("Arguments size is "<<arguments.size()<<". Expecting only 1 argument.")
graphicsToLoad.insert("story_background_image_location"_S+arguments[0]);
data.push_back(std::make_unique<BackgroundCommand>(arguments[0])); data.push_back(std::make_unique<BackgroundCommand>(arguments[0]));
}else }else
if(line.find("{LEFT")!=std::string::npos){//Left command if(line.find("{LEFT")!=std::string::npos){//Left command
AddImagesForLoading(arguments);
data.push_back(std::make_unique<LeftCommand>(arguments)); data.push_back(std::make_unique<LeftCommand>(arguments));
}else }else
if(line.find("{RIGHT")!=std::string::npos){//Right command if(line.find("{RIGHT")!=std::string::npos){//Right command
AddImagesForLoading(arguments);
data.push_back(std::make_unique<RightCommand>(arguments)); data.push_back(std::make_unique<RightCommand>(arguments));
}else }else
if(line.find("{PAUSE")!=std::string::npos){//Pause command if(line.find("{PAUSE")!=std::string::npos){//Pause command
@ -141,13 +162,51 @@ void VisualNovel::Initialize(){
}; };
void VisualNovel::LoadVisualNovel(std::string storyLevelName){ void VisualNovel::LoadVisualNovel(std::string storyLevelName){
novel.storyLevel=storyLevelName; novel.storyLevel=storyLevelName;
GameState::ChangeState(States::STORY); novel.activeText="";
novel.leftCharacters.clear();
novel.rightCharacters.clear();
novel.backgroundFilename="";
novel.commands.clear();
for(std::unique_ptr<Command>&command:storyLevelData.at(storyLevelName)){
novel.commands.push_back(command.get());
}
GameState::ChangeState(States::STORY,0.5f);
novel.ExecuteNextCommand();
novel.prevTheme=Menu::GetCurrentTheme().GetThemeName();
Menu::themeSelection="Purple";
} }
void VisualNovel::Update(){ void VisualNovel::Update(){
if(game->KEY_CONFIRM.Pressed()){
novel.ExecuteNextCommand();
}
locationDisplayTime=std::max(0.f,locationDisplayTime-game->GetElapsedTime());
}
void VisualNovel::ExecuteNextCommand(){
if(commandIndex<commands.size()){
commandIndex++;
commands[commandIndex-1]->Execute(novel);
}else{
Unlock::UnlockCurrentMap();
Menu::themeSelection=novel.prevTheme;
GameState::ChangeState(States::OVERWORLD_MAP,0.5f);
}
} }
void VisualNovel::Draw(){ void VisualNovel::Draw(){
if(backgroundFilename!=""){
game->DrawDecal({0,0},GFX["backgrounds/"+backgroundFilename].Decal());
}else{
game->FillRectDecal({0,0},game->GetScreenSize());
}
if(locationDisplayTime>0){
vi2d textSize=game->GetTextSizeProp(locationDisplayText)*2;
game->FillRectDecal(game->GetScreenSize()/2-textSize/2-vi2d{4,4},textSize+vi2d{8,8},BLACK);
game->DrawRectDecal(game->GetScreenSize()/2-textSize/2-vi2d{4,4},textSize+vi2d{8,8},WHITE);
game->DrawShadowStringPropDecal(game->GetScreenSize()/2-textSize/2,locationDisplayText,WHITE,VERY_DARK_BLUE,{2.f,2.f});
}
if(activeText.length()>0){
Menu::DrawThemedWindow({24.f,game->GetScreenSize().y-60.f},{48.f,-12.f});
Menu::DrawThemedWindow({24.f,game->GetScreenSize().y-48.f},{game->GetScreenSize().x-48.f,20.f});
}
} }
VisualNovel::VisualNovel(){} VisualNovel::VisualNovel(){}
@ -155,60 +214,49 @@ VisualNovel::VisualNovel(){}
Command::Command(){} Command::Command(){}
void LocationCommand::Execute(VisualNovel&vn){ void LocationCommand::Execute(VisualNovel&vn){
vn.locationDisplayTime=5.f;
vn.locationDisplayText=location;
vn.ExecuteNextCommand();
} }
LocationCommand::LocationCommand(std::string location) LocationCommand::LocationCommand(std::string location)
:location(location){ :location(location){}
}
void BackgroundCommand::Execute(VisualNovel&vn){ void BackgroundCommand::Execute(VisualNovel&vn){
vn.backgroundFilename=backgroundFilename;
vn.ExecuteNextCommand();
} }
BackgroundCommand::BackgroundCommand(std::string backgroundFilename) BackgroundCommand::BackgroundCommand(std::string backgroundFilename)
:backgroundFilename(backgroundFilename){ :backgroundFilename(backgroundFilename){}
}
void LeftCommand::Execute(VisualNovel&vn){ void LeftCommand::Execute(VisualNovel&vn){
vn.leftCharacters=characters;
vn.ExecuteNextCommand();
} }
LeftCommand::LeftCommand(std::vector<std::string>characters) LeftCommand::LeftCommand(std::vector<std::string>characters)
:characters(characters){ :characters(characters){}
}
void RightCommand::Execute(VisualNovel&vn){ void RightCommand::Execute(VisualNovel&vn){
vn.rightCharacters=characters;
vn.ExecuteNextCommand();
} }
RightCommand::RightCommand(std::vector<std::string>characters) RightCommand::RightCommand(std::vector<std::string>characters)
:characters(characters){ :characters(characters){}
}
void SpeakerCommand::Execute(VisualNovel&vn){ void SpeakerCommand::Execute(VisualNovel&vn){
vn.speakerDisplayName=displayedName;
vn.actualSpeakerName=actualSpeakerName;
vn.ExecuteNextCommand();
} }
SpeakerCommand::SpeakerCommand(std::string speaker) SpeakerCommand::SpeakerCommand(std::string speaker)
:displayedName(speaker),actualSpeakerName(speaker){ :displayedName(speaker),actualSpeakerName(speaker){}
}
SpeakerCommand::SpeakerCommand(std::string displayedName,std::string speaker) SpeakerCommand::SpeakerCommand(std::string displayedName,std::string speaker)
:displayedName(displayedName),actualSpeakerName(speaker){ :displayedName(displayedName),actualSpeakerName(speaker){}
}
void DialogCommand::Execute(VisualNovel&vn){ void DialogCommand::Execute(VisualNovel&vn){
vn.activeText=dialog;
} }
DialogCommand::DialogCommand(std::string dialog) DialogCommand::DialogCommand(std::string dialog)
:dialog(dialog){ :dialog(dialog){}
}
void PauseCommand::Execute(VisualNovel&vn){
} void PauseCommand::Execute(VisualNovel&vn){}
PauseCommand::PauseCommand(){ PauseCommand::PauseCommand(){}
}

@ -35,10 +35,12 @@ SUCH DAMAGE.
#include <vector> #include <vector>
#include <memory> #include <memory>
#include "safemap.h" #include "safemap.h"
#include <set>
class VisualNovel; class VisualNovel;
class Command{ class Command{
friend class VisualNovel;
virtual void Execute(VisualNovel&vn)=0; virtual void Execute(VisualNovel&vn)=0;
protected: protected:
Command(); Command();
@ -95,14 +97,30 @@ public:
}; };
class VisualNovel{ class VisualNovel{
friend class State_Story;
friend class Crawler;
friend class Command;
friend class LocationCommand;
friend class BackgroundCommand;
friend class LeftCommand;
friend class RightCommand;
friend class SpeakerCommand;
friend class DialogCommand;
friend class PauseCommand;
std::string storyLevel; std::string storyLevel;
std::string speakerDisplayName="";
std::string actualSpeakerName="";
std::string activeText; std::string activeText;
std::vector<std::string>leftCharacters; std::vector<std::string>leftCharacters;
std::vector<std::string>rightCharacters; std::vector<std::string>rightCharacters;
std::string backgroundFilename; std::string backgroundFilename;
std::vector<Command*>commands; std::vector<Command*>commands;
int commandIndex=0; int commandIndex=0;
std::string locationDisplayText="";
float locationDisplayTime=0;
std::string prevTheme="";
static std::set<std::string>graphicsToLoad;
static safemap<std::string,std::vector<std::unique_ptr<Command>>>storyLevelData; static safemap<std::string,std::vector<std::unique_ptr<Command>>>storyLevelData;
static VisualNovel novel; static VisualNovel novel;
@ -112,6 +130,7 @@ public:
VisualNovel(VisualNovel&&)=delete; VisualNovel(VisualNovel&&)=delete;
static void Initialize(); static void Initialize();
static void LoadVisualNovel(std::string storyLevelName); static void LoadVisualNovel(std::string storyLevelName);
static void Update(); void ExecuteNextCommand();
static void Draw(); void Update();
void Draw();
}; };

Before

Width:  |  Height:  |  Size: 1004 B

After

Width:  |  Height:  |  Size: 1004 B

@ -51,6 +51,15 @@ item_img_directory = items/
# Path to story files # Path to story files
story_directory = config/story/ story_directory = config/story/
# Path to character images
character_image_location = characters/
# Path to story backgrounds
story_background_image_location = backgrounds/
# The name substituted for the player in dialogs
story_player_name = You
# Whether or not to show individual data accesses from config data structure. # Whether or not to show individual data accesses from config data structure.
debug_access_options = 0 debug_access_options = 0

@ -30,7 +30,7 @@ Themes
BlueDefault BlueDefault
{ {
Name = 9patch filename = 9patch
ButtonColor = 0,0,64,255 ButtonColor = 0,0,64,255
HighlightColor = 0,200,200,255 HighlightColor = 0,200,200,255
@ -43,7 +43,7 @@ Themes
} }
Purple Purple
{ {
Name = 9patch_2 filename = 9patch_2
ButtonColor = 40,16,71,255 ButtonColor = 40,16,71,255
HighlightColor = 192,128,238,255 HighlightColor = 192,128,238,255
@ -56,7 +56,7 @@ Themes
} }
NicoPink NicoPink
{ {
Name = 9patch_3 filename = 9patch_3
ButtonColor = 208,73,182,255 ButtonColor = 208,73,182,255
HighlightColor = 255,239,232,255 HighlightColor = 255,239,232,255
@ -69,7 +69,7 @@ Themes
} }
NicoPinkTiled NicoPinkTiled
{ {
Name = 9patch_4 filename = 9patch_4
ButtonColor = 208,73,182,255 ButtonColor = 208,73,182,255
HighlightColor = 255,239,232,255 HighlightColor = 255,239,232,255

@ -1,10 +0,0 @@
character_image_location = assets/characters
Characters
{
Player_F = player_f.png
Player_M = player_m.png
Sherman = sherman.png
Greg = greg.png
Red Stone = red_stone.png
}
Loading…
Cancel
Save