diff --git a/Crawler/Crawler.cpp b/Crawler/Crawler.cpp
index a14d6257..5fd69fea 100644
--- a/Crawler/Crawler.cpp
+++ b/Crawler/Crawler.cpp
@@ -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: "<
+
+
+
+
diff --git a/Crawler/Crawler.vcxproj.filters b/Crawler/Crawler.vcxproj.filters
index 58a90e28..7da615e8 100644
--- a/Crawler/Crawler.vcxproj.filters
+++ b/Crawler/Crawler.vcxproj.filters
@@ -674,6 +674,9 @@
Source Files\Interface
+
+ Source Files\Interface
+
diff --git a/Crawler/MainMenuWindow.cpp b/Crawler/MainMenuWindow.cpp
index f6776e83..f37883a9 100644
--- a/Crawler/MainMenuWindow.cpp
+++ b/Crawler/MainMenuWindow.cpp
@@ -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){
diff --git a/Crawler/Menu.cpp b/Crawler/Menu.cpp
index 242e669f..6bb8a786 100644
--- a/Crawler/Menu.cpp
+++ b/Crawler/Menu.cpp
@@ -113,6 +113,7 @@ void Menu::InitializeMenus(){
InitializeConsumableCraftItemWindow();
InitializeSaveFileWindow();
InitializeLoadGameWindow();
+ InitializeUserIDWindow();
for(MenuType type=MenuType(int(MenuType::ENUM_START)+1);typeGetWrappedTextSizeProp(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.
}
diff --git a/Crawler/SaveFile.cpp b/Crawler/SaveFile.cpp
index d7543092..f1fd6c07 100644
--- a/Crawler/SaveFile.cpp
+++ b/Crawler/SaveFile.cpp
@@ -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- 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
- 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());
+ 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);
+ 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);
+ }
}
+ 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();
+
+ GameState::ChangeState(States::OVERWORLD_MAP,0.5f);
+ }else{
+ std::cout<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();
-
- GameState::ChangeState(States::OVERWORLD_MAP,0.5f);
- }else{
- std::cout<
+
+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;
+}
\ No newline at end of file
diff --git a/Crawler/Version.h b/Crawler/Version.h
index b01f7ba9..cafac076 100644
--- a/Crawler/Version.h
+++ b/Crawler/Version.h
@@ -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
diff --git a/Crawler/assets/config/configuration.txt b/Crawler/assets/config/configuration.txt
index d2a3294b..0c9424e8 100644
--- a/Crawler/assets/config/configuration.txt
+++ b/Crawler/assets/config/configuration.txt
@@ -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
\ No newline at end of file
+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.
\ No newline at end of file
diff --git a/Crawler/config.h b/Crawler/config.h
index be752d37..4665069a 100644
--- a/Crawler/config.h
+++ b/Crawler/config.h
@@ -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.
diff --git a/Crawler/emscripten_build.ps1 b/Crawler/emscripten_build.ps1
index 82d0964e..299cb300 100644
--- a/Crawler/emscripten_build.ps1
+++ b/Crawler/emscripten_build.ps1
@@ -1,3 +1,12 @@
cd ..
./emscripten_build.ps1
-./emscripten_run.ps1
\ No newline at end of file
+if( -not $? )
+{
+ $msg = $Error[0].Exception.Message
+ "$msg"
+ exit
+}
+else
+{
+ ./emscripten_run.ps1
+}
\ No newline at end of file
diff --git a/Crawler/olcPixelGameEngine.h b/Crawler/olcPixelGameEngine.h
index fa91d63f..df64b5b2 100644
--- a/Crawler/olcPixelGameEngine.h
+++ b/Crawler/olcPixelGameEngine.h
@@ -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;
diff --git a/Crawler/olcUTIL_DataFile.h b/Crawler/olcUTIL_DataFile.h
index a07f4806..ffcd8df8 100644
--- a/Crawler/olcUTIL_DataFile.h
+++ b/Crawler/olcUTIL_DataFile.h
@@ -61,8 +61,11 @@ David Barr, aka javidx9, �OneLoneCoder 2019, 2020, 2021, 2022
#include
#include
#include
+#include
#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
{