diff --git a/Adventures in Lestoria/Adventures in Lestoria.vcxproj b/Adventures in Lestoria/Adventures in Lestoria.vcxproj index 1b8da299..b76d56b3 100644 --- a/Adventures in Lestoria/Adventures in Lestoria.vcxproj +++ b/Adventures in Lestoria/Adventures in Lestoria.vcxproj @@ -415,6 +415,7 @@ + diff --git a/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters b/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters index 9d7625bf..328af5ab 100644 --- a/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters +++ b/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters @@ -633,6 +633,9 @@ Header Files + + Header Files + diff --git a/Adventures in Lestoria/AdventuresInLestoria.cpp b/Adventures in Lestoria/AdventuresInLestoria.cpp index 85cef9c4..f8effe9b 100644 --- a/Adventures in Lestoria/AdventuresInLestoria.cpp +++ b/Adventures in Lestoria/AdventuresInLestoria.cpp @@ -261,15 +261,6 @@ bool AiL::OnUserCreate(){ VisualNovel::Initialize(); - InitializeLevels(); - - //Initialize Camera. - camera=Camera2D{WINDOW_SIZE}; - camera.SetMode(olc::utils::Camera2D::Mode::LazyFollow); - camera.SetTarget(player->GetPos()); - camera.SetWorldBoundary({0,0},GetCurrentMap().MapData.MapSize*GetCurrentMap().MapData.TileSize); - camera.EnableWorldBoundary(false); - ItemAttribute::Initialize(); ItemInfo::InitializeItems(); @@ -290,6 +281,15 @@ bool AiL::OnUserCreate(){ MonsterData::InitializeMonsterData(); MonsterData::InitializeNPCData(); + InitializeLevels(); + + //Initialize Camera. + camera=Camera2D{WINDOW_SIZE}; + camera.SetMode(olc::utils::Camera2D::Mode::LazyFollow); + camera.SetTarget(player->GetPos()); + camera.SetWorldBoundary({0,0},GetCurrentMap().MapData.MapSize*GetCurrentMap().MapData.TileSize); + camera.EnableWorldBoundary(false); + sig::Animation::SetupPlayerAnimations(); view=TileTransformedView{GetScreenSize(),{1,1}}; diff --git a/Adventures in Lestoria/Monster.h b/Adventures in Lestoria/Monster.h index a7943f98..15f907e3 100644 --- a/Adventures in Lestoria/Monster.h +++ b/Adventures in Lestoria/Monster.h @@ -42,11 +42,11 @@ All rights reserved. #include "olcUTIL_Animate2D.h" #include "DEFINES.h" #include "Attributable.h" -#include "Item.h" #include "safemap.h" #include "Pathfinding.h" #include "GameEvent.h" #include "TMXParser.h" +#include "MonsterData.h" INCLUDE_ITEM_DATA @@ -62,62 +62,6 @@ enum class MonsterAnimation{ DEATH }; -struct MonsterDropData{ - ItemInfo*item; - float dropChance; - int minQty=1; - int maxQty=1; - MonsterDropData(std::string itemName,float dropChance,int minQty=1,int maxQty=1) - :item(&ITEM_DATA.at(itemName)),dropChance(dropChance),minQty(minQty),maxQty(maxQty){} -}; - -struct MonsterData{ -private: - std::string name; - int hp; - int atk; - uint32_t xp; - float moveSpd;//1.0=100% - float size; - std::vector animations; - std::string strategy; - int collisionDmg; - std::string jumpAnimation="WARRIOR_IDLE_S"; - std::string shootAnimation="WARRIOR_IDLE_S"; - std::string deathAnimation="WARRIOR_IDLE_S"; - EventName hurtSound=""; - EventName deathSound=""; - EventName walkSound=""; - std::vector dropData; - bool isNPC=false; -public: - MonsterData(); - MonsterData(std::string name,int hp,int atk,const uint32_t xp,std::vectoranimations,std::vectordrops,float moveSpd=1.0f,float size=1.0f,std::string strategy="Run Towards",int collisionDmg=0); - int GetHealth(); - int GetAttack(); - const uint32_t GetXP()const; - float GetMoveSpdMult(); - float GetSizeMult(); - const std::string&GetAIStrategy()const; - int GetCollisionDmg(); - std::string GetIdleAnimation(); - std::string GetJumpAnimation(); - std::string GetShootAnimation(); - std::string GetDeathAnimation(); - const EventName&GetHurtSound(); - const EventName&GetDeathSound(); - const EventName&GetWalkSound(); - const bool IsNPC()const; - std::vectorGetAnimations(){ - return animations; - } - const std::vector&GetDropData(); - std::string GetDisplayName(); - static void InitializeMonsterData(); - static void InitializeNPCData(); - static std::mapimgs; -}; - class GameEvent; class Monster:IAttributable{ diff --git a/Adventures in Lestoria/MonsterData.h b/Adventures in Lestoria/MonsterData.h new file mode 100644 index 00000000..0c127c1d --- /dev/null +++ b/Adventures in Lestoria/MonsterData.h @@ -0,0 +1,98 @@ +#pragma region License +/* +License (OLC-3) +~~~~~~~~~~~~~~~ + +Copyright 2024 Joshua Sigona + +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 © 2024 The FreeType +Project (www.freetype.org). Please see LICENSE_FT.txt for more information. +All rights reserved. +*/ +#pragma endregion +#pragma once +#include "DEFINES.h" +#include "Item.h" + +INCLUDE_ITEM_DATA + +struct MonsterDropData{ + ItemInfo*item; + float dropChance; + int minQty=1; + int maxQty=1; + MonsterDropData(std::string itemName,float dropChance,int minQty=1,int maxQty=1) + :item(&ITEM_DATA.at(itemName)),dropChance(dropChance),minQty(minQty),maxQty(maxQty){} +}; + +struct MonsterData{ +private: + std::string name; + int hp; + int atk; + uint32_t xp; + float moveSpd;//1.0=100% + float size; + std::vector animations; + std::string strategy; + int collisionDmg; + std::string jumpAnimation="WARRIOR_IDLE_S"; + std::string shootAnimation="WARRIOR_IDLE_S"; + std::string deathAnimation="WARRIOR_IDLE_S"; + EventName hurtSound=""; + EventName deathSound=""; + EventName walkSound=""; + std::vector dropData; + bool isNPC=false; +public: + MonsterData(); + MonsterData(std::string name,int hp,int atk,const uint32_t xp,std::vectoranimations,std::vectordrops,float moveSpd=1.0f,float size=1.0f,std::string strategy="Run Towards",int collisionDmg=0); + int GetHealth(); + int GetAttack(); + const uint32_t GetXP()const; + float GetMoveSpdMult(); + float GetSizeMult(); + const std::string&GetAIStrategy()const; + int GetCollisionDmg(); + std::string GetIdleAnimation(); + std::string GetJumpAnimation(); + std::string GetShootAnimation(); + std::string GetDeathAnimation(); + const EventName&GetHurtSound(); + const EventName&GetDeathSound(); + const EventName&GetWalkSound(); + const bool IsNPC()const; + std::vectorGetAnimations(){ + return animations; + } + const std::vector&GetDropData(); + std::string GetDisplayName(); + static void InitializeMonsterData(); + static void InitializeNPCData(); + static std::mapimgs; +}; \ No newline at end of file diff --git a/Adventures in Lestoria/TMXParser.h b/Adventures in Lestoria/TMXParser.h index ccc590ef..7f4acad9 100644 --- a/Adventures in Lestoria/TMXParser.h +++ b/Adventures in Lestoria/TMXParser.h @@ -45,7 +45,9 @@ All rights reserved. #include "safemap.h" #include "ItemMapData.h" #include "Class.h" +#include "MonsterData.h" +INCLUDE_MONSTER_DATA using MapName=std::string; using namespace olc; @@ -61,7 +63,7 @@ struct XMLTag{ float GetFloat(std::string dataTag); double GetDouble(std::string dataTag); bool GetBool(std::string dataTag); - std::string GetString(std::string dataTag); + std::string GetString(std::string dataTag)const; }; struct ForegroundTileTag:public XMLTag{ @@ -224,13 +226,13 @@ class TMXParser{ double XMLTag::GetDouble(std::string dataTag) { return std::stod(data[dataTag]); } - std::string XMLTag::GetString(std::string dataTag) { - return data[dataTag]; + std::string XMLTag::GetString(std::string dataTag)const{ + return data.at(dataTag); } bool XMLTag::GetBool(std::string dataTag) { if (data[dataTag]=="0"||data[dataTag]=="false") { return false; - } else { + }else{ return true; } } @@ -246,7 +248,7 @@ class TMXParser{ bool Property::GetBool() { if (value=="0") { return false; - } else { + }else{ return true; } } @@ -396,7 +398,7 @@ class TMXParser{ #if _DEBUG if(_DEBUG_MAP_LOAD_INFO)LOG("Tag: "<unlockCondition=newTag.data["value"]; - } else + }else if(newTag.tag=="property"&&newTag.data["name"]=="Upper?"&&prevZoneData!=nullptr){ prevZoneData->isUpper=newTag.GetBool("value"); }else if (newTag.tag=="property"&&newTag.data["name"]=="Optimize"&&newTag.data["value"]=="true") { parsedMapInfo.MapData.optimized=true; - } else + }else if (newTag.tag=="property"&&newTag.data["name"]=="Boss Title Display") { parsedMapInfo.SpawnerData[prevSpawner].bossNameDisplay=newTag.data["value"]; - } else + }else if (newTag.tag=="property"&&newTag.data["name"]=="Level Type") { parsedMapInfo.mapType=newTag.data["value"]; - } else + }else if (newTag.tag=="property"&&newTag.data["name"]=="Background Music") { if(newTag.data["value"]!="None"){ //None is a default value that we ignore. parsedMapInfo.bgmSongName=newTag.data["value"]; } - } else + }else if (newTag.tag=="property"&&newTag.data["name"].starts_with("Dev Completion Time")) { if(newTag.data.count("value")){ //None is a default value that we ignore. size_t classStartPos="Dev Completion Time - "s.length(); std::string className=newTag.data["name"].substr(classStartPos,newTag.data["name"].find(' ',classStartPos)-classStartPos); parsedMapInfo.devCompletionTrialTime[classutils::StringToClass(className)]=newTag.GetFloat("value"); } - } else + }else if (newTag.tag=="property"&&newTag.data["name"]=="Backdrop") { if(newTag.data["value"]!="None"){ //None is a default value that we ignore. parsedMapInfo.backdrop=newTag.data["value"]; } - } else + }else if (newTag.tag=="object"&&newTag.data["type"]=="AudioEnvironmentalSound") { parsedMapInfo.environmentalAudioData.emplace_back(); prevAudioData=&parsedMapInfo.environmentalAudioData.back(); prevAudioData->SetPos({newTag.GetFloat("x"),newTag.GetFloat("y")}); - } else + }else if (newTag.tag=="property"&&newTag.data["propertytype"]=="EnvironmentalSounds") { if(newTag.data["value"]!="None"){ //None is a default value that we ignore. prevAudioData->SetAudioName(newTag.data["value"]); } - } else + }else if (newTag.tag=="object"&&newTag.data["type"]=="PlayerSpawnLocation") { float width=1.f; float height=1.f; if(newTag.data.count("width")>0)width=newTag.GetFloat("width"); if(newTag.data.count("height")>0)height=newTag.GetFloat("height"); parsedMapInfo.MapData.playerSpawnLocation={int(newTag.GetFloat("x")-width/2),int(newTag.GetFloat("y")-height/2)}; - } else + }else if (newTag.tag=="object"&&newTag.data["type"]=="NPC") { if(inNPCTag)parsedMapInfo.npcs.push_back(NPCData{npcTag}); npcTag=newTag; inNPCTag=true; } else - if (newTag.tag=="object"&&newTag.data["type"]=="Monster") { + if (newTag.tag=="object"&&newTag.data["template"].starts_with("../maps/Monsters")) { monsterTag=newTag; monsterPropertyTagCount=0; - } else + }else if (newTag.tag=="property"&&inNPCTag) { npcTag.data[newTag.data["name"]]=newTag.data["value"]; - } + }else if (newTag.tag=="property"&&monsterPropertyTagCount==0) { - if(newTag.data["value"]=="None")ERR(std::format("WARNING! Invalid monster type provided: {} in map {}",newTag.data["value"],fileName)); - monsterTag.data["value"]=newTag.data["value"]; - parsedMapInfo.spawns.insert(newTag.GetString("value")); - monsterPropertyTagCount++; - } else - if (newTag.tag=="property"&&monsterPropertyTagCount==1) { + std::string monsterName=ParseMonsterTemplateName(monsterTag); + if(!MONSTER_DATA.count(monsterName))ERR(std::format("WARNING! Could not find monster type {}",monsterName)); + parsedMapInfo.spawns.insert(monsterName); spawnerLinkTag=newTag; + monsterTag.data["value"]=monsterName; monsterTag.data["spawnerLink"]=spawnerLinkTag.data["value"]; accumulatedMonsterTags.push_back(monsterTag); monsterPropertyTagCount=-1; - } else + }else if (newTag.tag=="object"&&newTag.data["type"]=="StagePlate") { if(newTag.GetInteger("id")!=0){ stagePlates[newTag.GetInteger("id")]={newTag}; currentStagePlate=&stagePlates.at(newTag.GetInteger("id")); } - } else + }else if(newTag.tag=="property"&¤tStagePlate!=nullptr){ currentStagePlate->properties[newTag.data["name"]]={newTag.data["name"],newTag.data["value"]}; }else @@ -586,7 +596,7 @@ class TMXParser{ if(accumulator.length()>1&&accumulator.find('>')!=std::string::npos){ accumulator=""; //Restart because this tag has nothing in it! } - } else { + }else{ //Start reading in data for this layer. std::vectorrowData; while (data.find(",")!=std::string::npos) { diff --git a/Adventures in Lestoria/Version.h b/Adventures in Lestoria/Version.h index 8e43dc0b..4c07c0d5 100644 --- a/Adventures in Lestoria/Version.h +++ b/Adventures in Lestoria/Version.h @@ -39,7 +39,7 @@ All rights reserved. #define VERSION_MAJOR 1 #define VERSION_MINOR 2 #define VERSION_PATCH 0 -#define VERSION_BUILD 8926 +#define VERSION_BUILD 8944 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Adventures in Lestoria/assets/Campaigns/1_2.tmx b/Adventures in Lestoria/assets/Campaigns/1_2.tmx index c6a003fb..7eb4e972 100644 --- a/Adventures in Lestoria/assets/Campaigns/1_2.tmx +++ b/Adventures in Lestoria/assets/Campaigns/1_2.tmx @@ -885,14 +885,34 @@ - + + + + + - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/Adventures in Lestoria/assets/Campaigns/1_8.tmx b/Adventures in Lestoria/assets/Campaigns/1_8.tmx index 1e58c2c6..39c93fb4 100644 --- a/Adventures in Lestoria/assets/Campaigns/1_8.tmx +++ b/Adventures in Lestoria/assets/Campaigns/1_8.tmx @@ -675,7 +675,11 @@ - + + + + + diff --git a/Adventures in Lestoria/assets/Campaigns/Intro_Map.tmx b/Adventures in Lestoria/assets/Campaigns/Intro_Map.tmx index c1c96a1f..614a513b 100644 --- a/Adventures in Lestoria/assets/Campaigns/Intro_Map.tmx +++ b/Adventures in Lestoria/assets/Campaigns/Intro_Map.tmx @@ -1331,7 +1331,11 @@ - + + + + + diff --git a/x64/Release/Adventures in Lestoria.exe b/x64/Release/Adventures in Lestoria.exe index c78869e3..a56fad35 100644 Binary files a/x64/Release/Adventures in Lestoria.exe and b/x64/Release/Adventures in Lestoria.exe differ