Display DPS tracker + encounter timer
This commit is contained in:
parent
c4db27a78d
commit
f0169b06ab
@ -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…
x
Reference in New Issue
Block a user