Display DPS tracker + encounter timer

pull/28/head
sigonasr2 1 year ago
parent c4db27a78d
commit f0169b06ab
  1. 90
      Crawler/Crawler.cpp
  2. 11
      Crawler/Crawler.h
  3. 15
      Crawler/Monster.cpp
  4. 3
      Crawler/Monster.h
  5. 2
      Crawler/Version.h
  6. 24
      Crawler/utils.cpp
  7. 1
      Crawler/utils.h

@ -123,7 +123,12 @@ 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;
bossDisplayTimer=std::max(0.f,bossDisplayTimer-fElapsedTime); if(totalBossEncounterMobs>0){
bossDisplayTimer=std::max(0.f,bossDisplayTimer-fElapsedTime);
}
if(encounterStarted){
encounterDuration+=fElapsedTime;
}
HandleUserInput(fElapsedTime); HandleUserInput(fElapsedTime);
UpdateEffects(fElapsedTime); UpdateEffects(fElapsedTime);
player->Update(fElapsedTime); player->Update(fElapsedTime);
@ -1025,21 +1030,7 @@ void Crawler::RenderHud(){
std::string displayText=player->notificationDisplay.first; std::string displayText=player->notificationDisplay.first;
DrawShadowStringPropDecal(vf2d{float(ScreenWidth()/2),float(ScreenHeight()/4)-24}-GetTextSizeProp(displayText)/2,displayText,BLUE,VERY_DARK_BLUE); DrawShadowStringPropDecal(vf2d{float(ScreenWidth()/2),float(ScreenHeight()/4)-24}-GetTextSizeProp(displayText)/2,displayText,BLUE,VERY_DARK_BLUE);
} }
if(bossDisplayTimer>0){ DisplayBossEncounterInfo();
std::string displayText="- "+bossName+" -";
uint8_t alpha=0;
if(bossDisplayTimer>4){
alpha=uint8_t((5-bossDisplayTimer)*255);
}else
if(bossDisplayTimer>1){
alpha=255;
}else{
alpha=uint8_t((bossDisplayTimer)*255);
}
vf2d textScale={3,5};
DrawShadowStringPropDecal(vf2d{float(ScreenWidth()/2),float(ScreenHeight()/2)}-vf2d{GetTextSizeProp(displayText)}*textScale/2,displayText,{252, 186, 3, alpha},{128,0,0,alpha},textScale,2);
}
std::string versionStr("v" + std::to_string(VERSION_MAJOR) + "." + std::to_string(VERSION_MINOR) + "." + std::to_string(VERSION_PATCH) + "." + std::to_string(VERSION_BUILD)); std::string versionStr("v" + std::to_string(VERSION_MAJOR) + "." + std::to_string(VERSION_MINOR) + "." + std::to_string(VERSION_PATCH) + "." + std::to_string(VERSION_BUILD));
DrawShadowStringDecal(vf2d{ GetScreenSize() } - vf2d{ GetTextSize(versionStr) }*0.4,versionStr,WHITE,BLACK,{0.4,0.4},0.4); DrawShadowStringDecal(vf2d{ GetScreenSize() } - vf2d{ GetTextSize(versionStr) }*0.4,versionStr,WHITE,BLACK,{0.4,0.4},0.4);
if("debug_player_info"_I){ if("debug_player_info"_I){
@ -1163,6 +1154,11 @@ void Crawler::LoadLevel(MapName map){
currentLevel=map; currentLevel=map;
WORLD_SIZE={MAP_DATA[map].MapData.width,MAP_DATA[map].MapData.height}; WORLD_SIZE={MAP_DATA[map].MapData.width,MAP_DATA[map].MapData.height};
levelTime=0; levelTime=0;
bossName="";
encounterDuration=0;
totalDamageDealt=0;
encounterStarted=false;
totalBossEncounterMobs=0;
#pragma region Monster Spawn Data Setup #pragma region Monster Spawn Data Setup
for(auto key:MAP_DATA[map].SpawnerData){ for(auto key:MAP_DATA[map].SpawnerData){
@ -1581,8 +1577,11 @@ void Crawler::InitializeLevels(){
LEVEL_NAMES.SetInitialized(); LEVEL_NAMES.SetInitialized();
} }
void Crawler::SpawnMonster(vf2d pos,MonsterData*data,bool upperLevel){ void Crawler::SpawnMonster(vf2d pos,MonsterData*data,bool upperLevel,bool isBossSpawn){
monstersToBeSpawned.push_back(Monster(pos,*data,upperLevel)); monstersToBeSpawned.push_back(Monster(pos,*data,upperLevel,isBossSpawn));
if(isBossSpawn){
totalBossEncounterMobs++;
}
} }
void Crawler::DrawPie(vf2d center,float radius,float degreesCut,Pixel col){ void Crawler::DrawPie(vf2d center,float radius,float degreesCut,Pixel col){
@ -1609,4 +1608,59 @@ void Crawler::InitializeDefaultKeybinds(){
void Crawler::SetBossNameDisplay(std::string name,float time){ void Crawler::SetBossNameDisplay(std::string name,float time){
bossName=name; bossName=name;
bossDisplayTimer=time; bossDisplayTimer=time;
}
bool Crawler::InBossEncounter(){
return bossName!="";
}
void Crawler::StartBossEncounter(){
if(!encounterStarted){
encounterStarted=true;
totalDamageDealt=encounterDuration=0;
}
}
void Crawler::DisplayBossEncounterInfo(){
if(bossDisplayTimer>0){
std::string displayText="- "+bossName+" -";
uint8_t alpha=0;
if(bossDisplayTimer>4){
alpha=uint8_t((5-bossDisplayTimer)*255);
}else
if(bossDisplayTimer>1){
alpha=255;
}else{
alpha=uint8_t((bossDisplayTimer)*255);
}
vf2d textScale={3,5};
DrawShadowStringPropDecal(vf2d{float(ScreenWidth()/2),float(ScreenHeight()/2)}-vf2d{GetTextSizeProp(displayText)}*textScale/2,displayText,{252, 186, 3, alpha},{128,0,0,alpha},textScale,2);
}
if(InBossEncounter()){
Pixel displayCol=totalBossEncounterMobs==0?Pixel{224, 133, 29}:WHITE;
std::string timeDisplay=util::timerStr(encounterDuration);
vf2d timerTextSize=GetTextSizeProp(timeDisplay);
DrawShadowStringPropDecal(vf2d{ScreenWidth()-2-timerTextSize.x,2+10*0},timeDisplay,displayCol);
vf2d displayTextSize=GetTextSizeProp(bossName);
DrawShadowStringPropDecal(vf2d{ScreenWidth()-2-displayTextSize.x,2+10*1},bossName,displayCol);
if(encounterDuration>=1){
std::string dpsText="DPS: "+std::to_string(int(totalDamageDealt/encounterDuration));
vf2d dpsDisplayTextSize=GetTextSizeProp(dpsText);
DrawShadowStringPropDecal(vf2d{ScreenWidth()-2-dpsDisplayTextSize.x,2+10*2},dpsText,displayCol);
}
}
}
void Crawler::BossDamageDealt(int damage){
totalDamageDealt+=damage;
}
void Crawler::ReduceBossEncounterMobCount(){
totalBossEncounterMobs--;
if(totalBossEncounterMobs<0){
std::cout<<"WARNING! Boss Encounter mob count is less than zero, THIS SHOULD NOT BE HAPPENING!"<<std::endl;
throw;
}
} }

@ -54,6 +54,10 @@ private:
std::vector<Monster>monstersToBeSpawned; std::vector<Monster>monstersToBeSpawned;
float bossDisplayTimer=0; float bossDisplayTimer=0;
std::string bossName; std::string bossName;
int totalDamageDealt=0;
float encounterDuration=0;
bool encounterStarted=false;
int totalBossEncounterMobs=0;
public: public:
Crawler(); Crawler();
bool OnUserCreate() override; bool OnUserCreate() override;
@ -115,11 +119,16 @@ public:
void RenderTile(vi2d pos,TilesheetData tileSheet,int tileSheetIndex,vi2d tileSheetPos); void RenderTile(vi2d pos,TilesheetData tileSheet,int tileSheetIndex,vi2d tileSheetPos);
void RenderTile(TileRenderData&tileSheet,Pixel col); void RenderTile(TileRenderData&tileSheet,Pixel col);
bool IsReflectiveTile(TilesheetData tileSheet,int tileID); bool IsReflectiveTile(TilesheetData tileSheet,int tileID);
void SpawnMonster(vf2d pos,MonsterData*data,bool upperLevel=false); //Queues a monster for spawning on the next frame. void SpawnMonster(vf2d pos,MonsterData*data,bool upperLevel=false,bool isBossSpawn=false); //Queues a monster for spawning on the next frame.
void DrawPie(vf2d center,float radius,float degreesCut,Pixel col); void DrawPie(vf2d center,float radius,float degreesCut,Pixel col);
void RenderCooldowns(); void RenderCooldowns();
void InitializeDefaultKeybinds(); void InitializeDefaultKeybinds();
void SetBossNameDisplay(std::string name,float time=5); void SetBossNameDisplay(std::string name,float time=5);
bool InBossEncounter();
void StartBossEncounter();
void DisplayBossEncounterInfo();
void BossDamageDealt(int damage);
void ReduceBossEncounterMobCount();
struct TileGroupData{ struct TileGroupData{
vi2d tilePos; vi2d tilePos;

@ -23,8 +23,8 @@ safemap<std::string,int>STRATEGY_DATA;
safemap<int,std::string>STRATEGY_ID_DATA; safemap<int,std::string>STRATEGY_ID_DATA;
std::map<int,Renderable*>MonsterData::imgs; std::map<int,Renderable*>MonsterData::imgs;
Monster::Monster(vf2d pos,MonsterData data,bool upperLevel): Monster::Monster(vf2d pos,MonsterData data,bool upperLevel,bool bossMob):
pos(pos),hp(data.GetHealth()),maxhp(data.GetHealth()),atk(data.GetAttack()),moveSpd(data.GetMoveSpdMult()),size(data.GetSizeMult()),targetSize(data.GetSizeMult()),strategy(data.GetAIStrategy()),id(data.GetID()),upperLevel(upperLevel){ pos(pos),hp(data.GetHealth()),maxhp(data.GetHealth()),atk(data.GetAttack()),moveSpd(data.GetMoveSpdMult()),size(data.GetSizeMult()),targetSize(data.GetSizeMult()),strategy(data.GetAIStrategy()),id(data.GetID()),upperLevel(upperLevel),isBoss(bossMob){
bool firstAnimation=true; bool firstAnimation=true;
for(std::string&anim:data.GetAnimations()){ for(std::string&anim:data.GetAnimations()){
animation.AddState(anim,ANIMATION_DATA[anim]); animation.AddState(anim,ANIMATION_DATA[anim]);
@ -243,6 +243,9 @@ std::string Monster::GetDeathAnimationName(){
} }
bool Monster::Hurt(int damage,bool onUpperLevel,float z){ bool Monster::Hurt(int damage,bool onUpperLevel,float z){
if(!IsAlive()||onUpperLevel!=OnUpperLevel()||HasIframes()||abs(GetZ()-z)>1) return false; if(!IsAlive()||onUpperLevel!=OnUpperLevel()||HasIframes()||abs(GetZ()-z)>1) return false;
if(game->InBossEncounter()){
game->StartBossEncounter();
}
float mod_dmg=damage; float mod_dmg=damage;
for(Buff&b:GetBuffs(BuffType::DAMAGE_REDUCTION)){ for(Buff&b:GetBuffs(BuffType::DAMAGE_REDUCTION)){
mod_dmg-=damage*b.intensity; mod_dmg-=damage*b.intensity;
@ -258,9 +261,15 @@ bool Monster::Hurt(int damage,bool onUpperLevel,float z){
lastHitTimer=0.05; lastHitTimer=0.05;
if(!IsAlive()){ if(!IsAlive()){
animation.ChangeState(internal_animState,GetDeathAnimationName()); animation.ChangeState(internal_animState,GetDeathAnimationName());
if(isBoss){
game->ReduceBossEncounterMobCount();
}
}else{ }else{
hp=std::max(1,hp); //Make sure it stays alive if it's supposed to be alive... hp=std::max(1,hp); //Make sure it stays alive if it's supposed to be alive...
} }
if(game->InBossEncounter()){
game->BossDamageDealt(int(mod_dmg));
}
GetInt(Attribute::HITS_UNTIL_DEATH)=std::max(0,GetInt(Attribute::HITS_UNTIL_DEATH)-1); GetInt(Attribute::HITS_UNTIL_DEATH)=std::max(0,GetInt(Attribute::HITS_UNTIL_DEATH)-1);
iframe_timer=GetFloat(Attribute::IFRAME_TIME_UPON_HIT); iframe_timer=GetFloat(Attribute::IFRAME_TIME_UPON_HIT);
return true; return true;
@ -291,7 +300,7 @@ void MonsterSpawner::SetTriggered(bool trigger,bool spawnMonsters){
triggered=trigger; triggered=trigger;
if(spawnMonsters){ if(spawnMonsters){
for(std::pair<int,vf2d>&monsterInfo:monsters){ for(std::pair<int,vf2d>&monsterInfo:monsters){
game->SpawnMonster(pos+monsterInfo.second,&MONSTER_DATA[monsterInfo.first],DoesUpperLevelSpawning()); game->SpawnMonster(pos+monsterInfo.second,&MONSTER_DATA[monsterInfo.first],DoesUpperLevelSpawning(),bossNameDisplay!="");
} }
if(bossNameDisplay!=""){ if(bossNameDisplay!=""){
game->SetBossNameDisplay(bossNameDisplay); game->SetBossNameDisplay(bossNameDisplay);

@ -94,10 +94,11 @@ private:
bool diesNormally=true; //If set to false, the monster death is handled in a special way. Set it to true when it's time to die. bool diesNormally=true; //If set to false, the monster death is handled in a special way. Set it to true when it's time to die.
float targetSize=0; float targetSize=0;
std::map<Attribute,std::variant<VARIANTS>>attributes; std::map<Attribute,std::variant<VARIANTS>>attributes;
bool isBoss=false;
protected: protected:
public: public:
Monster()=delete; Monster()=delete;
Monster(vf2d pos,MonsterData data,bool upperLevel=false); Monster(vf2d pos,MonsterData data,bool upperLevel=false,bool bossMob=false);
vf2d&GetPos(); vf2d&GetPos();
int GetHealth(); int GetHealth();
int GetAttack(); int GetAttack();

@ -2,7 +2,7 @@
#define VERSION_MAJOR 0 #define VERSION_MAJOR 0
#define VERSION_MINOR 2 #define VERSION_MINOR 2
#define VERSION_PATCH 0 #define VERSION_PATCH 0
#define VERSION_BUILD 1567 #define VERSION_BUILD 1572
#define stringify(a) stringify_(a) #define stringify(a) stringify_(a)
#define stringify_(a) #a #define stringify_(a) #a

@ -22,4 +22,28 @@ float util::radToDeg(float rad){
float util::lerp(float n1,float n2,double t){ float util::lerp(float n1,float n2,double t){
return n1*(1-t)+n2*t; return n1*(1-t)+n2*t;
}
std::string util::timerStr(float time){
int seconds=int(time);
int hours=seconds/3600;
int minutes=seconds/60;
std::string timeStr="";
if(hours>0){
if(hours<10)timeStr+="0";
timeStr+=std::to_string(hours)+":";
}
if(minutes>0){
if(minutes%60<10)timeStr+="0";
timeStr+=std::to_string(minutes%60)+":";
}
if(seconds>0){
if(seconds%60<10&&minutes>0)timeStr+="0";
timeStr+=std::to_string(seconds%60);
}
return timeStr;
} }

@ -11,4 +11,5 @@ namespace util{
float degToRad(float deg); float degToRad(float deg);
float radToDeg(float rad); float radToDeg(float rad);
float lerp(float n1,float n2,double t); float lerp(float n1,float n2,double t);
std::string timerStr(float time);
} }
Loading…
Cancel
Save