From 2a72238e4035f3d3fc1747a56759848f388209ef Mon Sep 17 00:00:00 2001 From: sigonasr2 Date: Sun, 24 Dec 2023 06:04:49 -0600 Subject: [PATCH] Implemented all item stats. --- Crawler/Ability.cpp | 8 +- Crawler/Ability.h | 1 + Crawler/Crawler.cpp | 21 ++++- Crawler/DamageNumber.h | 3 +- Crawler/Monster.cpp | 15 ++++ Crawler/Player.cpp | 89 ++++++++++++++++++-- Crawler/Player.h | 13 ++- Crawler/TODO.txt | 2 +- Crawler/Version.h | 2 +- Crawler/assets/config/Player.txt | 6 ++ Crawler/assets/config/items/ItemDatabase.txt | 1 + 11 files changed, 146 insertions(+), 15 deletions(-) diff --git a/Crawler/Ability.cpp b/Crawler/Ability.cpp index 2f01e0cc..a29f6a1a 100644 --- a/Crawler/Ability.cpp +++ b/Crawler/Ability.cpp @@ -38,6 +38,8 @@ All rights reserved. #include "Ability.h" #include "Crawler.h" +INCLUDE_game + PrecastData::PrecastData() :castTime(0),range(0),size(0){}; PrecastData::PrecastData(float castTime) @@ -52,4 +54,8 @@ InputGroup Ability::DEFAULT; Ability::Ability() :name("???"),shortName("???"),description("???"),cooldown(0),COOLDOWN_TIME(0),input(&DEFAULT){}; Ability::Ability(std::string name,std::string shortName,std::string description,float cooldownTime,int manaCost,InputGroup*input,std::string icon,Pixel barColor1,Pixel barColor2,PrecastData precastInfo,bool canCancelCast) - :name(name),shortName(shortName),description(description),cooldown(0),COOLDOWN_TIME(cooldownTime),manaCost(manaCost),input(input),icon(icon),barColor1(barColor1),barColor2(barColor2),precastInfo(precastInfo),canCancelCast(canCancelCast){} \ No newline at end of file + :name(name),shortName(shortName),description(description),cooldown(0),COOLDOWN_TIME(cooldownTime),manaCost(manaCost),input(input),icon(icon),barColor1(barColor1),barColor2(barColor2),precastInfo(precastInfo),canCancelCast(canCancelCast){} + +const float Ability::GetCooldownTime()const{ + return COOLDOWN_TIME*std::max(0.f,(1-game->GetPlayer()->GetCooldownReductionPct())); +} \ No newline at end of file diff --git a/Crawler/Ability.h b/Crawler/Ability.h index 0206a172..4f1ed8ec 100644 --- a/Crawler/Ability.h +++ b/Crawler/Ability.h @@ -74,6 +74,7 @@ struct Ability{ // Argument 2: vf2d - The returned precast target position (if the ability needs to be aimed, otherwise {}) std::functionaction=[](Player*,vf2d){return false;}; static InputGroup DEFAULT; + const float GetCooldownTime()const; Ability(); //NOTE: icon expects the actual name relative to the "Ability Icons" directory for this constructor! Ability(std::string name,std::string shortName,std::string description,float cooldownTime,int manaCost,InputGroup*input,std::string icon,Pixel barColor1=VERY_DARK_RED,Pixel barColor2=DARK_RED,PrecastData precastInfo={},bool canCancelCast=false); diff --git a/Crawler/Crawler.cpp b/Crawler/Crawler.cpp index 0c736d78..93434df6 100644 --- a/Crawler/Crawler.cpp +++ b/Crawler/Crawler.cpp @@ -193,6 +193,8 @@ bool Crawler::OnUserCreate(){ Inventory::AddItem("Blue Slime Remains",22); Inventory::AddItem("Copper Armor"); Inventory::AddItem("Copper Pants"); + Inventory::AddItem("Copper Helmet"); + Inventory::AddItem("Copper Shoes"); Inventory::AddItem("Shell Helmet"); Inventory::AddItem("Shell Armor"); Inventory::AddItem("Bone Armor"); @@ -202,6 +204,9 @@ bool Crawler::OnUserCreate(){ Inventory::AddItem("Bone Gloves"); Inventory::AddItem("Elixir of Bear Strength",3); Inventory::AddItem("Leather Helmet"); + Inventory::AddItem("Leather Pants"); + Inventory::AddItem("Leather Gloves"); + Inventory::AddItem("Leather Shoes"); LoadLevel(LEVEL_NAMES["starting_map"_S]); ChangePlayerClass(WARRIOR); @@ -1196,6 +1201,14 @@ void Crawler::RenderWorld(float fElapsedTime){ view.DrawShadowStringPropDecal(dn->pos-GetTextSizeProp(text)/2,text,BLACK,VERY_DARK_GREY,{0.5,1}); } }break; + case CRIT:{ + std::string text=std::to_string(dn->damage); + if(!dn->friendly){ + view.DrawShadowStringPropDecal(dn->pos-GetTextSizeProp(text)/2,text,YELLOW,DARK_YELLOW); + }else{ + view.DrawStringPropDecal(dn->pos-GetTextSizeProp(text)/2,text,BLACK); + } + }break; } } @@ -1254,6 +1267,8 @@ void Crawler::RenderHud(){ if("debug_player_info"_I){ DrawShadowStringDecal({0,128},player->GetPos().str()); DrawShadowStringDecal({0,136},"Spd: "+std::to_string(player->GetMoveSpdMult())); + DrawShadowStringDecal({0,144},"HP Timer: "+std::to_string(player->hpRecoveryTimer)); + DrawShadowStringDecal({0,152},"HP Recovery Amt: "+std::to_string(player->GetHPRecoveryPct()*player->GetMaxHealth())); if(!ISBLANK(GetLoadoutItem(0))){ DrawShadowStringDecal({0,92},"Loadout Slot 1 Qty: "+std::to_string(GetLoadoutItem(0).lock()->Amt())); } @@ -1277,9 +1292,9 @@ void Crawler::RenderCooldowns(){ if(loadoutSlot!=-1)iconScale={0.7f,0.7f}; DrawRotatedDecal(pos+vf2d{12,12},GFX[a.icon].Decal(),0,{12,12},iconScale,{255,255,255,64}); if(circle){ - DrawPie(pos+vf2d{12,12},12,360-(a.cooldown/a.COOLDOWN_TIME)*360,PixelLerp(a.barColor1,a.barColor2,(a.cooldown/a.COOLDOWN_TIME))); + DrawPie(pos+vf2d{12,12},12,360-(a.cooldown/a.GetCooldownTime())*360,PixelLerp(a.barColor1,a.barColor2,(a.cooldown/a.GetCooldownTime()))); }else{ - DrawSquarePie(pos+vf2d{12,12},10,360-(a.cooldown/a.COOLDOWN_TIME)*360,PixelLerp(a.barColor1,a.barColor2,(a.cooldown/a.COOLDOWN_TIME))); + DrawSquarePie(pos+vf2d{12,12},10,360-(a.cooldown/a.GetCooldownTime())*360,PixelLerp(a.barColor1,a.barColor2,(a.cooldown/a.GetCooldownTime()))); } std::stringstream cooldownTimeDisplay; cooldownTimeDisplay<GetDisplayName(),keyDisplayCol,BLACK,{0.5f,0.5f},std::numeric_limits::max(),1); vf2d shortNameSize=vf2d{GetTextSize(a.shortName)}*vf2d{0.5f,0.75f}; - DrawShadowStringDecal(pos+vf2d{13,24}-shortNameSize/2,a.shortName,shortNameCol,{255,255,255,64},{0.5f,0.75f}); + DrawShadowStringDecal(pos+vf2d{13,24}-shortNameSize/2,a.shortName,shortNameCol,WHITE,{0.5f,0.75f}); } }; diff --git a/Crawler/DamageNumber.h b/Crawler/DamageNumber.h index 694f3b77..7748bd7a 100644 --- a/Crawler/DamageNumber.h +++ b/Crawler/DamageNumber.h @@ -42,7 +42,8 @@ enum DamageNumberType{ HEALTH_LOSS, HEALTH_GAIN, MANA_GAIN, - INTERRUPT + INTERRUPT, + CRIT, }; struct DamageNumber{ diff --git a/Crawler/Monster.cpp b/Crawler/Monster.cpp index 10e0886d..805cb231 100644 --- a/Crawler/Monster.cpp +++ b/Crawler/Monster.cpp @@ -286,11 +286,21 @@ bool Monster::Hurt(int damage,bool onUpperLevel,float z){ } game->GetPlayer()->ResetLastCombatTime(); float mod_dmg=float(damage); + + #pragma region Handle Crits + bool crit=false; + if(util::random(1)GetPlayer()->GetCritRatePct()){ + mod_dmg*=game->GetPlayer()->GetCritDmgPct(); + crit=true; + } + #pragma endregion + for(Buff&b:GetBuffs(BuffType::DAMAGE_REDUCTION)){ mod_dmg-=damage*b.intensity; } mod_dmg=std::ceil(mod_dmg); hp=std::max(0,hp-int(mod_dmg)); + if(lastHitTimer>0){ damageNumberPtr.get()->damage+=int(mod_dmg); damageNumberPtr.get()->pauseTime=0.4f; @@ -298,6 +308,11 @@ bool Monster::Hurt(int damage,bool onUpperLevel,float z){ damageNumberPtr=std::make_shared(pos,int(mod_dmg)); DAMAGENUMBER_LIST.push_back(damageNumberPtr); } + #pragma region Change Label to Crit + if(crit){ + damageNumberPtr.get()->type=CRIT; + } + #pragma endregion lastHitTimer=0.05f; if(!IsAlive()){ OnDeath(); diff --git a/Crawler/Player.cpp b/Crawler/Player.cpp index 0a532b30..209cf268 100644 --- a/Crawler/Player.cpp +++ b/Crawler/Player.cpp @@ -92,8 +92,8 @@ void Player::Initialize(){ SetBaseStat("Attack","Warrior.BaseAtk"_I); SetBaseStat("Move Spd %",100); SetBaseStat("CDR",0); - SetBaseStat("Crit Rate",0); - SetBaseStat("Crit Dmg",0); + SetBaseStat("Crit Rate","Player.Crit Rate"_F); + SetBaseStat("Crit Dmg","Player.Crit Dmg"_F); SetBaseStat("Health %",0); SetBaseStat("HP6 Recovery %",0); } @@ -183,7 +183,7 @@ const int Player::GetHealth()const{ return hp; } -const int Player::GetMaxHealth()const{ +const float&Player::GetMaxHealth()const{ return GetStat("Health"); } @@ -249,8 +249,13 @@ void Player::Update(float fElapsedTime){ notificationDisplay.second=std::max(0.f,notificationDisplay.second-fElapsedTime); lastHitTimer=std::max(0.f,lastHitTimer-fElapsedTime); blockTimer=std::max(0.f,blockTimer-fElapsedTime); - lastCombatTime=lastCombatTime+fElapsedTime;\ + lastCombatTime=lastCombatTime+fElapsedTime; manaTickTimer-=fElapsedTime; + hpRecoveryTimer=std::max(0.f,hpRecoveryTimer-fElapsedTime); + hp6RecoveryTimer=std::max(0.f,hp6RecoveryTimer-fElapsedTime); + hp4RecoveryTimer=std::max(0.f,hp4RecoveryTimer-fElapsedTime); + + PerformHPRecovery(); CheckEndZoneCollision(); @@ -260,7 +265,7 @@ void Player::Update(float fElapsedTime){ bool allowed=castPrepAbility->actionPerformedDuringCast; if(!allowed&&castPrepAbility->action(this,castInfo.castPos))allowed=true; if(allowed){ - castPrepAbility->cooldown=castPrepAbility->COOLDOWN_TIME; + castPrepAbility->cooldown=castPrepAbility->GetCooldownTime(); ConsumeMana(castPrepAbility->manaCost); } castInfo.castTimer=0; @@ -326,7 +331,7 @@ void Player::Update(float fElapsedTime){ } }break; case State::SWING_SONIC_SWORD:{ - if(ability3.COOLDOWN_TIME-ability3.cooldown>0.5){ + if(ability3.GetCooldownTime()-ability3.cooldown>0.5){ SetState(State::NORMAL); switch(facingDirection){ case DOWN:{ @@ -439,7 +444,7 @@ void Player::Update(float fElapsedTime){ if(key.Held()||key.Released()&&&ability==castPrepAbility&&GetState()==State::PREP_CAST){ if(AllowedToCast(ability)&&ability.action(this,{})){ bool allowed=ability.actionPerformedDuringCast; - ability.cooldown=ability.COOLDOWN_TIME; + ability.cooldown=ability.GetCooldownTime(); CancelCast(); ConsumeMana(ability.manaCost); }else @@ -984,6 +989,7 @@ const float Player::GetDamageReductionFromBuffs()const{ for(const Buff&b:GetBuffs(BuffType::DAMAGE_REDUCTION)){ dmgReduction+=b.intensity; } + dmgReduction+=GetDamageReductionPct(); return std::min(0.75f,dmgReduction); }; const float Player::GetDamageReductionFromArmor()const{ @@ -1014,4 +1020,73 @@ const ItemAttributable&Player::GetStats()const{ ItemAttribute&Player::Get(std::string_view attr){ return ItemAttribute::Get(attr,this); +} + +const float Player::GetCooldownReductionPct()const{ + float modCDRPct=0; + const std::vector&buffs=GetStatBuffs({"CDR"}); + for(const Buff&b:buffs){ + modCDRPct+=b.intensity; + } + modCDRPct+=GetStat("CDR")/100; + return modCDRPct; +} + +const float Player::GetCritRatePct()const{ + float modCritRatePct=0; + modCritRatePct+=GetStat("Crit Rate")/100; + return modCritRatePct; +} +const float Player::GetCritDmgPct()const{ + float modCritDmgPct=0; + modCritDmgPct+=GetStat("Crit Dmg")/100; + return modCritDmgPct; +} + + +const float Player::GetHPRecoveryPct()const{ + float modHPRecoveryPct=0; + modHPRecoveryPct+=GetStat("HP Recovery %")/100; + return modHPRecoveryPct; +} +const float Player::GetHP6RecoveryPct()const{ + float modHPRecoveryPct=0; + modHPRecoveryPct+=GetStat("HP6 Recovery %")/100; + return modHPRecoveryPct; +} +const float Player::GetHP4RecoveryPct()const{ + float modHPRecoveryPct=0; + modHPRecoveryPct+=GetStat("HP4 Recovery %")/100; + return modHPRecoveryPct; +} + +void Player::PerformHPRecovery(){ + int hpRecoveryAmt=0; + if(hpRecoveryTimer==0){ + if(float(GetHPRecoveryPct()*GetMaxHealth())>0.1_Pct){ + hpRecoveryAmt+=std::ceil(GetHPRecoveryPct()*GetMaxHealth()); + } + hpRecoveryTimer=1; + } + if(hp4RecoveryTimer==0){ + if(float(GetHP4RecoveryPct()*GetMaxHealth())>0.1_Pct){ + hpRecoveryAmt+=std::ceil(GetHP4RecoveryPct()*GetMaxHealth()); + } + hp4RecoveryTimer=4; + } + if(hp6RecoveryTimer==0){ + if(float(GetHP6RecoveryPct()*GetMaxHealth())>0.1_Pct){ + hpRecoveryAmt+=std::ceil(GetHP6RecoveryPct()*GetMaxHealth()); + } + hp6RecoveryTimer=6; + } + if(GetHealth()moneyListeners; @@ -217,6 +225,9 @@ private: float spin_angle=0; float lastAnimationFlip=0; float manaTickTimer=0; + float hpRecoveryTimer=0; + float hp6RecoveryTimer=0; + float hp4RecoveryTimer=0; std::pair notEnoughManaDisplay={"",0.f}; float teleportAttemptWaitTime=0; //If a teleport fails, we wait awhile before trying again, it's expensive. State::State state=State::NORMAL; diff --git a/Crawler/TODO.txt b/Crawler/TODO.txt index e2561954..2afd0bfc 100644 --- a/Crawler/TODO.txt +++ b/Crawler/TODO.txt @@ -1,6 +1,6 @@ January 1st =========== -Buff Item Script (Implement Other Stats, Level Up Stats) +Level Up Stats, Levels/EXP Sell Item Merchant Screen Blacksmith Item Crafting Screen Randomized Item Stats diff --git a/Crawler/Version.h b/Crawler/Version.h index e81db637..7675c87a 100644 --- a/Crawler/Version.h +++ b/Crawler/Version.h @@ -39,7 +39,7 @@ All rights reserved. #define VERSION_MAJOR 0 #define VERSION_MINOR 2 #define VERSION_PATCH 1 -#define VERSION_BUILD 4739 +#define VERSION_BUILD 4771 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Crawler/assets/config/Player.txt b/Crawler/assets/config/Player.txt index 1731ebf8..de8e2fd2 100644 --- a/Crawler/assets/config/Player.txt +++ b/Crawler/assets/config/Player.txt @@ -3,6 +3,12 @@ Player BaseMana = 100 MoveSpd = 100 + # Starting base crit rate. + Crit Rate = 0% + + # Starting base crit dmg. + Crit Dmg = 150% + Starting Money = 100 # Amount of spd to increase/decrease vertically as you climb staircases diff --git a/Crawler/assets/config/items/ItemDatabase.txt b/Crawler/assets/config/items/ItemDatabase.txt index f24e152d..9917be2c 100644 --- a/Crawler/assets/config/items/ItemDatabase.txt +++ b/Crawler/assets/config/items/ItemDatabase.txt @@ -47,6 +47,7 @@ ItemDatabase ItemScript = Buff Description = Increase your attack by 15% for 30 seconds. Attack % = 15%,30 + CDR = 50%,60 ItemCategory = Consumables Cooldown Time = 5.0 Cast Time = 0.0