sigonasr2 1 year ago
commit 62cfe67119
  1. 3
      .vscode/settings.json
  2. 102
      Adventures in Lestoria/AdventuresInLestoria.cpp
  3. 2
      Adventures in Lestoria/DamageNumber.cpp
  4. 14
      Adventures in Lestoria/Error.h
  5. 15
      Adventures in Lestoria/Monster.cpp
  6. 7
      Adventures in Lestoria/Monster.h
  7. 1
      Adventures in Lestoria/MonsterAttribute.h
  8. 3
      Adventures in Lestoria/MonsterData.cpp
  9. 2
      Adventures in Lestoria/Player.cpp
  10. 12
      Adventures in Lestoria/TMXParser.h
  11. 3
      Adventures in Lestoria/Ursule.cpp
  12. 6
      CMakeLists.txt
  13. 2
      debug.sh
  14. 2
      emscripten_debug_build.ps1
  15. 4
      emscripten_debug_build.sh

@ -91,7 +91,8 @@
"*.inc": "cpp", "*.inc": "cpp",
"future": "cpp", "future": "cpp",
"any": "cpp", "any": "cpp",
"source_location": "cpp" "source_location": "cpp",
"forward_list": "cpp"
}, },
"editor.suggest.insertMode": "replace" "editor.suggest.insertMode": "replace"
} }

@ -1366,42 +1366,52 @@ void AiL::RenderWorld(float fElapsedTime){
} }
} }
} }
#define NumberScalesWithDamage true
#define NormalNumber false
auto DrawDamageNumber=[&](const bool ScaleWithNumber,std::string_view text,std::pair<Pixel,Pixel>colorsEnemy,std::pair<Pixel,Pixel>colorsFriendly,vf2d scaling={1.f,1.f}){
vf2d textSize=GetTextSizeProp(text)*scaling;
if(!dn->friendly){
vf2d additionalScaling={1.f,1.f};
if(ScaleWithNumber)additionalScaling=dn->size;
textSize*=additionalScaling;
vf2d drawPos=dn->pos-textSize/2.f;
drawPos.x=std::clamp(drawPos.x,view.GetWorldTL().x,view.GetWorldBR().x-textSize.x);
drawPos.y=std::clamp(drawPos.y,view.GetWorldTL().y,view.GetWorldBR().y-textSize.y);
view.DrawShadowStringPropDecal(drawPos,text,colorsEnemy.first,colorsEnemy.second,scaling*additionalScaling);
}else{
vf2d drawPos=dn->pos-textSize/2.f;
drawPos.x=std::clamp(drawPos.x,view.GetWorldTL().x,view.GetWorldBR().x-textSize.x);
drawPos.y=std::clamp(drawPos.y,view.GetWorldTL().y,view.GetWorldBR().y-textSize.y);
view.DrawShadowStringPropDecal(drawPos,text,colorsFriendly.first,colorsFriendly.second,scaling);
}
};
switch(dn->type){ switch(dn->type){
case HEALTH_LOSS:{ case HEALTH_LOSS:{
std::string text=std::to_string(dn->damage); std::string text=std::to_string(dn->damage);
if(!dn->friendly){ DrawDamageNumber(NumberScalesWithDamage,text,{DARK_RED,{0,0,0,0}},{RED,VERY_DARK_GREY});
view.DrawStringPropDecal(dn->pos-GetTextSizeProp(text)/2.f*dn->size,text,DARK_RED,dn->size);
}else{
view.DrawShadowStringPropDecal(dn->pos-GetTextSizeProp(text)/2,text,RED,VERY_DARK_GREY);
}
}break; }break;
case HEALTH_GAIN:{ case HEALTH_GAIN:{
std::string text="+"+std::to_string(dn->damage); std::string text="+"+std::to_string(dn->damage);
if(!dn->friendly){ DrawDamageNumber(NormalNumber,text,{DARK_GREEN,{0,0,0,0}},{GREEN,VERY_DARK_GREY});
view.DrawStringPropDecal(dn->pos-GetTextSizeProp(text)/2,text,DARK_GREEN);
}else{
view.DrawShadowStringPropDecal(dn->pos-GetTextSizeProp(text)/2,text,GREEN,VERY_DARK_GREY);
}
}break; }break;
case MANA_GAIN:{ case MANA_GAIN:{
std::string text="+"+std::to_string(dn->damage); std::string text="+"+std::to_string(dn->damage);
if(dn->friendly){ DrawDamageNumber(NormalNumber,text,{BLUE,VERY_DARK_GREY},{BLUE,VERY_DARK_GREY});
view.DrawShadowStringPropDecal(dn->pos-GetTextSizeProp(text)/2,text,BLUE,VERY_DARK_GREY);
}
}break; }break;
case INTERRUPT:{ case INTERRUPT:{
std::string text="Interrupted!"; std::string text="Interrupted!";
if(dn->friendly){ DrawDamageNumber(NormalNumber,text,{BLACK,VERY_DARK_GREY},{BLACK,VERY_DARK_GREY},{0.5f,1});
view.DrawShadowStringPropDecal(dn->pos-GetTextSizeProp(text)/2,text,BLACK,VERY_DARK_GREY,{0.5,1});
}
}break; }break;
case CRIT:{ case CRIT:{
std::string text=std::to_string(dn->damage); std::string text=std::to_string(dn->damage);
if(!dn->friendly){ DrawDamageNumber(NumberScalesWithDamage,text,{YELLOW,DARK_YELLOW},{BLACK,{0,0,0,0}});
view.DrawShadowStringPropDecal(dn->pos-GetTextSizeProp(text)/2.f*dn->size,text,YELLOW,DARK_YELLOW,dn->size);
}else{
view.DrawStringPropDecal(dn->pos-GetTextSizeProp(text)/2,text,BLACK);
}
}break; }break;
} }
} }
@ -2234,31 +2244,35 @@ int main()
} }
#ifdef _DEBUG #ifdef _DEBUG
HANDLE hLogFile; #ifndef __EMSCRIPTEN__
hLogFile = CreateFile(L"assets/memoryleak.txt", GENERIC_WRITE, #ifndef __linux__
FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, HANDLE hLogFile;
FILE_ATTRIBUTE_NORMAL, NULL); hLogFile = CreateFile(L"assets/memoryleak.txt", GENERIC_WRITE,
_CrtSetReportMode(_CRT_WARN,_CRTDBG_MODE_FILE); FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
_CrtSetReportFile(_CRT_WARN,hLogFile); FILE_ATTRIBUTE_NORMAL, NULL);
_CrtDumpMemoryLeaks(); _CrtSetReportMode(_CRT_WARN,_CRTDBG_MODE_FILE);
CloseHandle(hLogFile); _CrtSetReportFile(_CRT_WARN,hLogFile);
_CrtDumpMemoryLeaks();
std::ifstream file("assets/memoryleak.txt"); CloseHandle(hLogFile);
bool leaked=false;
while(file.good()){ std::ifstream file("assets/memoryleak.txt");
std::string line; bool leaked=false;
std::getline(file,line); while(file.good()){
if(line.find("AiL\\")!=std::string::npos){ std::string line;
if(!leaked){
leaked=true;
std::cout<<std::endl<<std::endl<<std::endl<<"Memory leak detected!"<<std::endl;
}
std::cout<<line<<std::endl;
std::getline(file,line); std::getline(file,line);
std::cout<<line<<std::endl; if(line.find("AiL\\")!=std::string::npos){
if(!leaked){
leaked=true;
std::cout<<std::endl<<std::endl<<std::endl<<"Memory leak detected!"<<std::endl;
}
std::cout<<line<<std::endl;
std::getline(file,line);
std::cout<<line<<std::endl;
}
} }
} if(leaked)ERR("")
if(leaked)ERR("") #endif
#endif
#endif #endif
return 0; return 0;

@ -54,7 +54,7 @@ DamageNumber::DamageNumber(vf2d pos,int damage,bool friendly,DamageNumberType ty
} }
void DamageNumber::RecalculateSize(){ void DamageNumber::RecalculateSize(){
float damageMultRatio=damage/game->GetPlayer()->GetBaseStat("Attack")/2.f; float damageMultRatio=damage/game->GetPlayer()->GetStat("Attack")/2.f;
riseSpd=originalRiseSpd; riseSpd=originalRiseSpd;
if(!friendly){ if(!friendly){
float newSize=std::clamp(roundf(damageMultRatio),1.0f,4.0f); float newSize=std::clamp(roundf(damageMultRatio),1.0f,4.0f);

@ -44,9 +44,17 @@ All rights reserved.
#include <source_location> #include <source_location>
#ifdef _DEBUG #ifdef _DEBUG
#define NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ ) #ifndef __EMSCRIPTEN__
// Replace _NORMAL_BLOCK with _CLIENT_BLOCK if you want the #ifndef __linux__
// allocations to be of _CLIENT_BLOCK type #define NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
// Replace _NORMAL_BLOCK with _CLIENT_BLOCK if you want the
// allocations to be of _CLIENT_BLOCK type
#else
#define NEW new
#endif
#else
#define NEW new
#endif
#else #else
#define NEW new #define NEW new
#endif #endif

@ -400,6 +400,9 @@ void Monster::Collision(Player*p){
p->Knockback(knockbackVecNorm*knockbackStrength); p->Knockback(knockbackVecNorm*knockbackStrength);
#pragma endregion #pragma endregion
B(Attribute::COLLIDED_WITH_PLAYER)=true;
Collision(); Collision();
} }
void Monster::Collision(Monster&m){ void Monster::Collision(Monster&m){
@ -687,8 +690,8 @@ void Monster::OnDeath(){
const geom2d::rect<int>arenaBounds=game->GetZones().at("BossArena")[0].zone; const geom2d::rect<int>arenaBounds=game->GetZones().at("BossArena")[0].zone;
geom2d::rect<int>clampedArena{vi2d(arenaBounds.pos+"boss_spawn_ring_radius"_I),vi2d(arenaBounds.size-"boss_spawn_ring_radius"_I*2)}; geom2d::rect<int>clampedArena{vi2d(arenaBounds.pos+"boss_spawn_ring_radius"_I),vi2d(arenaBounds.size-"boss_spawn_ring_radius"_I*2)};
exitRing.zone.pos.x=std::clamp(exitRing.zone.pos.x,clampedArena.pos.x,clampedArena.pos.x+clampedArena.size.x); exitRing.zone.pos.x=std::clamp(exitRing.zone.pos.x,clampedArena.pos.x-"boss_spawn_ring_radius"_I,clampedArena.pos.x-"boss_spawn_ring_radius"_I+clampedArena.size.x);
exitRing.zone.pos.y=std::clamp(exitRing.zone.pos.y,clampedArena.pos.y,clampedArena.pos.y+clampedArena.size.y); exitRing.zone.pos.y=std::clamp(exitRing.zone.pos.y,clampedArena.pos.y-"boss_spawn_ring_radius"_I,clampedArena.pos.y-"boss_spawn_ring_radius"_I+clampedArena.size.y);
game->AddZone("EndZone",exitRing); //Create a 144x144 ring around the dead boss. game->AddZone("EndZone",exitRing); //Create a 144x144 ring around the dead boss.
} }
@ -783,4 +786,12 @@ const float Monster::GetCollisionDamage()const{
void Monster::SetStrategyDeathFunction(std::function<bool(GameEvent&,Monster&,const std::string&)>func){ void Monster::SetStrategyDeathFunction(std::function<bool(GameEvent&,Monster&,const std::string&)>func){
hasStrategyDeathFunction=true; hasStrategyDeathFunction=true;
strategyDeathFunc=func; strategyDeathFunc=func;
}
const bool Monster::IsNPC()const{
return MONSTER_DATA[name].IsNPC();
}
const bool MonsterData::IsNPC()const{
return isNPC;
} }

@ -71,7 +71,7 @@ struct MonsterDropData{
}; };
struct MonsterData{ struct MonsterData{
private: private:
std::string name; std::string name;
int hp; int hp;
int atk; int atk;
@ -88,7 +88,8 @@ struct MonsterData{
EventName deathSound=""; EventName deathSound="";
EventName walkSound=""; EventName walkSound="";
std::vector<MonsterDropData> dropData; std::vector<MonsterDropData> dropData;
public: bool isNPC=false;
public:
MonsterData(); MonsterData();
MonsterData(std::string name,int hp,int atk,const uint32_t xp,std::vector<std::string>animations,std::vector<MonsterDropData>drops,float moveSpd=1.0f,float size=1.0f,std::string strategy="Run Towards",int collisionDmg=0); MonsterData(std::string name,int hp,int atk,const uint32_t xp,std::vector<std::string>animations,std::vector<MonsterDropData>drops,float moveSpd=1.0f,float size=1.0f,std::string strategy="Run Towards",int collisionDmg=0);
int GetHealth(); int GetHealth();
@ -105,6 +106,7 @@ struct MonsterData{
const EventName&GetHurtSound(); const EventName&GetHurtSound();
const EventName&GetDeathSound(); const EventName&GetDeathSound();
const EventName&GetWalkSound(); const EventName&GetWalkSound();
const bool IsNPC()const;
std::vector<std::string>GetAnimations(){ std::vector<std::string>GetAnimations(){
return animations; return animations;
} }
@ -193,6 +195,7 @@ public:
void RotateTowardsPos(const vf2d&targetPos); void RotateTowardsPos(const vf2d&targetPos);
const float GetDamageReductionFromBuffs()const; const float GetDamageReductionFromBuffs()const;
const float GetCollisionDamage()const; const float GetCollisionDamage()const;
const bool IsNPC()const;
private: private:
std::string name; std::string name;
vf2d pos; vf2d pos;

@ -92,4 +92,5 @@ enum class Attribute{
BULLETS_REMOVED, BULLETS_REMOVED,
BEAR_STOMP_COUNT, BEAR_STOMP_COUNT,
PREVIOUS_PHASE, PREVIOUS_PHASE,
COLLIDED_WITH_PLAYER, //A boolean flag that is set to true when an enemy makes contact with the player.
}; };

@ -207,7 +207,7 @@ void MonsterData::InitializeMonsterData(){
} }
} }
void MonsterData::InitializeNPCData(){ void MonsterData::InitializeNPCData(){
for(auto&[key,size]:DATA["NPCs"].GetKeys()){ for(auto&[key,dataSize]:DATA["NPCs"].GetKeys()){
std::string NPCName=key; std::string NPCName=key;
if(MONSTER_DATA.count(key)){ if(MONSTER_DATA.count(key)){
ERR("WARNING! A monster with the name "<<key<<" already exists in the database! Duplicates are not allowed.") ERR("WARNING! A monster with the name "<<key<<" already exists in the database! Duplicates are not allowed.")
@ -357,6 +357,7 @@ void MonsterData::InitializeNPCData(){
monster.hurtSound=hurtSound; monster.hurtSound=hurtSound;
monster.deathSound=deathSound; monster.deathSound=deathSound;
monster.walkSound=walkSound; monster.walkSound=walkSound;
monster.isNPC=true; //If we read any data from this config file, it's definitely considered an NPC.
MONSTER_DATA[NPCName]=monster; MONSTER_DATA[NPCName]=monster;
} }

@ -467,7 +467,7 @@ void Player::Update(float fElapsedTime){
}else{ }else{
m.SetPos(line.rpoint(dist*1.1f)); m.SetPos(line.rpoint(dist*1.1f));
} }
if(m.IsAlive()){ if(m.IsAlive()&&!m.IsNPC()){ //Don't set the knockback if this monster is actually an NPC. Let's just push them around.
vel=line.vector().norm()*-128; vel=line.vector().norm()*-128;
} }
} }

@ -168,7 +168,7 @@ class TMXParser{
XMLTag monsterTag; XMLTag monsterTag;
XMLTag npcTag; XMLTag npcTag;
XMLTag spawnerLinkTag; XMLTag spawnerLinkTag;
StagePlate*currentStagePlate; StagePlate*currentStagePlate=nullptr;
std::vector<XMLTag>accumulatedMonsterTags; std::vector<XMLTag>accumulatedMonsterTags;
std::map<int,StagePlate>stagePlates; std::map<int,StagePlate>stagePlates;
bool infiniteMap=false; bool infiniteMap=false;
@ -400,7 +400,7 @@ class TMXParser{
}; };
XMLTag newTag=ReadNextTag(); XMLTag newTag=ReadNextTag();
if (newTag.tag=="object"&&newTag.data["type"]!="StagePlate"){ if (newTag.tag=="object"&&newTag.data["type"]!="StagePlate"){
currentStagePlate=nullptr; currentStagePlate=nullptr;
} }
@ -514,13 +514,13 @@ class TMXParser{
} }
} }
}else{ }else{
#if _DEBUG #ifdef _DEBUG
if(_DEBUG_MAP_LOAD_INFO)std::cout<<"Unsupported tag format! Ignoring."<<"\n"; if(_DEBUG_MAP_LOAD_INFO)std::cout<<"Unsupported tag format! Ignoring."<<"\n";
#endif #endif
} }
#if _DEBUG #ifdef _DEBUG
if(_DEBUG_MAP_LOAD_INFO)std::cout<<"\n"<<"=============\n"; if(_DEBUG_MAP_LOAD_INFO)std::cout<<"\n"<<"=============\n";
#endif #endif
} }
TMXParser::TMXParser(std::string file){ TMXParser::TMXParser(std::string file){
fileName=file; fileName=file;

@ -306,6 +306,7 @@ void Monster::STRATEGY::URSULE(Monster&m,float fElapsedTime,std::string strategy
m.F(A::CASTING_TIMER)=ConfigFloat("Phase 3.Charge Cast Time"); m.F(A::CASTING_TIMER)=ConfigFloat("Phase 3.Charge Cast Time");
m.UpdateFacingDirection(geom2d::line<float>(m.GetPos(),game->GetPlayer()->GetPos()).vector()); m.UpdateFacingDirection(geom2d::line<float>(m.GetPos(),game->GetPlayer()->GetPos()).vector());
m.PerformOtherAnimation(4); m.PerformOtherAnimation(4);
m.B(A::COLLIDED_WITH_PLAYER)=false;
} }
} }
if(m.F(A::CASTING_TIMER)>0.f){ if(m.F(A::CASTING_TIMER)>0.f){
@ -350,7 +351,7 @@ void Monster::STRATEGY::URSULE(Monster&m,float fElapsedTime,std::string strategy
float distToTarget=geom2d::line<float>(m.target,m.GetPos()).length(); float distToTarget=geom2d::line<float>(m.target,m.GetPos()).length();
if(distToTarget<=4.f||m.F(A::TARGET_TIMER)==0.f){ if(distToTarget<=4.f||m.F(A::TARGET_TIMER)==0.f||m.B(A::COLLIDED_WITH_PLAYER)){
m.phase=3; m.phase=3;
m.RemoveBuff(SPEEDBOOST); m.RemoveBuff(SPEEDBOOST);
m.RemoveBuff(FIXED_COLLISION_DMG); m.RemoveBuff(FIXED_COLLISION_DMG);

@ -311,6 +311,12 @@ if (EMSCRIPTEN)
# Build Cache: SDL2_mixer, libpng, zlib # Build Cache: SDL2_mixer, libpng, zlib
execute_process(COMMAND "${EMSCRIPTEN_ROOT_PATH}/embuilder${EMCC_SUFFIX}" build sdl2_mixer freetype libpng zlib) execute_process(COMMAND "${EMSCRIPTEN_ROOT_PATH}/embuilder${EMCC_SUFFIX}" build sdl2_mixer freetype libpng zlib)
target_compile_definitions(
${OutputExecutable}
PUBLIC
$<$<CONFIG:Debug>:_DEBUG>
)
if(EXISTS "${SOURCE_DATA_DIR}" AND IS_DIRECTORY "${SOURCE_DATA_DIR}") if(EXISTS "${SOURCE_DATA_DIR}" AND IS_DIRECTORY "${SOURCE_DATA_DIR}")
target_link_options( target_link_options(

@ -1 +1 @@
cmake -DCMAKE_BUILD_TYPE=Debug .;make -j 8 cmake -DCMAKE_BUILD_TYPE=Debug -D_DEBUG=1 .;make -j 8

@ -1,3 +1,3 @@
clear clear
emcmake cmake -DCMAKE_BUILD_TYPE=Debug . emcmake cmake -DCMAKE_BUILD_TYPE=Debug -D_DEBUG=1 .
cmake --build . -j 8 cmake --build . -j 8

@ -0,0 +1,4 @@
clear
source ./emsdk/emsdk_env.sh
emcmake cmake -DCMAKE_BUILD_TYPE=Debug -D_DEBUG=1 .
cmake --build . -j 8
Loading…
Cancel
Save