#ifndef ENTITY_H #define ENTITY_H #include "pixelGameEngine.h" #include "object.h" #include extern std::vectorPARTY_INVENTORY; using namespace olc; namespace boost{ enum{ ATK, HP, PP, SPD }; } class Entity{ struct pstats_t{ public: int HP=0; int maxHP=0; int PP=0; int maxPP=0; int targetHP=0; int targetPP=0; int baseAtk=0; int speed=0; std::arrayresistances={0,0,0,0}; int damageReduction=0; //A percentage of how much damage to reduce. bool smart=false; bool dumb=false; }; public: struct stats_t{ private: int HP=0; public: int maxHP=0; private: int PP=0; public: int maxPP=0; private: int targetHP=0; int targetPP=0; public: int baseAtk=0; int speed=0; std::arrayresistances={0,0,0,0}; int damageReduction=0; //A percentage of how much damage to reduce. bool smart=false; bool dumb=false; stats_t(pstats_t stats) { this->HP=stats.HP; this->maxHP=stats.maxHP; this->PP=stats.PP; this->maxPP=stats.maxPP; this->targetHP=stats.targetHP; this->targetPP=stats.targetPP; this->baseAtk=stats.baseAtk; this->speed=stats.speed; this->resistances=stats.resistances; this->damageReduction=stats.damageReduction; this->smart=stats.smart; this->dumb=stats.dumb; }; bool operator==(const stats_t&t)const{ return HP==t.HP&& maxHP==t.maxHP&& PP==t.PP&& maxPP==t.maxPP&& baseAtk==t.baseAtk&& speed==t.speed&& resistances==t.resistances&& damageReduction==t.damageReduction&& smart==t.smart&& dumb==t.dumb; } //Get the HP that the rolling counter is moving towards. int GetTargetHP() { return targetHP; } //Gets the current actual health of the target. int GetHP() { return HP; } //Get the PP that the rolling counter is moving towards. int GetTargetPP() { return targetPP; } //Gets the current actual pp of the target. int GetPP() { return PP; } //Sets the rolling counter target to this health value. void SetTargetHP(int hp) { targetHP=hp; } //Sets the rolling counter target to this pp value. void SetTargetPP(int pp) { targetPP=pp; } //Subtracts from the rolling counter target from this health value. void SubtractHP(int hp) { targetHP-=hp; } //Adds to the rolling counter target from this health value. void AddHP(int hp) { targetHP=std::clamp(targetHP+hp,0,maxHP); } //Subtracts from the rolling counter target from this pp value. void SubtractPP(int pp) { targetPP=std::clamp(targetPP-pp,0,maxPP); } //Adds to the rolling counter target from this pp value. void AddPP(int pp) { targetPP=std::clamp(targetPP+pp,0,maxPP); } //THIS IS FOR SPECIAL USE CASES ONLY! Normally you want to touch the rolling counter amount instead using SetTargetHP()! void _SetDirectHP(int hp) { HP=hp; } //THIS IS FOR SPECIAL USE CASES ONLY! Normally you want to touch the rolling counter amount instead using SetTargetPP()! void _SetDirectPP(int pp) { PP=pp; } }; private: pstats_t pstats; public: stats_t stats; int atb=0; //When this value reaches 1000, it's this entity's turn. public: Object* obj; std::vector moveSet; std::map statusEffects; int selectedTarget = NO_TARGET; Battle::Move*selectedMove = nullptr; //The index of the selected move. int channelTimeRemaining = 0; //The amount of channel time left until move can be performed. vd2d channelPos = DEFAULT_CHANNELPOS; //Where our channel is happening. std::vector inventory; //Used mostly for enemy spoils. int money=0; //Amount of money this entity will drop when defeated. std::array equipment = {nullptr,nullptr,nullptr}; //Equipment this character is using. bool isPlayer=false; //Whether or not this is a player entity. std::array boosts = {0,0,0,0}; //Values to indicate how much the boosts of each stat ended up being. Order is ATK,HP,PP,SPD. //Used for initializing players. Entity(pstats_t stats,std::vectormoveSet,std::vectoritems={},int money=0,std::arrayequipment={}) :Entity(nullptr,stats,moveSet,items,money,equipment){ isPlayer=true; } //Use this for initializing enemies as it lets you specify an object. Entity(Object*obj,pstats_t stats,std::vectormoveSet,std::vectoritems={},int money=0,std::arrayequipment={}) :obj(obj),stats({HP:stats.HP,maxHP:stats.maxHP,PP:stats.PP,maxPP:stats.maxPP,targetHP:stats.targetHP,targetPP:stats.targetPP,baseAtk:stats.baseAtk,speed:stats.speed,resistances:stats.resistances,damageReduction:stats.damageReduction,smart:stats.smart,dumb:stats.dumb}),equipment(equipment),moveSet(moveSet),inventory(items),money(money){ for (int i=0;i<4;i++) { this->stats.resistances[i]=stats.resistances[i]; } this->stats.SetTargetHP(stats.HP); this->stats.SetTargetPP(stats.PP); } //Get the HP that the rolling counter is moving towards. int GetTargetHP() { return stats.GetTargetHP(); } //Gets the current actual health of the target. int GetHP() { return stats.GetHP(); } //Get the PP that the rolling counter is moving towards. int GetTargetPP() { return stats.GetTargetPP(); } //Gets the current actual pp of the target. int GetPP() { return stats.GetPP(); } //Sets the rolling counter target to this health value. void SetTargetHP(int hp) { stats.SetTargetHP(hp); } //Sets the rolling counter target to this pp value. void SetTargetPP(int pp) { stats.SetTargetPP(pp); } //Subtracts from the rolling counter target from this health value. void SubtractHP(int hp) { stats.SubtractHP(hp); } //Adds to the rolling counter target from this health value. void AddHP(int hp) { stats.AddHP(hp); } //Subtracts from the rolling counter target from this pp value. void SubtractPP(int pp) { stats.SubtractPP(pp); } //Adds to the rolling counter target from this pp value. void AddPP(int pp) { stats.AddPP(pp); } //THIS IS FOR SPECIAL USE CASES ONLY! Normally you want to touch the rolling counter amount instead using SetTargetHP()! void _SetDirectHP(int hp) { stats._SetDirectHP(hp); } //THIS IS FOR SPECIAL USE CASES ONLY! Normally you want to touch the rolling counter amount instead using SetTargetPP()! void _SetDirectPP(int pp) { stats._SetDirectPP(pp); } Property GetPrimaryStatusEffect() { for (std::map::iterator it = statusEffects.begin();it!=statusEffects.end();++it) { if (it->second!=0) { return it->first; } } return Property::NONE; } void RemoveItem(int index) { if (isPlayer) { PARTY_INVENTORY.erase(PARTY_INVENTORY.begin()+index); } else { inventory.erase(inventory.begin()+index); } } //If index is -1, the item is inserted at the end of the list. Otherwise it's going to overwrite a certain slot. Be certain you swap the item before doing this! void RemoveEquip(EquipSlot::Equip slot,int index=-1) { Item*CurrentEquip=equipment[slot]; if (CurrentEquip==nullptr) { return; } if (isPlayer) { if (index==-1) { PARTY_INVENTORY.push_back(CurrentEquip); } else { PARTY_INVENTORY[index]=CurrentEquip; } equipment[slot]=nullptr; } else { if (index==-1) { inventory.push_back(CurrentEquip); } else { inventory[index]=CurrentEquip; } equipment[slot]=nullptr; } } //Will automatically swap items with current equipment so no need to call remove first. void EquipItem(int index) { Item*equip=nullptr; if (isPlayer) { equip=PARTY_INVENTORY[index]; } else { equip=inventory[index]; } if (equip==nullptr) { return; } if (equip->stats.equip==EquipSlot::NONE) { printf("Cannot equip %s! Does not have a valid Equip slot!\n",equip->name.c_str()); return; } Item*CurrentEquip=equipment[equip->stats.equip]; if (CurrentEquip==nullptr) { if (isPlayer) { PARTY_INVENTORY.erase(PARTY_INVENTORY.begin()+index); } else { inventory.erase(inventory.begin()+index); } } else { RemoveEquip(CurrentEquip->stats.equip,index); } equipment[equip->stats.equip]=equip; } }; #endif