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){
|
||||
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;
|
||||
bossDisplayTimer=std::max(0.f,bossDisplayTimer-fElapsedTime);
|
||||
if(totalBossEncounterMobs>0){
|
||||
bossDisplayTimer=std::max(0.f,bossDisplayTimer-fElapsedTime);
|
||||
}
|
||||
if(encounterStarted){
|
||||
encounterDuration+=fElapsedTime;
|
||||
}
|
||||
HandleUserInput(fElapsedTime);
|
||||
UpdateEffects(fElapsedTime);
|
||||
player->Update(fElapsedTime);
|
||||
@ -1025,21 +1030,7 @@ void Crawler::RenderHud(){
|
||||
std::string displayText=player->notificationDisplay.first;
|
||||
DrawShadowStringPropDecal(vf2d{float(ScreenWidth()/2),float(ScreenHeight()/4)-24}-GetTextSizeProp(displayText)/2,displayText,BLUE,VERY_DARK_BLUE);
|
||||
}
|
||||
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);
|
||||
}
|
||||
DisplayBossEncounterInfo();
|
||||
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);
|
||||
if("debug_player_info"_I){
|
||||
@ -1163,6 +1154,11 @@ void Crawler::LoadLevel(MapName map){
|
||||
currentLevel=map;
|
||||
WORLD_SIZE={MAP_DATA[map].MapData.width,MAP_DATA[map].MapData.height};
|
||||
levelTime=0;
|
||||
bossName="";
|
||||
encounterDuration=0;
|
||||
totalDamageDealt=0;
|
||||
encounterStarted=false;
|
||||
totalBossEncounterMobs=0;
|
||||
|
||||
#pragma region Monster Spawn Data Setup
|
||||
for(auto key:MAP_DATA[map].SpawnerData){
|
||||
@ -1581,8 +1577,11 @@ void Crawler::InitializeLevels(){
|
||||
LEVEL_NAMES.SetInitialized();
|
||||
}
|
||||
|
||||
void Crawler::SpawnMonster(vf2d pos,MonsterData*data,bool upperLevel){
|
||||
monstersToBeSpawned.push_back(Monster(pos,*data,upperLevel));
|
||||
void Crawler::SpawnMonster(vf2d pos,MonsterData*data,bool upperLevel,bool isBossSpawn){
|
||||
monstersToBeSpawned.push_back(Monster(pos,*data,upperLevel,isBossSpawn));
|
||||
if(isBossSpawn){
|
||||
totalBossEncounterMobs++;
|
||||
}
|
||||
}
|
||||
|
||||
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){
|
||||
bossName=name;
|
||||
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;
|
||||
float bossDisplayTimer=0;
|
||||
std::string bossName;
|
||||
int totalDamageDealt=0;
|
||||
float encounterDuration=0;
|
||||
bool encounterStarted=false;
|
||||
int totalBossEncounterMobs=0;
|
||||
public:
|
||||
Crawler();
|
||||
bool OnUserCreate() override;
|
||||
@ -115,11 +119,16 @@ public:
|
||||
void RenderTile(vi2d pos,TilesheetData tileSheet,int tileSheetIndex,vi2d tileSheetPos);
|
||||
void RenderTile(TileRenderData&tileSheet,Pixel col);
|
||||
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 RenderCooldowns();
|
||||
void InitializeDefaultKeybinds();
|
||||
void SetBossNameDisplay(std::string name,float time=5);
|
||||
bool InBossEncounter();
|
||||
void StartBossEncounter();
|
||||
void DisplayBossEncounterInfo();
|
||||
void BossDamageDealt(int damage);
|
||||
void ReduceBossEncounterMobCount();
|
||||
|
||||
struct TileGroupData{
|
||||
vi2d tilePos;
|
||||
|
@ -23,8 +23,8 @@ safemap<std::string,int>STRATEGY_DATA;
|
||||
safemap<int,std::string>STRATEGY_ID_DATA;
|
||||
std::map<int,Renderable*>MonsterData::imgs;
|
||||
|
||||
Monster::Monster(vf2d pos,MonsterData data,bool 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){
|
||||
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),isBoss(bossMob){
|
||||
bool firstAnimation=true;
|
||||
for(std::string&anim:data.GetAnimations()){
|
||||
animation.AddState(anim,ANIMATION_DATA[anim]);
|
||||
@ -243,6 +243,9 @@ std::string Monster::GetDeathAnimationName(){
|
||||
}
|
||||
bool Monster::Hurt(int damage,bool onUpperLevel,float z){
|
||||
if(!IsAlive()||onUpperLevel!=OnUpperLevel()||HasIframes()||abs(GetZ()-z)>1) return false;
|
||||
if(game->InBossEncounter()){
|
||||
game->StartBossEncounter();
|
||||
}
|
||||
float mod_dmg=damage;
|
||||
for(Buff&b:GetBuffs(BuffType::DAMAGE_REDUCTION)){
|
||||
mod_dmg-=damage*b.intensity;
|
||||
@ -258,9 +261,15 @@ bool Monster::Hurt(int damage,bool onUpperLevel,float z){
|
||||
lastHitTimer=0.05;
|
||||
if(!IsAlive()){
|
||||
animation.ChangeState(internal_animState,GetDeathAnimationName());
|
||||
if(isBoss){
|
||||
game->ReduceBossEncounterMobCount();
|
||||
}
|
||||
}else{
|
||||
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);
|
||||
iframe_timer=GetFloat(Attribute::IFRAME_TIME_UPON_HIT);
|
||||
return true;
|
||||
@ -291,7 +300,7 @@ void MonsterSpawner::SetTriggered(bool trigger,bool spawnMonsters){
|
||||
triggered=trigger;
|
||||
if(spawnMonsters){
|
||||
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!=""){
|
||||
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.
|
||||
float targetSize=0;
|
||||
std::map<Attribute,std::variant<VARIANTS>>attributes;
|
||||
bool isBoss=false;
|
||||
protected:
|
||||
public:
|
||||
Monster()=delete;
|
||||
Monster(vf2d pos,MonsterData data,bool upperLevel=false);
|
||||
Monster(vf2d pos,MonsterData data,bool upperLevel=false,bool bossMob=false);
|
||||
vf2d&GetPos();
|
||||
int GetHealth();
|
||||
int GetAttack();
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 2
|
||||
#define VERSION_PATCH 0
|
||||
#define VERSION_BUILD 1567
|
||||
#define VERSION_BUILD 1572
|
||||
|
||||
#define stringify(a) stringify_(a)
|
||||
#define stringify_(a) #a
|
||||
|
@ -22,4 +22,28 @@ float util::radToDeg(float rad){
|
||||
|
||||
float util::lerp(float n1,float n2,double 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 radToDeg(float rad);
|
||||
float lerp(float n1,float n2,double t);
|
||||
std::string timerStr(float time);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user