Properly reset the player's health and mana between stages.

pull/28/head
sigonasr2 11 months ago
parent 668a5ca1b1
commit 52d36eab3b
  1. 6
      Crawler/AttributableStat.cpp
  2. 10
      Crawler/Crawler.cpp
  3. 14
      Crawler/Item.cpp
  4. 10
      Crawler/Monster.cpp
  5. 2
      Crawler/Monster.h
  6. 21
      Crawler/Player.cpp
  7. 14
      Crawler/Player.h
  8. 8
      Crawler/SlimeKing.cpp
  9. 2
      Crawler/TODO.txt
  10. 2
      Crawler/Version.h
  11. 100
      Crawler/assets/Campaigns/1_1_v2.tmx
  12. 3
      Crawler/config.h
  13. BIN
      x64/Release/Crawler.exe

@ -59,7 +59,7 @@ ItemAttributable&ItemAttributable::operator+=(ItemAttributable&rhs){
};
ItemAttribute::ItemAttribute(std::string_view name,bool isPct,std::string_view modifies)
:name(name),isPct(isPct),modifies(modifies){}
:name(std::string(name)),isPct(isPct),modifies(std::string(modifies)){}
void ItemAttribute::Initialize(){
for(auto&[key,size]:DATA["Stats"]){
@ -73,7 +73,9 @@ void ItemAttribute::Initialize(){
}
ItemAttribute&ItemAttribute::Get(const std::string_view name,const std::optional<std::variant<Player*,Monster*>>target){
attributes.at(std::string(name)).target=target;
if(target.has_value()){
attributes.at(std::string(name)).target=target;
}
return attributes.at(std::string(name));
}
const std::string_view ItemAttribute::Name()const{

@ -201,6 +201,7 @@ bool Crawler::OnUserCreate(){
Inventory::AddItem("Bone Pants");
Inventory::AddItem("Bone Gloves");
Inventory::AddItem("Elixir of Bear Strength",3);
Inventory::AddItem("Leather Helmet");
LoadLevel(LEVEL_NAMES["starting_map"_S]);
ChangePlayerClass(WARRIOR);
@ -1518,8 +1519,12 @@ void Crawler::LoadLevel(MapName map){
totalBossEncounterMobs=0;
Inventory::Clear("Monster Loot");
Inventory::Clear("Stage Loot");
std::cout<<GetPlayer()->hp<<std::endl;
GetPlayer()->hp=GetPlayer()->GetStat("Health");
GetPlayer()->mana=GetPlayer()->GetMaxMana();
GetPlayer()->SetState(State::NORMAL);
GetPlayer()->GetCastInfo()={};
std::cout<<GetPlayer()->hp<<std::endl;
#pragma region Monster Spawn Data Setup
for(auto&[key,value]:MAP_DATA[map].SpawnerData){
@ -1835,6 +1840,7 @@ void Crawler::ChangePlayerClass(Class cl){
Ability itemAbility3=player->useItem3;
uint32_t oldMoney=player->money;
std::set<MenuComponent*>moneyListeners=Player::moneyListeners;
EntityStats previousStats=player->stats;
switch(cl){
case WARRIOR:{
player.reset(NEW Warrior(player.get()));
@ -1855,6 +1861,7 @@ void Crawler::ChangePlayerClass(Class cl){
player.reset(NEW Witch(player.get()));
}break;
}
player->stats=previousStats;
player->SetBaseStat("Health",DATA.GetProperty(player->GetClassName()+".BaseHealth").GetInt());
player->hp=player->GetBaseStat("Health");
player->SetBaseStat("Attack",DATA.GetProperty(player->GetClassName()+".BaseAtk").GetInt());
@ -2000,6 +2007,9 @@ float operator ""_FRange(const char*key,std::size_t len){
Crawler::OutputDebugInfo(key,len);
return float(util::random(float(DATA.GetProperty(std::string(key,len)).GetReal(1)-DATA.GetProperty(std::string(key,len)).GetReal(0)))+DATA.GetProperty(std::string(key,len)).GetReal(0));
}
float operator ""_Pct(long double pct){
return pct/100;
}
double operator ""_D(const char*key,std::size_t len){
Crawler::OutputDebugInfo(key,len);

@ -798,24 +798,24 @@ void Stats::InitializeDamageReductionTable(){
maxDamageReductionTable[0]=0;
for(int i=1;i<=1000;i++){
if(i<=10){
totalReduction+=0.01;
totalReduction+=1._Pct;
}else
if(i<=30){
totalReduction+=0.00'5;
totalReduction+=0.5_Pct;
}else
if(i<=70){
totalReduction+=0.00'25;
totalReduction+=0.25_Pct;
}else
if(i<=150){
totalReduction+=0.00'125;
totalReduction+=0.125_Pct;
}else
if(i<=310){
totalReduction+=0.00'0625;
totalReduction+=0.0625_Pct;
}else
if(i<=950){
totalReduction+=0.00'03125;
totalReduction+=0.03125_Pct;
}else{
totalReduction+=0.00'1;
totalReduction+=0.1_Pct;
}
maxDamageReductionTable[i]=totalReduction;
}

@ -60,7 +60,7 @@ safemap<std::string,std::function<void(Monster&,float,std::string)>>STRATEGY_DAT
std::map<std::string,Renderable*>MonsterData::imgs;
Monster::Monster(vf2d pos,MonsterData data,bool upperLevel,bool bossMob):
pos(pos),maxhp(data.GetHealth()),size(data.GetSizeMult()),targetSize(data.GetSizeMult()),strategy(data.GetAIStrategy()),name(data.GetDisplayName()),upperLevel(upperLevel),isBoss(bossMob),facingDirection(DOWN){
pos(pos),hp(data.GetHealth()),size(data.GetSizeMult()),targetSize(data.GetSizeMult()),strategy(data.GetAIStrategy()),name(data.GetDisplayName()),upperLevel(upperLevel),isBoss(bossMob),facingDirection(DOWN){
bool firstAnimation=true;
for(std::string&anim:data.GetAnimations()){
animation.AddState(anim,ANIMATION_DATA[anim]);
@ -78,7 +78,7 @@ vf2d&Monster::GetPos(){
return pos;
}
int Monster::GetHealth(){
return stats.A("Health");
return hp;
}
int Monster::GetAttack(){
float mod_atk=float(stats.A("Attack"));
@ -290,7 +290,7 @@ bool Monster::Hurt(int damage,bool onUpperLevel,float z){
mod_dmg-=damage*b.intensity;
}
mod_dmg=std::ceil(mod_dmg);
stats.A("Health")=std::max(0.f,stats.A("Health")-int(mod_dmg));
hp=std::max(0,hp-int(mod_dmg));
if(lastHitTimer>0){
damageNumberPtr.get()->damage+=int(mod_dmg);
damageNumberPtr.get()->pauseTime=0.4f;
@ -302,7 +302,7 @@ bool Monster::Hurt(int damage,bool onUpperLevel,float z){
if(!IsAlive()){
OnDeath();
}else{
stats.A("Health")=std::max(1.f,stats.A("Health")); //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));
@ -313,7 +313,7 @@ bool Monster::Hurt(int damage,bool onUpperLevel,float z){
}
bool Monster::IsAlive(){
return stats.A("Health")>0||!diesNormally;
return hp>0||!diesNormally;
}
vf2d&Monster::GetTargetPos(){
return target;

@ -165,7 +165,7 @@ private:
float friction=400;
vf2d target={0,0};
float targetAcquireTimer=0;
int maxhp;
int hp;
ItemAttributable stats;
float size;
float attackCooldownTimer=0;

@ -48,6 +48,7 @@ All rights reserved.
#include "Menu.h"
#include "GameState.h"
#include "MenuComponent.h"
#include "config.h"
#include <string_view>
@ -612,13 +613,13 @@ bool Player::Hurt(int damage,bool onUpperLevel,float z){
float finalPctDmgTaken=armorDmgTaken*otherDmgTaken;
if(finalPctDmgTaken<=0.06f){
if(finalPctDmgTaken<=6._Pct){
std::cout<<"WARNING! Damage Reduction has somehow ended up below 6%, which is over the cap!"<<std::endl;
}
finalPctDmgTaken=std::max(0.0625f,finalPctDmgTaken);//Apply Damage Cap.
finalPctDmgTaken=std::max(6.25_Pct,finalPctDmgTaken);//Apply Damage Cap.
float minPctDmgReduction=0.00'05f*GetStat("Defense");
float minPctDmgReduction=0.05_Pct*GetStat("Defense");
float finalPctDmgReduction=1-finalPctDmgTaken;
float pctDmgReductionDiff=finalPctDmgReduction-minPctDmgReduction;
@ -935,27 +936,27 @@ void EntityStats::RecalculateEquipStats(){
component->OnEquipStatsUpdate();
}
}
const int&EntityStats::GetStat(ItemAttribute stat)const{
const float&EntityStats::GetStat(ItemAttribute stat)const{
return equipStats.A_Read(stat);
}
const int&EntityStats::GetStat(std::string_view stat)const{
const float&EntityStats::GetStat(std::string_view stat)const{
return equipStats.A_Read(stat);
}
const int&EntityStats::GetBaseStat(ItemAttribute stat)const{
const float&EntityStats::GetBaseStat(ItemAttribute stat)const{
return baseStats.A_Read(stat);
}
const int&EntityStats::GetBaseStat(std::string_view stat)const{
const float&EntityStats::GetBaseStat(std::string_view stat)const{
return baseStats.A_Read(stat);
}
void EntityStats::SetBaseStat(ItemAttribute stat,int val){
void EntityStats::SetBaseStat(ItemAttribute stat,float val){
baseStats.A(stat)=val;
RecalculateEquipStats();
}
void Player::SetBaseStat(std::string_view a,int val){
void Player::SetBaseStat(std::string_view a,float val){
stats.SetBaseStat(ItemAttribute::Get(a),val);
}
void Player::SetBaseStat(ItemAttribute a,int val){
void Player::SetBaseStat(ItemAttribute a,float val){
stats.SetBaseStat(a,val);
}

@ -68,11 +68,11 @@ class EntityStats{
public:
void RecalculateEquipStats(); //Called when equipment is updated.
const ItemAttributable&GetStats()const;
const int&GetStat(ItemAttribute stat)const; //Get stats with equipment applied.
const int&GetStat(std::string_view stat)const; //Get stats with equipment applied.
const int&GetBaseStat(ItemAttribute stat)const;
const int&GetBaseStat(std::string_view stat)const;
void SetBaseStat(ItemAttribute a,int val);
const float&GetStat(ItemAttribute stat)const; //Get stats with equipment applied.
const float&GetStat(std::string_view stat)const; //Get stats with equipment applied.
const float&GetBaseStat(ItemAttribute stat)const;
const float&GetBaseStat(std::string_view stat)const;
void SetBaseStat(ItemAttribute a,float val);
};
struct Player{
@ -102,8 +102,8 @@ public:
const int&GetStat(std::string_view a)const;
const int&GetBaseStat(ItemAttribute a)const;
const int&GetBaseStat(std::string_view a)const;
void SetBaseStat(std::string_view a,int val);
void SetBaseStat(ItemAttribute a,int val);
void SetBaseStat(std::string_view a,float val);
void SetBaseStat(ItemAttribute a,float val);
const int GetMaxHealth()const;
const int GetHealth()const;
const int GetMana()const;

@ -240,7 +240,7 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,std::string strat
m.phase=ConfigInt("StartPhase");
}break;
case 1:{
if(m.stats.A("Health")<=m.maxhp*ConfigFloat("Phase2.Change")/100){
if(m.hp<=m.stats.A("Health")*ConfigFloat("Phase2.Change")/100){
m.phase=2;
m.SetSize(ConfigFloat("Phase2.Size")/100,false);
TransitionPhase(m.phase);
@ -273,7 +273,7 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,std::string strat
}
}break;
case 2:{
if(m.stats.A("Health")<=m.maxhp*ConfigFloat("Phase3.Change")/100){
if(m.hp<=m.stats.A("Health")*ConfigFloat("Phase3.Change")/100){
m.phase=3;
m.SetSize(ConfigFloat("Phase3.Size")/100,false);
TransitionPhase(m.phase);
@ -297,7 +297,7 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,std::string strat
}
}break;
case 3:{
if(m.stats.A("Health")<=m.maxhp*ConfigFloat("Phase4.Change")/100){
if(m.hp<=m.stats.A("Health")*ConfigFloat("Phase4.Change")/100){
m.phase=4;
m.SetSize(ConfigFloat("Phase4.Size")/100,false);
m.AddBuff(BuffType::SLOWDOWN,99999,ConfigFloat("Phase4.MoveSpdModifier")/100);
@ -325,7 +325,7 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,std::string strat
}
}break;
case 4:{
if(m.stats.A("Health")<=1){ //HP can't reach 0 when the dies normally flag is on.
if(m.hp<=1){ //HP can't reach 0 when the dies normally flag is on.
m.phase=5;
m.F(A::IFRAME_TIME_UPON_HIT)=1;
m.I(A::HITS_UNTIL_DEATH)=int(m.GetSizeMult()*100/ConfigFloat("Phase5.SizeLossPerHit"))-1;

@ -1,6 +1,6 @@
January 1st
===========
Buff Item Script (Implement Other Stats)
Buff Item Script (Implement Other Stats, Level Up Stats)
Sell Item Merchant Screen
Blacksmith Item Crafting Screen
Randomized Item Stats

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 0
#define VERSION_MINOR 2
#define VERSION_PATCH 1
#define VERSION_BUILD 4643
#define VERSION_BUILD 4672
#define stringify(a) stringify_(a)
#define stringify_(a) #a

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="right-down" width="205" height="205" tilewidth="24" tileheight="24" infinite="0" backgroundcolor="#475500" nextlayerid="9" nextobjectid="149">
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="right-down" width="205" height="205" tilewidth="24" tileheight="24" infinite="0" backgroundcolor="#475500" nextlayerid="9" nextobjectid="163">
<properties>
<property name="Level Type" propertytype="LevelType" value="Dungeon"/>
</properties>
@ -1971,5 +1971,103 @@
<point/>
</object>
<object id="148" name="Player Spawn" type="PlayerSpawnLocation" x="624" y="4248" width="24" height="24"/>
<object id="149" name="Green Slime" type="Monster" x="1044" y="4254">
<properties>
<property name="Type" propertytype="MonsterName" value="Green Slime"/>
<property name="spawner" type="object" value="2"/>
</properties>
<point/>
</object>
<object id="150" name="Green Slime" type="Monster" x="1056" y="4350">
<properties>
<property name="Type" propertytype="MonsterName" value="Green Slime"/>
<property name="spawner" type="object" value="2"/>
</properties>
<point/>
</object>
<object id="151" name="Green Slime" type="Monster" x="1056" y="4386">
<properties>
<property name="Type" propertytype="MonsterName" value="Green Slime"/>
<property name="spawner" type="object" value="2"/>
</properties>
<point/>
</object>
<object id="152" name="Green Slime" type="Monster" x="1008" y="4290">
<properties>
<property name="Type" propertytype="MonsterName" value="Green Slime"/>
<property name="spawner" type="object" value="2"/>
</properties>
<point/>
</object>
<object id="153" name="Green Slime" type="Monster" x="1016" y="4322">
<properties>
<property name="Type" propertytype="MonsterName" value="Green Slime"/>
<property name="spawner" type="object" value="2"/>
</properties>
<point/>
</object>
<object id="154" name="Green Slime" type="Monster" x="1014" y="4242">
<properties>
<property name="Type" propertytype="MonsterName" value="Green Slime"/>
<property name="spawner" type="object" value="2"/>
</properties>
<point/>
</object>
<object id="155" name="Green Slime" type="Monster" x="1050" y="4218">
<properties>
<property name="Type" propertytype="MonsterName" value="Green Slime"/>
<property name="spawner" type="object" value="2"/>
</properties>
<point/>
</object>
<object id="156" name="Green Slime" type="Monster" x="1032" y="4338">
<properties>
<property name="Type" propertytype="MonsterName" value="Green Slime"/>
<property name="spawner" type="object" value="2"/>
</properties>
<point/>
</object>
<object id="157" name="Green Slime" type="Monster" x="1028" y="4364">
<properties>
<property name="Type" propertytype="MonsterName" value="Green Slime"/>
<property name="spawner" type="object" value="2"/>
</properties>
<point/>
</object>
<object id="158" name="Green Slime" type="Monster" x="1074" y="4272">
<properties>
<property name="Type" propertytype="MonsterName" value="Green Slime"/>
<property name="spawner" type="object" value="2"/>
</properties>
<point/>
</object>
<object id="159" name="Green Slime" type="Monster" x="1080" y="4314">
<properties>
<property name="Type" propertytype="MonsterName" value="Green Slime"/>
<property name="spawner" type="object" value="2"/>
</properties>
<point/>
</object>
<object id="160" name="Green Slime" type="Monster" x="1104" y="4350">
<properties>
<property name="Type" propertytype="MonsterName" value="Green Slime"/>
<property name="spawner" type="object" value="2"/>
</properties>
<point/>
</object>
<object id="161" name="Green Slime" type="Monster" x="1110" y="4278">
<properties>
<property name="Type" propertytype="MonsterName" value="Green Slime"/>
<property name="spawner" type="object" value="2"/>
</properties>
<point/>
</object>
<object id="162" name="Green Slime" type="Monster" x="1122" y="4308">
<properties>
<property name="Type" propertytype="MonsterName" value="Green Slime"/>
<property name="spawner" type="object" value="2"/>
</properties>
<point/>
</object>
</objectgroup>
</map>

@ -60,4 +60,5 @@ double operator ""_D(const char*key,std::size_t len);
utils::datafile operator ""_A(const char*key,std::size_t len);
Pixel operator ""_Pixel(const char*key,std::size_t len);
float operator ""_FRange(const char*key,std::size_t len);
float operator ""_FRange(const char*key,std::size_t len);
float operator ""_Pct(long double pct);

Binary file not shown.
Loading…
Cancel
Save