Add in emscripten-specific branching menus and special load/save routines for online saving.
This commit is contained in:
parent
2a900fa06e
commit
497db80b9b
@ -238,8 +238,6 @@ bool Crawler::OnUserCreate(){
|
||||
#ifndef __EMSCRIPTEN__
|
||||
SetupDiscord();
|
||||
#endif
|
||||
|
||||
SendRequest("index.html","");
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -2568,4 +2566,9 @@ void Crawler::ResetGame(){
|
||||
|
||||
void Crawler::OnRequestCompleted(const std::string_view receivedData)const{
|
||||
std::cout<<"Received in engine: "<<receivedData<<std::endl;
|
||||
}
|
||||
|
||||
std::string operator ""_FS(const char*key,std::size_t len){
|
||||
Crawler::OutputDebugInfo(key,len);
|
||||
return DATA.GetProperty(std::string(key,len)).GetFullString();
|
||||
}
|
@ -612,6 +612,10 @@
|
||||
<ClCompile Include="Trapper.cpp" />
|
||||
<ClCompile Include="Turret.cpp" />
|
||||
<ClCompile Include="Unlock.cpp" />
|
||||
<ClCompile Include="UserIDMenu.cpp">
|
||||
<SubType>
|
||||
</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="VisualNovel.cpp" />
|
||||
<ClCompile Include="Warrior.cpp" />
|
||||
<ClCompile Include="util.cpp" />
|
||||
|
@ -674,6 +674,9 @@
|
||||
<ClCompile Include="LoadGameWindow.cpp">
|
||||
<Filter>Source Files\Interface</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="UserIDMenu.cpp">
|
||||
<Filter>Source Files\Interface</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="cpp.hint" />
|
||||
|
@ -49,7 +49,11 @@ void Menu::InitializeMainMenuWindow(){
|
||||
|
||||
mainMenuWindow->ADD("New Game Button",MenuComponent)({{12,4},{72,24}},"New Game",[](MenuFuncData data){
|
||||
game->TextEntryEnable(true);
|
||||
Menu::OpenMenu(SAVE_FILE_NAME);
|
||||
#ifdef __EMSCRIPTEN__
|
||||
Menu::OpenMenu(USER_ID);
|
||||
#else
|
||||
Menu::OpenMenu(SAVE_FILE_NAME);
|
||||
#endif
|
||||
return true;
|
||||
})END;
|
||||
mainMenuWindow->ADD("Load Game Button",MenuComponent)({{12,36},{72,24}},"Load Game",[](MenuFuncData data){
|
||||
|
@ -113,6 +113,7 @@ void Menu::InitializeMenus(){
|
||||
InitializeConsumableCraftItemWindow();
|
||||
InitializeSaveFileWindow();
|
||||
InitializeLoadGameWindow();
|
||||
InitializeUserIDWindow();
|
||||
|
||||
for(MenuType type=MenuType(int(MenuType::ENUM_START)+1);type<MenuType::ENUM_END;type=MenuType(int(type+1))){
|
||||
if(menus.count(type)==0){
|
||||
|
@ -79,6 +79,7 @@ enum MenuType{
|
||||
CONSUMABLE_CRAFT_ITEM,
|
||||
SAVE_FILE_NAME,
|
||||
LOAD_GAME,
|
||||
USER_ID,
|
||||
///////////////////////////////////////////////////////////
|
||||
/*DO NOT REMOVE!!*/ENUM_END////////////////////////////////
|
||||
///////////////////////////////////////////////////////////
|
||||
@ -104,6 +105,7 @@ class Menu:public IAttributable{
|
||||
static void InitializeConsumableCraftItemWindow();
|
||||
static void InitializeSaveFileWindow();
|
||||
static void InitializeLoadGameWindow();
|
||||
static void InitializeUserIDWindow();
|
||||
|
||||
friend class Crawler;
|
||||
friend struct Player;
|
||||
|
@ -78,8 +78,8 @@ protected:
|
||||
vf2d adjustedScale={scale,scale};
|
||||
vf2d labelTextSize=
|
||||
proportional?
|
||||
vf2d(game->GetWrappedTextSizeProp(label,rect.size.x,adjustedScale)):
|
||||
vf2d(game->GetWrappedTextSize(label,rect.size.x,adjustedScale));
|
||||
vf2d(game->GetWrappedTextSizeProp(label,rect.size.x-8,adjustedScale)):
|
||||
vf2d(game->GetWrappedTextSize(label,rect.size.x-8,adjustedScale));
|
||||
|
||||
if(fitToLabel){
|
||||
labelTextSize=
|
||||
@ -93,7 +93,7 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
vf2d drawPos=rect.middle()-vf2d{labelTextSize}/2; //Assume centered.
|
||||
vf2d drawPos=vf2d{-4.f,0.f}+rect.middle()-vf2d{labelTextSize}/2; //Assume centered.
|
||||
if(!centered){
|
||||
drawPos=vf2d{rect.pos.x+2,rect.middle().y-labelTextSize.y/2}; //We should at least vertically align here.
|
||||
}
|
||||
|
@ -114,55 +114,63 @@ const void SaveFile::SaveGame(){
|
||||
utils::datafile::Write(metadata,"save_file_path"_S+"metadata.dat");
|
||||
|
||||
utils::datafile::INITIAL_SETUP_COMPLETE=true;
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
Server_SaveFile();
|
||||
#endif
|
||||
}
|
||||
|
||||
const void SaveFile::LoadGame(){
|
||||
std::filesystem::create_directories("save_file_path"_S);
|
||||
utils::datafile loadFile;
|
||||
if(std::filesystem::exists("save_file_path"_S+std::format("save.{:04}",saveFileID))){
|
||||
utils::datafile::Read(loadFile,"save_file_path"_S+std::format("save.{:04}",saveFileID));
|
||||
game->ResetGame();
|
||||
for(auto&[key,data]:loadFile["Items"].GetOrderedKeys()){
|
||||
std::weak_ptr<Item>newItem=Inventory::AddItem(data["Item Name"].GetString(),data["Amt"].GetInt());
|
||||
newItem.lock()->enhancementLevel=data["Enhancement Level"].GetInt();
|
||||
if(loadFile.GetProperty(std::format("Items.{}",key)).HasProperty("Attributes")){
|
||||
for(auto&[attr,data]:loadFile.GetProperty(std::format("Items.{}.Attributes",key)).GetOrderedKeys()){
|
||||
newItem.lock()->randomizedStats.A(attr)=data.GetReal();
|
||||
#ifdef __EMSCRIPTEN__
|
||||
Server_GetFile();
|
||||
#else
|
||||
std::filesystem::create_directories("save_file_path"_S);
|
||||
utils::datafile loadFile;
|
||||
if(std::filesystem::exists("save_file_path"_S+std::format("save.{:04}",saveFileID))){
|
||||
utils::datafile::Read(loadFile,"save_file_path"_S+std::format("save.{:04}",saveFileID));
|
||||
game->ResetGame();
|
||||
for(auto&[key,data]:loadFile["Items"].GetOrderedKeys()){
|
||||
std::weak_ptr<Item>newItem=Inventory::AddItem(data["Item Name"].GetString(),data["Amt"].GetInt());
|
||||
newItem.lock()->enhancementLevel=data["Enhancement Level"].GetInt();
|
||||
if(loadFile.GetProperty(std::format("Items.{}",key)).HasProperty("Attributes")){
|
||||
for(auto&[attr,data]:loadFile.GetProperty(std::format("Items.{}.Attributes",key)).GetOrderedKeys()){
|
||||
newItem.lock()->randomizedStats.A(attr)=data.GetReal();
|
||||
}
|
||||
}
|
||||
if(data.HasProperty("LoadoutSlot")){
|
||||
uint8_t loadoutSlot=data["LoadoutSlot"].GetInt();
|
||||
if(loadoutSlot!=255){
|
||||
game->SetLoadoutItem(loadoutSlot,newItem.lock()->ActualName());
|
||||
}
|
||||
}
|
||||
|
||||
EquipSlot slot=EquipSlot(loadFile.GetProperty(std::format("Items.{}.Equip Slot",key)).GetInt());
|
||||
if(slot!=EquipSlot::NONE){ //This should be equipped somewhere!
|
||||
Inventory::EquipItem(newItem,slot);
|
||||
}
|
||||
}
|
||||
if(data.HasProperty("LoadoutSlot")){
|
||||
uint8_t loadoutSlot=data["LoadoutSlot"].GetInt();
|
||||
if(loadoutSlot!=255){
|
||||
game->SetLoadoutItem(loadoutSlot,newItem.lock()->ActualName());
|
||||
}
|
||||
game->ChangePlayerClass(classutils::StringToClass(loadFile["Player"]["Class"].GetString()));
|
||||
game->GetPlayer()->level=loadFile["Player"]["Level"].GetInt();
|
||||
game->GetPlayer()->SetMoney(loadFile["Player"]["Money"].GetInt());
|
||||
game->GetPlayer()->currentLevelXP=loadFile["Player"]["Current EXP"].GetInt();
|
||||
game->GetPlayer()->totalXPEarned=loadFile["Player"]["Total EXP"].GetInt();
|
||||
for(auto&[key,data]:loadFile["Player"]["Base Stats"].GetOrderedKeys()){
|
||||
game->GetPlayer()->SetBaseStat(key,data.GetReal());
|
||||
}
|
||||
|
||||
EquipSlot slot=EquipSlot(loadFile.GetProperty(std::format("Items.{}.Equip Slot",key)).GetInt());
|
||||
if(slot!=EquipSlot::NONE){ //This should be equipped somewhere!
|
||||
Inventory::EquipItem(newItem,slot);
|
||||
for(const auto&[key,data]:loadFile["Unlocks"].GetOrderedKeys()){
|
||||
Unlock::UnlockArea(key);
|
||||
}
|
||||
}
|
||||
game->ChangePlayerClass(classutils::StringToClass(loadFile["Player"]["Class"].GetString()));
|
||||
game->GetPlayer()->level=loadFile["Player"]["Level"].GetInt();
|
||||
game->GetPlayer()->SetMoney(loadFile["Player"]["Money"].GetInt());
|
||||
game->GetPlayer()->currentLevelXP=loadFile["Player"]["Current EXP"].GetInt();
|
||||
game->GetPlayer()->totalXPEarned=loadFile["Player"]["Total EXP"].GetInt();
|
||||
for(auto&[key,data]:loadFile["Player"]["Base Stats"].GetOrderedKeys()){
|
||||
game->GetPlayer()->SetBaseStat(key,data.GetReal());
|
||||
}
|
||||
for(const auto&[key,data]:loadFile["Unlocks"].GetOrderedKeys()){
|
||||
Unlock::UnlockArea(key);
|
||||
}
|
||||
State_OverworldMap::SetStageMarker(loadFile["Overworld Map Location"].GetString());
|
||||
game->SetChapter(loadFile["Chapter"].GetInt());
|
||||
SaveFile::SetSaveFileName(loadFile["Save Name"].GetString());
|
||||
game->SetRuntime(loadFile["Game Time"].GetReal());
|
||||
game->GetPlayer()->RecalculateEquipStats();
|
||||
State_OverworldMap::SetStageMarker(loadFile["Overworld Map Location"].GetString());
|
||||
game->SetChapter(loadFile["Chapter"].GetInt());
|
||||
SaveFile::SetSaveFileName(loadFile["Save Name"].GetString());
|
||||
game->SetRuntime(loadFile["Game Time"].GetReal());
|
||||
game->GetPlayer()->RecalculateEquipStats();
|
||||
|
||||
GameState::ChangeState(States::OVERWORLD_MAP,0.5f);
|
||||
}else{
|
||||
std::cout<<std::format("WARNING! File {} does not exist for loading!","save_file_path"_S+std::format("save.{:04}",saveFileID))<<std::endl;
|
||||
}
|
||||
GameState::ChangeState(States::OVERWORLD_MAP,0.5f);
|
||||
}else{
|
||||
std::cout<<std::format("WARNING! File {} does not exist for loading!","save_file_path"_S+std::format("save.{:04}",saveFileID))<<std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
const std::string_view SaveFile::GetSaveFileName(){
|
||||
|
46
Crawler/UserIDMenu.cpp
Normal file
46
Crawler/UserIDMenu.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
#pragma region License
|
||||
/*
|
||||
License (OLC-3)
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Copyright 2024 Joshua Sigona <sigonasr2@gmail.com>
|
||||
|
||||
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 © 2023 The FreeType
|
||||
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
|
||||
All rights reserved.
|
||||
*/
|
||||
#pragma endregion
|
||||
|
||||
#include "Menu.h"
|
||||
#include "MenuLabel.h"
|
||||
|
||||
void Menu::InitializeUserIDWindow(){
|
||||
Menu*userIDWindow=CreateMenu(USER_ID,CENTERED,vi2d{144,96});
|
||||
|
||||
userIDWindow->ADD("User ID Creation Explanation",MenuLabel)({{0,0},{144,96}},"user_id_message"_FS+"\n\n"+"user_id_message2"_FS,1.f,ComponentAttr::SHADOW|ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE)END;
|
||||
}
|
@ -39,7 +39,7 @@ All rights reserved.
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 2
|
||||
#define VERSION_PATCH 1
|
||||
#define VERSION_BUILD 5283
|
||||
#define VERSION_BUILD 5285
|
||||
|
||||
#define stringify(a) stringify_(a)
|
||||
#define stringify_(a) #a
|
||||
|
@ -117,4 +117,8 @@ water_reflection_update_time = 0.5
|
||||
water_reflection_time_step = 0.6
|
||||
|
||||
# the amount of scaling done to the water reflection.
|
||||
water_reflection_scale_factor = 0.05
|
||||
water_reflection_scale_factor = 0.05
|
||||
|
||||
# The message displayed to the user about ID creation.
|
||||
user_id_message = You are playing the web build of this game. In order to save progress, we ask that you provide a unique username to identify your save data with.
|
||||
user_id_message2 = Only game save data will be stored.
|
@ -51,6 +51,8 @@ utils::datafilefloatdata operator ""_f(const char*key,std::size_t len);
|
||||
utils::datafiledoubledata operator ""_d(const char*key,std::size_t len);
|
||||
//Read a string key from the config.
|
||||
std::string operator ""_S(const char*key,std::size_t len);
|
||||
//Read a full string key from the config.
|
||||
std::string operator ""_FS(const char*key,std::size_t len);
|
||||
//Read an integer key from the config.
|
||||
int operator ""_I(const char*key,std::size_t len);
|
||||
//Read a float key from the config.
|
||||
|
@ -1,3 +1,12 @@
|
||||
cd ..
|
||||
./emscripten_build.ps1
|
||||
./emscripten_run.ps1
|
||||
if( -not $? )
|
||||
{
|
||||
$msg = $Error[0].Exception.Message
|
||||
"$msg"
|
||||
exit
|
||||
}
|
||||
else
|
||||
{
|
||||
./emscripten_run.ps1
|
||||
}
|
@ -3718,13 +3718,13 @@ namespace olc
|
||||
skip--;
|
||||
continue;
|
||||
}
|
||||
if(c==' '||c=='\t'){
|
||||
if(c==' '||c=='\t'||c=='\n'){
|
||||
drawingMarker.x+=lettersWidth;
|
||||
lettersWidth=0;
|
||||
wrappingOccurred=false;
|
||||
}
|
||||
if(wrappingOccurred){
|
||||
if(c!=' '&&c!='\t'){
|
||||
if(c!=' '&&c!='\t'&&c!='\n'){
|
||||
wrappingOccurred=false;
|
||||
maxWidth=std::max(maxWidth,drawingMarker.x);
|
||||
}else{
|
||||
@ -3835,7 +3835,7 @@ namespace olc
|
||||
skip--;
|
||||
continue;
|
||||
}
|
||||
if(c==' '||c=='\t'){
|
||||
if(c==' '||c=='\t'||c=='\n'){
|
||||
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||
DrawPartialSprite(vi2d(pos + drawingMarker), fontRenderable.Sprite(), vi2d(letter.sourcePos), vi2d(letter.sourceSize), scale, Sprite::Flip::NONE,letter.col);
|
||||
drawingMarker.x += 8.0f * scale;
|
||||
@ -3844,7 +3844,7 @@ namespace olc
|
||||
wrappingOccurred=false;
|
||||
}
|
||||
if(wrappingOccurred){
|
||||
if(c!=' '&&c!='\t'){
|
||||
if(c!=' '&&c!='\t'&&c!='\n'){
|
||||
wrappingOccurred=false;
|
||||
}else{
|
||||
continue;
|
||||
@ -3974,14 +3974,14 @@ namespace olc
|
||||
skip--;
|
||||
continue;
|
||||
}
|
||||
if(c==' '||c=='\t'){
|
||||
if(c==' '||c=='\t'||c=='\n'){
|
||||
drawingMarker.x+=lettersWidth;
|
||||
lettersWidth=0;
|
||||
wrappingOccurred=false;
|
||||
maxWidth=std::max(maxWidth,drawingMarker.x);
|
||||
}
|
||||
if(wrappingOccurred){
|
||||
if(c!=' '&&c!='\t'){
|
||||
if(c!=' '&&c!='\t'&&c!='\n'){
|
||||
wrappingOccurred=false;
|
||||
}else{
|
||||
continue;
|
||||
@ -4065,7 +4065,7 @@ namespace olc
|
||||
skip--;
|
||||
continue;
|
||||
}
|
||||
if(c==' '||c=='\t'){
|
||||
if(c==' '||c=='\t'||c=='\n'){
|
||||
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||
DrawPartialSprite(vi2d(pos + drawingMarker), GetFontSprite(), vi2d(letter.sourcePos), vi2d(letter.sourceSize), scale,Sprite::Flip::NONE, letter.col);
|
||||
drawingMarker.x += float(vFontSpacing[letter.c - 32].y) * scale;
|
||||
@ -4074,7 +4074,7 @@ namespace olc
|
||||
wrappingOccurred=false;
|
||||
}
|
||||
if(wrappingOccurred){
|
||||
if(c!=' '&&c!='\t'){
|
||||
if(c!=' '&&c!='\t'&&c!='\n'){
|
||||
wrappingOccurred=false;
|
||||
}else{
|
||||
continue;
|
||||
@ -7106,7 +7106,8 @@ namespace olc
|
||||
|
||||
|
||||
EM_ASM({
|
||||
|
||||
|
||||
requestResp="";
|
||||
// olc_ApsectRatio
|
||||
//
|
||||
// Used by olc_ResizeHandler to calculate the viewport from the
|
||||
@ -7347,7 +7348,6 @@ namespace olc
|
||||
olc::Platform::ptrPGE->olc_CoreUpdate();
|
||||
char*ptr=(char*)EM_ASM_PTR({
|
||||
if(requestResp!==""){
|
||||
console.log("Request received: "+requestResp);
|
||||
var newPtr=stringToNewUTF8(requestResp);
|
||||
requestResp="";
|
||||
return newPtr;
|
||||
|
@ -61,8 +61,11 @@ David Barr, aka javidx9, <20>OneLoneCoder 2019, 2020, 2021, 2022
|
||||
#include <fstream>
|
||||
#include <stack>
|
||||
#include <sstream>
|
||||
#include <numeric>
|
||||
#include "Error.h"
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
int operator ""_I(const char*key,std::size_t len);
|
||||
|
||||
namespace olc::utils
|
||||
@ -96,6 +99,18 @@ namespace olc::utils
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieves the String Value of a Property, to include all values that are normally separated by the list separator.
|
||||
inline const std::string GetFullString() const
|
||||
{
|
||||
return std::accumulate(m_vContent.begin(),m_vContent.end(),""s,[](std::string str,const std::string&data){
|
||||
if(str.size()==0){
|
||||
return std::move(str)+data;
|
||||
}else{
|
||||
return std::move(str)+","+data;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Retrieves the Real Value of a Property (for a given index) or 0.0
|
||||
inline const double GetReal(const size_t nItem = 0) const
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user