diff --git a/C++ProjectTemplate b/C++ProjectTemplate index c56e203..ba109a7 100755 Binary files a/C++ProjectTemplate and b/C++ProjectTemplate differ diff --git a/battle.h b/battle.h index a06de0c..7555540 100644 --- a/battle.h +++ b/battle.h @@ -2,7 +2,6 @@ #define BATTLE_H #include "effect.h" #include "pixelGameEngine.h" -#include "battleproperty.h" using namespace olc; enum class BattleMoveName{ @@ -59,29 +58,29 @@ enum class Resistance{ namespace Battle{ struct Move{ - std::string name=""; - std::string desc=""; - char grade=0; //If the name of a move name match, then the grade helps sort it into the same category on menus. - int baseDmg=10; //The base damage of the attack. - int randomDmg=5; //Additional random roll damage to add onto the base damage. - int PPCost=0; - int range=1; //The range of this ability in tiles. - int channelTime=0; //The amount of frames to channel the spell. - bool friendly=false; //Target allies instead. - std::arraycomposition={0,0,0,0}; - std::string attackMsg="$USER uses $POWER"; - Effect*eff=nullptr; - bool pctDamage=false; //Uses % damage for the base damage instead of flat damage. - std::map properties={}; //The int is used to determine the chance of something occurring. - //Properties order is WET, DRY, COLD, HEAT - bool overworld=false; //Whether or not a move can be used on the overworld. - std::string GetPowerName() { - if (grade!=0) { - return name+" "+grade; - } else { - return name; - } + std::string name=""; + std::string desc=""; + char grade=0; //If the name of a move name match, then the grade helps sort it into the same category on menus. + int baseDmg=10; //The base damage of the attack. + int randomDmg=5; //Additional random roll damage to add onto the base damage. + int PPCost=0; + int range=1; //The range of this ability in tiles. + int channelTime=0; //The amount of frames to channel the spell. + bool friendly=false; //Target allies instead. + std::arraycomposition={0,0,0,0}; + std::string attackMsg="$USER uses $POWER"; + Effect*eff=nullptr; + bool pctDamage=false; //Uses % damage for the base damage instead of flat damage. + std::map properties={}; //The int is used to determine the chance of something occurring. + //Properties order is WET, DRY, COLD, HEAT + bool overworld=false; //Whether or not a move can be used on the overworld. + std::string GetPowerName() { + if (grade!=0) { + return name+" "+grade; + } else { + return name; } + } }; } #endif \ No newline at end of file diff --git a/battleproperty.c b/battleproperty.c deleted file mode 100644 index e69de29..0000000 diff --git a/battleproperty.h b/battleproperty.h index 5bde52c..787110d 100644 --- a/battleproperty.h +++ b/battleproperty.h @@ -1,7 +1,7 @@ #ifndef BATTLE_PROPERTY_H #define BATTLE_PROPERTY_H #include "pixelGameEngine.h" -#include "defines.h" +#include "entity.h" using namespace olc; @@ -9,24 +9,26 @@ class BattleProperty{ public: std::string displayName; std::string effectName; - BattleProperty(std::string displayName,std::string effectName) - :displayName(displayName),effectName(effectName){} - virtual void OnApplication()=0; //What happens when the effect is immediately applied. - virtual void OnTurnStart()=0; //Effects on turn start. - virtual void OnTurnEnd()=0; //Effects on turn end. + Property prop; + BattleProperty(Property prop,std::string displayName,std::string effectName) + :prop(prop),displayName(displayName),effectName(effectName){} + virtual void OnApplication(Entity*ent,int val)=0; //What happens when the effect is immediately applied. + virtual bool OnTurnStart(Entity*ent,int val)=0; //Effects on turn start. + virtual void OnTurnEnd(Entity*ent,int val)=0; //Effects on turn end. }; class Property_PETRIFY:public BattleProperty{ public: Property_PETRIFY() - :BattleProperty("PETRIFY","Petrified"){} - void OnApplication(){ + :BattleProperty(Property::PETRIFY,"PETRIFY","Petrified"){} + void OnApplication(Entity*ent,int val){ } - void OnTurnStart(){ - + //Return false to cancel the move. + bool OnTurnStart(Entity*ent,int val){ + return true; } - void OnTurnEnd(){ + void OnTurnEnd(Entity*ent,int val){ } }; @@ -34,14 +36,15 @@ class Property_PETRIFY:public BattleProperty{ class Property_PARALYZE:public BattleProperty{ public: Property_PARALYZE() - :BattleProperty("PARALYZE","Paralyzed"){} - void OnApplication(){ + :BattleProperty(Property::PARALYZE,"PARALYZE","Paralyzed"){} + void OnApplication(Entity*ent,int val){ } - void OnTurnStart(){ - + //Return false to cancel the move. + bool OnTurnStart(Entity*ent,int val){ + return true; } - void OnTurnEnd(){ + void OnTurnEnd(Entity*ent,int val){ } }; @@ -49,14 +52,15 @@ class Property_PARALYZE:public BattleProperty{ class Property_DIAMONDIZE:public BattleProperty{ public: Property_DIAMONDIZE() - :BattleProperty("DIAMONDIZE","Diamondized"){} - void OnApplication(){ + :BattleProperty(Property::DIAMONDIZE,"DIAMONDIZE","Diamondized"){} + void OnApplication(Entity*ent,int val){ } - void OnTurnStart(){ - + //Return false to cancel the move. + bool OnTurnStart(Entity*ent,int val){ + return true; } - void OnTurnEnd(){ + void OnTurnEnd(Entity*ent,int val){ } }; @@ -64,14 +68,15 @@ class Property_DIAMONDIZE:public BattleProperty{ class Property_CRYING:public BattleProperty{ public: Property_CRYING() - :BattleProperty("CRYING","Crying"){} - void OnApplication(){ + :BattleProperty(Property::CRYING,"CRYING","Crying"){} + void OnApplication(Entity*ent,int val){ } - void OnTurnStart(){ - + //Return false to cancel the move. + bool OnTurnStart(Entity*ent,int val){ + return true; } - void OnTurnEnd(){ + void OnTurnEnd(Entity*ent,int val){ } }; @@ -79,29 +84,34 @@ class Property_CRYING:public BattleProperty{ class Property_SLOW:public BattleProperty{ public: Property_SLOW() - :BattleProperty("SLOW","Slowed"){} - void OnApplication(){ - + :BattleProperty(Property::SLOW,"SLOW","Slowed"){} + void OnApplication(Entity*ent,int val){ + ent->statusEffects[prop]=val; + printf("%s: %s - %d\n",displayName.c_str(),ent->obj->name.c_str(),ent->statusEffects[prop]); } - void OnTurnStart(){ - + //Return false to cancel the move. + bool OnTurnStart(Entity*ent,int val){ + printf("%s: %s - %d\n",displayName.c_str(),ent->obj->name.c_str(),ent->statusEffects[prop]); + return true; } - void OnTurnEnd(){ - + void OnTurnEnd(Entity*ent,int val){ + ent->statusEffects[prop]--; + printf("%s: %s - %d\n",displayName.c_str(),ent->obj->name.c_str(),ent->statusEffects[prop]); } }; class Property_MUSHROOMIZED:public BattleProperty{ public: Property_MUSHROOMIZED() - :BattleProperty("MUSHROOMIZED","Mushroomized"){} - void OnApplication(){ + :BattleProperty(Property::MUSHROOMIZED,"MUSHROOMIZED","Mushroomized"){} + void OnApplication(Entity*ent,int val){ } - void OnTurnStart(){ - + //Return false to cancel the move. + bool OnTurnStart(Entity*ent,int val){ + return true; } - void OnTurnEnd(){ + void OnTurnEnd(Entity*ent,int val){ } }; @@ -109,14 +119,15 @@ class Property_MUSHROOMIZED:public BattleProperty{ class Property_CONFUSE:public BattleProperty{ public: Property_CONFUSE() - :BattleProperty("CONFUSE","Confused"){} - void OnApplication(){ + :BattleProperty(Property::CONFUSE,"CONFUSE","Confused"){} + void OnApplication(Entity*ent,int val){ } - void OnTurnStart(){ - + //Return false to cancel the move. + bool OnTurnStart(Entity*ent,int val){ + return true; } - void OnTurnEnd(){ + void OnTurnEnd(Entity*ent,int val){ } }; @@ -124,14 +135,15 @@ class Property_CONFUSE:public BattleProperty{ class Property_POISON:public BattleProperty{ public: Property_POISON() - :BattleProperty("POISON","Poisoned"){} - void OnApplication(){ + :BattleProperty(Property::POISON,"POISON","Poisoned"){} + void OnApplication(Entity*ent,int val){ } - void OnTurnStart(){ - +//Return false to cancel the move. + bool OnTurnStart(Entity*ent,int val){ + return true; } - void OnTurnEnd(){ + void OnTurnEnd(Entity*ent,int val){ } }; @@ -139,14 +151,15 @@ class Property_POISON:public BattleProperty{ class Property_REGEN:public BattleProperty{ public: Property_REGEN() - :BattleProperty("REGEN","Regenerating"){} - void OnApplication(){ + :BattleProperty(Property::REGEN,"REGEN","Regenerating"){} + void OnApplication(Entity*ent,int val){ } - void OnTurnStart(){ - + //Return false to cancel the move. + bool OnTurnStart(Entity*ent,int val){ + return true; } - void OnTurnEnd(){ + void OnTurnEnd(Entity*ent,int val){ } }; @@ -154,13 +167,15 @@ class Property_REGEN:public BattleProperty{ class Property_DEFENSE_UP:public BattleProperty{ public: Property_DEFENSE_UP() - :BattleProperty("DEFENSE_UP","Hardened"){} - void OnApplication(){ + :BattleProperty(Property::DEFENSE_UP,"DEFENSE_UP","Hardened"){} + void OnApplication(Entity*ent,int val){ + } - void OnTurnStart(){ - + //Return false to cancel the move. + bool OnTurnStart(Entity*ent,int val){ + return true; } - void OnTurnEnd(){ + void OnTurnEnd(Entity*ent,int val){ } }; @@ -168,14 +183,15 @@ class Property_DEFENSE_UP:public BattleProperty{ class Property_REVIVE:public BattleProperty{ public: Property_REVIVE() - :BattleProperty("REVIVE","Revived"){} - void OnApplication(){ + :BattleProperty(Property::REVIVE,"REVIVE","Revived"){} + void OnApplication(Entity*ent,int val){ } - void OnTurnStart(){ - + //Return false to cancel the move. + bool OnTurnStart(Entity*ent,int val){ + return true; } - void OnTurnEnd(){ + void OnTurnEnd(Entity*ent,int val){ } }; @@ -183,30 +199,16 @@ class Property_REVIVE:public BattleProperty{ class Property_NONE:public BattleProperty{ public: Property_NONE() - :BattleProperty("NONE",""){} - void OnApplication(){ + :BattleProperty(Property::NONE,"NONE",""){} + void OnApplication(Entity*ent,int val){ } - void OnTurnStart(){ - + //Return false to cancel the move. + bool OnTurnStart(Entity*ent,int val){ + return true; } - void OnTurnEnd(){ + void OnTurnEnd(Entity*ent,int val){ } }; - -enum class Property{ - PETRIFY, - PARALYZE, - DIAMONDIZE, - CRYING, - SLOW, - MUSHROOMIZED, - CONFUSE, - POISON, - REGEN, - DEFENSE_UP, - REVIVE, - NONE -}; #endif \ No newline at end of file diff --git a/defines.h b/defines.h index 5f8aa0b..879e330 100644 --- a/defines.h +++ b/defines.h @@ -36,6 +36,21 @@ using namespace olc; #define 액션 (CutsceneAction*)new +enum class Property{ + PETRIFY, + PARALYZE, + DIAMONDIZE, + CRYING, + SLOW, + MUSHROOMIZED, + CONFUSE, + POISON, + REGEN, + DEFENSE_UP, + REVIVE, + NONE +}; + extern PixelGameEngine*GAME; extern vd2d cameraPos; #endif \ No newline at end of file diff --git a/encounters.h b/encounters.h index 6d2fea4..3de355f 100644 --- a/encounters.h +++ b/encounters.h @@ -6,6 +6,7 @@ using namespace olc; #include "object.h" #include "battle.h" #include "item.h" +#include "entity.h" extern std::vector PARTY_INVENTORY; @@ -18,163 +19,6 @@ namespace encounter{ }; } -class Entity{ - private: - int HP=0; - int targetHP=0; - int PP=0; - int targetPP=0; - public: - int maxHP=0; - int maxPP=0; - std::arrayresistances={0,0,0,0}; - int speed=0; - int baseAtk=0; - int damageReduction=0; //A percentage of how much damage to reduce. - bool smart=false; - bool dumb=false; - int atb=0; //When this value reaches 1000, it's this entity's turn. - 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. - std::array equipment = {nullptr,nullptr,nullptr}; //Equipment this character is using. - bool isPlayer=false; //Whether or not this is a player entity. - //Used for initializing players. - Entity(int HP,int maxHP,int PP,int maxPP,int baseAtk,std::arrayresistances,int speed,std::vectormoveSet,std::vectoritems={},std::arrayequipment={},int damageReduction=0,bool smart=false,bool dumb=false) - :Entity(nullptr,HP,maxHP,PP,maxPP,baseAtk,resistances,speed,moveSet,items,equipment,damageReduction,smart,dumb){ - isPlayer=true; - } - //Use this for initializing enemies as it lets you specify an object. - Entity(Object*obj,int HP,int maxHP,int PP,int maxPP,int baseAtk,std::arrayresistances,int speed,std::vectormoveSet,std::vectoritems={},std::arrayequipment={},int damageReduction=0,bool smart=false,bool dumb=false) - :obj(obj),HP(HP),maxHP(maxHP),PP(PP),maxPP(maxPP),baseAtk(baseAtk),speed(speed),equipment(equipment),moveSet(moveSet),damageReduction(damageReduction),inventory(items),smart(smart),dumb(dumb){ - for (int i=0;i<4;i++) { - this->resistances[i]=resistances[i]; - } - this->targetHP=HP; - this->targetPP=PP; - } - Property GetPrimaryStatusEffect() { - for (std::map::iterator it = statusEffects.begin();it!=statusEffects.end();++it) { - if (it->second!=0) { - return it->first; - } - } - return Property::NONE; - } - //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; - } - - 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; - } -}; - class Encounter{ public: vd2d pos; diff --git a/entity.h b/entity.h new file mode 100644 index 0000000..373ce1c --- /dev/null +++ b/entity.h @@ -0,0 +1,168 @@ +#ifndef ENTITY_H +#define ENTITY_H + +#include "pixelGameEngine.h" +#include "object.h" + +extern std::vectorPARTY_INVENTORY; + +using namespace olc; + + +class Entity{ + private: + int HP=0; + int targetHP=0; + int PP=0; + int targetPP=0; + public: + int maxHP=0; + int maxPP=0; + std::arrayresistances={0,0,0,0}; + int speed=0; + int baseAtk=0; + int damageReduction=0; //A percentage of how much damage to reduce. + bool smart=false; + bool dumb=false; + int atb=0; //When this value reaches 1000, it's this entity's turn. + 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. + std::array equipment = {nullptr,nullptr,nullptr}; //Equipment this character is using. + bool isPlayer=false; //Whether or not this is a player entity. + //Used for initializing players. + Entity(int HP,int maxHP,int PP,int maxPP,int baseAtk,std::arrayresistances,int speed,std::vectormoveSet,std::vectoritems={},std::arrayequipment={},int damageReduction=0,bool smart=false,bool dumb=false) + :Entity(nullptr,HP,maxHP,PP,maxPP,baseAtk,resistances,speed,moveSet,items,equipment,damageReduction,smart,dumb){ + isPlayer=true; + } + //Use this for initializing enemies as it lets you specify an object. + Entity(Object*obj,int HP,int maxHP,int PP,int maxPP,int baseAtk,std::arrayresistances,int speed,std::vectormoveSet,std::vectoritems={},std::arrayequipment={},int damageReduction=0,bool smart=false,bool dumb=false) + :obj(obj),HP(HP),maxHP(maxHP),PP(PP),maxPP(maxPP),baseAtk(baseAtk),speed(speed),equipment(equipment),moveSet(moveSet),damageReduction(damageReduction),inventory(items),smart(smart),dumb(dumb){ + for (int i=0;i<4;i++) { + this->resistances[i]=resistances[i]; + } + this->targetHP=HP; + this->targetPP=PP; + } + Property GetPrimaryStatusEffect() { + for (std::map::iterator it = statusEffects.begin();it!=statusEffects.end();++it) { + if (it->second!=0) { + return it->first; + } + } + return Property::NONE; + } + //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; + } + + 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 \ No newline at end of file diff --git a/main.cpp b/main.cpp index f7457d5..0dc7aa5 100644 --- a/main.cpp +++ b/main.cpp @@ -56,6 +56,8 @@ class Map{ } }; + + class DamageNumber{ public: int damage; //If it's negative then it's a healing number. @@ -65,6 +67,127 @@ class DamageNumber{ :damage(damage),pos(pos),timer(timer){} }; +int frameCount=0; +float elapsedTime=0; +const float TARGET_RATE = 1/60.0; +int MAP_WIDTH=-1; +int MAP_HEIGHT=-1; +Map*CURRENT_MAP=nullptr; +Map*MAP_ONETT=nullptr; +int GAME_STATE = GameState::EDITOR; +vi2d SELECTED_TILE={0,0}; +vi2d HIGHLIGHTED_TILE={0,0}; +int EDITING_LAYER=layer::DYNAMIC; +int SELECTED_OBJ_ID = PLAYER; +int OBJ_DISPLAY_OFFSET = 0; +bool GAME_FLAGS[128]={}; +std::array PARTY_MEMBER_OBJ={}; +std::array PARTY_MEMBER_ID={}; +std::array PARTY_MEMBER_STATS={}; +bool messageBoxVisible=false; +std::string messageBoxText=""; +std::string targetText=""; +std::string messageBoxFinalText=""; +int messageBoxMarker=0; +int messageBoxStartMarker=0; //Start of text display. +int messageBoxStopMarker=0; //End of text display for current printout. +int messageBoxFrameWaitTime=1; +bool messageBoxLoad=false; //Set to true when ready to load a message in. +std::map additionalChars={}; +Cutscene*TestCutscene=nullptr; +Cutscene*CurrentCutscene=nullptr; +ActionType CurrentAction=ActionType::NONE; +double CUTSCENE_FADE_VALUE=0; +std::vectorCUTSCENE_QUEUE={}; +std::mapMOVELIST={}; +std::array partyTrail={vd2d{0,0}}; +int PARTY_MEMBER_COUNT = 1; +int ENCOUNTER_SELECTED = 0; +int ENCOUNTER_OFFSET = 0; +std::vectorENCOUNTER_LIST={}; +Encounter*EDITING_ENCOUNTER=nullptr; +Encounter*BATTLE_ENCOUNTER=nullptr; +int BATTLE_STATE=BattleState::MOVE_CAMERA; +int CAMERA_WAIT_TIMER=0; +int player_rollhp_counter[4][3] = {{0,0,0},{0,0,0},{0,0,0},{0,0,0}}; +int player_rollpp_counter[4][3] = {{0,0,0},{0,0,0},{0,0,0},{0,0,0}}; +int player_rollhp_display[4][3] = {{0,0,0},{0,0,0},{0,0,0},{0,0,0}}; +int player_rollpp_display[4][3] = {{0,0,0},{0,0,0},{0,0,0},{0,0,0}}; +int player_rollwait_counter[4] = {0,0,0,0}; +int previousEquip[4] = {-1,-1,-1,-1}; +int SELECTED_TARGET=0; //Battle target that is selected. +int BATTLE_TARGET=-99; //Negative numbers for players and positive numbers for enemy targets. +int CURRENT_TURN=-99; //Who's turn we are enacting. +int BATTLE_SELECTION_CURSOR=0; +int POWER_SELECTION_CURSOR[4]={0,0,0,0}; +int POWER_GRADE_CURSOR[4]={0,0,0,0}; +int ITEM_SELECTION_CURSOR=0; +int ITEM_SELECTION_OFFSET=0; +int TARGET_SELECTION_CURSOR=0; +bool ANYKEYPRESSED=false; +bool ACTIONKEYPRESSED=false; +std::vector> BATTLE_MOVELIST_DISPLAY; +std::map ADDITIONAL_FONT_VALS = { + {α,0},{β,1},{γ,2},{Ω,3},{Σ,4}, +}; +int POWER_SELECTION_OFFSET[4]={0,0,0,0}; +int BATTLE_ANIMATION_TIMER=0; +int BATTLE_ROLLING_COUNTER_WAITTIME = 0; //Number of frames to wait for each rolling counter. +int BATTLE_HIT_SCREENSHAKE = 0; //Amount of time the screen will rapidly shake as getting hit. +bool ITEM_REQUIRES_EQUIPPING=false; +std::string EQUIP_$ITEM_DISPLAY=" "; //Use this to change the $ITEM tag modifier for abilities. +std::vector BATTLE_CUSTOM_MSGS={}; //Used for displaying additional information during battles. +CustomItemMessage BATTLE_CURRENT_CUSTOM_MSG={}; +int BATTLE_CUSTOM_MESSAGE_WAIT_TIME=0; +Item*BATTLE_CUSTOM_ITEM=nullptr; +std::vector BATTLE_SPOILS_LIST={}; +std::string BATTLE_SPOILS_MESSAGE=""; +int OVERWORLD_MENU_SELECTION=0; +std::vector INTERACTION_MESSAGES={}; +bool CLOSE_OVERWORLD_WINDOW=false; //When set to true, should cause the overworld menu to close as well once the dialog box is closed. +int OVERWORLD_POWER_SELECTION_CURSOR[4]={0,0,0,0}; +int OVERWORLD_POWER_GRADE_CURSOR=0; +int OVERWORLD_POWER_SELECTION_OFFSET[4]={0,0,0,0}; +int OVERWORLD_GRADE_SELECTION_OFFSET=0; +int OVERWORLD_POWER_SELECTION_MEMBER=-1; +Battle::Move*OVERWORLD_SELECTED_POWER; +int OVERWORLD_TARGET_SELECTION=0; +bool HEALING_OVERWORLD_MEMBERS=false; //When set to true, members will be healed as dialog boxes are closed using the HEALING_OVERWORLD_MEMBER variable. +int HEALING_OVERWORLD_MEMBER=0; +bool HEALING_OVERWORLD_SINGLE_MEMBER=false; //When set to true, a single member is being healed. +bool OVERWORLD_ITEM_BEING_USED=false; //When set to true, we need to equip an item after target selected. +std::string DISPLAY_TARGET_MESSAGE=""; //Display some text while selecting a target. +Key KEY_LASTPRESSED=NONE; +int lastPress=0; +int lastRepeatedFrame=0; +EquipSlot::Equip EQUIP_MENU_SLOT=EquipSlot::WEAPON; +int EQUIP_ITEM_MENU_CURSOR=0; +int EQUIP_ITEM_MENU_OFFSET=0; +std::vector EQUIP_ITEM_MENU_CONTENTS={}; + +bool MOUSE_PRESSED_DOWN=false,MOUSE_DOWN=false,MOUSE_RELEASED=false; //TODO Implement Mouse things. + +std::vector> MAP={}; //The foreground layer. +std::vector> MAP2={}; +std::vector> MAP3={}; +std::vector> MAP4={}; +std::vector> MAP5={}; //Collision Layer +std::map SPRITES; +std::map ANIMATIONS={}; +std::map OBJ_INFO={}; +std::map BATTLE_PROPERTIES={}; +std::vector PARTICLES={}; +std::vector DAMAGE_NUMBERS={}; +std::map,vd2d> MOVEMENT_GRID={}; +std::mapITEMLIST={}; +vi2d SELECTED_MOVE_SQUARE={}; + +FountainEffect*FOUNTAIN_EFFECT=nullptr; +FireFountainEffect*FIREFOUNTAIN_EFFECT=nullptr; + +Effect*CURRENT_EFFECT=nullptr; + + class SeasonI : public PixelGameEngine { public: @@ -74,128 +197,6 @@ public: } public: - int frameCount=0; - float elapsedTime=0; - const float TARGET_RATE = 1/60.0; - int MAP_WIDTH=-1; - int MAP_HEIGHT=-1; - Map*CURRENT_MAP=nullptr; - Map*MAP_ONETT=nullptr; - int GAME_STATE = GameState::EDITOR; - vi2d SELECTED_TILE={0,0}; - vi2d HIGHLIGHTED_TILE={0,0}; - int EDITING_LAYER=layer::DYNAMIC; - int SELECTED_OBJ_ID = PLAYER; - int OBJ_DISPLAY_OFFSET = 0; - bool GAME_FLAGS[128]={}; - std::array PARTY_MEMBER_OBJ={}; - std::array PARTY_MEMBER_ID={}; - std::array PARTY_MEMBER_STATS={}; - bool messageBoxVisible=false; - std::string messageBoxText=""; - std::string targetText=""; - std::string messageBoxFinalText=""; - int messageBoxMarker=0; - int messageBoxStartMarker=0; //Start of text display. - int messageBoxStopMarker=0; //End of text display for current printout. - int messageBoxFrameWaitTime=1; - bool messageBoxLoad=false; //Set to true when ready to load a message in. - std::map additionalChars={}; - Cutscene*TestCutscene=nullptr; - Cutscene*CurrentCutscene=nullptr; - ActionType CurrentAction=ActionType::NONE; - double CUTSCENE_FADE_VALUE=0; - std::vectorCUTSCENE_QUEUE={}; - std::mapMOVELIST={}; - std::array partyTrail={vd2d{0,0}}; - int PARTY_MEMBER_COUNT = 1; - int ENCOUNTER_SELECTED = 0; - int ENCOUNTER_OFFSET = 0; - std::vectorENCOUNTER_LIST={}; - Encounter*EDITING_ENCOUNTER=nullptr; - Encounter*BATTLE_ENCOUNTER=nullptr; - int BATTLE_STATE=BattleState::MOVE_CAMERA; - int CAMERA_WAIT_TIMER=0; - int player_rollhp_counter[4][3] = {{0,0,0},{0,0,0},{0,0,0},{0,0,0}}; - int player_rollpp_counter[4][3] = {{0,0,0},{0,0,0},{0,0,0},{0,0,0}}; - int player_rollhp_display[4][3] = {{0,0,0},{0,0,0},{0,0,0},{0,0,0}}; - int player_rollpp_display[4][3] = {{0,0,0},{0,0,0},{0,0,0},{0,0,0}}; - int player_rollwait_counter[4] = {0,0,0,0}; - int previousEquip[4] = {-1,-1,-1,-1}; - int SELECTED_TARGET=0; //Battle target that is selected. - int BATTLE_TARGET=-99; //Negative numbers for players and positive numbers for enemy targets. - int CURRENT_TURN=-99; //Who's turn we are enacting. - int BATTLE_SELECTION_CURSOR=0; - int POWER_SELECTION_CURSOR[4]={0,0,0,0}; - int POWER_GRADE_CURSOR[4]={0,0,0,0}; - int ITEM_SELECTION_CURSOR=0; - int ITEM_SELECTION_OFFSET=0; - int TARGET_SELECTION_CURSOR=0; - bool ANYKEYPRESSED=false; - bool ACTIONKEYPRESSED=false; - std::vector> BATTLE_MOVELIST_DISPLAY; - std::map ADDITIONAL_FONT_VALS = { - {α,0},{β,1},{γ,2},{Ω,3},{Σ,4}, - }; - int POWER_SELECTION_OFFSET[4]={0,0,0,0}; - int BATTLE_ANIMATION_TIMER=0; - int BATTLE_ROLLING_COUNTER_WAITTIME = 0; //Number of frames to wait for each rolling counter. - int BATTLE_HIT_SCREENSHAKE = 0; //Amount of time the screen will rapidly shake as getting hit. - bool ITEM_REQUIRES_EQUIPPING=false; - std::string EQUIP_$ITEM_DISPLAY=" "; //Use this to change the $ITEM tag modifier for abilities. - std::vector BATTLE_CUSTOM_MSGS={}; //Used for displaying additional information during battles. - CustomItemMessage BATTLE_CURRENT_CUSTOM_MSG={}; - int BATTLE_CUSTOM_MESSAGE_WAIT_TIME=0; - Item*BATTLE_CUSTOM_ITEM=nullptr; - std::vector BATTLE_SPOILS_LIST={}; - std::string BATTLE_SPOILS_MESSAGE=""; - int OVERWORLD_MENU_SELECTION=0; - std::vector INTERACTION_MESSAGES={}; - bool CLOSE_OVERWORLD_WINDOW=false; //When set to true, should cause the overworld menu to close as well once the dialog box is closed. - int OVERWORLD_POWER_SELECTION_CURSOR[4]={0,0,0,0}; - int OVERWORLD_POWER_GRADE_CURSOR=0; - int OVERWORLD_POWER_SELECTION_OFFSET[4]={0,0,0,0}; - int OVERWORLD_GRADE_SELECTION_OFFSET=0; - int OVERWORLD_POWER_SELECTION_MEMBER=-1; - Battle::Move*OVERWORLD_SELECTED_POWER; - int OVERWORLD_TARGET_SELECTION=0; - bool HEALING_OVERWORLD_MEMBERS=false; //When set to true, members will be healed as dialog boxes are closed using the HEALING_OVERWORLD_MEMBER variable. - int HEALING_OVERWORLD_MEMBER=0; - bool HEALING_OVERWORLD_SINGLE_MEMBER=false; //When set to true, a single member is being healed. - bool OVERWORLD_ITEM_BEING_USED=false; //When set to true, we need to equip an item after target selected. - std::string DISPLAY_TARGET_MESSAGE=""; //Display some text while selecting a target. - Key KEY_LASTPRESSED=NONE; - int lastPress=0; - int lastRepeatedFrame=0; - EquipSlot::Equip EQUIP_MENU_SLOT=EquipSlot::WEAPON; - int EQUIP_ITEM_MENU_CURSOR=0; - int EQUIP_ITEM_MENU_OFFSET=0; - std::vector EQUIP_ITEM_MENU_CONTENTS={}; - - bool MOUSE_PRESSED_DOWN=false,MOUSE_DOWN=false,MOUSE_RELEASED=false; //TODO Implement Mouse things. - - std::vector> MAP={}; //The foreground layer. - std::vector> MAP2={}; - std::vector> MAP3={}; - std::vector> MAP4={}; - std::vector> MAP5={}; //Collision Layer - std::map SPRITES; - std::map ANIMATIONS={}; - std::map OBJ_INFO={}; - std::map BATTLE_PROPERTIES={}; - std::vector PARTICLES={}; - std::vector DAMAGE_NUMBERS={}; - std::map,vd2d> MOVEMENT_GRID={}; - std::mapITEMLIST={}; - vi2d SELECTED_MOVE_SQUARE={}; - - FountainEffect*FOUNTAIN_EFFECT=nullptr; - FireFountainEffect*FIREFOUNTAIN_EFFECT=nullptr; - - - - Effect*CURRENT_EFFECT=nullptr; - bool OnUserCreate() override { srand(time(NULL)); @@ -1992,7 +1993,7 @@ This is a test message that lets us trigger straight from a cutscene! Cool!)"), SetDrawTarget(layer::GROUND); if (SELECTED_TARGET<0||GAME_STATE==GameState::OVERWORLD_TARGET_MENU) { int memberIndex = GAME_STATE==GameState::OVERWORLD_TARGET_MENU?OVERWORLD_TARGET_SELECTION:-SELECTED_TARGET-1; - Battle::Move*selectedMove=GameState::OVERWORLD_TARGET_MENU?OVERWORLD_SELECTED_POWER:PARTY_MEMBER_STATS[PARTY_MEMBER_ID[-CURRENT_TURN-1]]->selectedMove; + Battle::Move*selectedMove= GAME_STATE==GameState::OVERWORLD_TARGET_MENU?OVERWORLD_SELECTED_POWER:PARTY_MEMBER_STATS[PARTY_MEMBER_ID[-CURRENT_TURN-1]]->selectedMove; vd2d scale = {PARTY_MEMBER_OBJ[memberIndex]->spr->width/(double)SPRITES["targetCircle.png"]->sprite->width,PARTY_MEMBER_OBJ[memberIndex]->spr->spr->sprite->height/(double)SPRITES["targetCircle.png"]->sprite->height}; vi2d size = {SPRITES["targetCircle.png"]->sprite->width,SPRITES["targetCircle.png"]->sprite->height}; DrawDecal(PARTY_MEMBER_OBJ[memberIndex]->GetPosWithOrigin()-cameraPos-size/2*scale,SPRITES["targetCircle.png"],{static_cast(PARTY_MEMBER_OBJ[memberIndex]->spr->width/(double)SPRITES["targetCircle.png"]->sprite->width),static_cast(PARTY_MEMBER_OBJ[memberIndex]->spr->spr->sprite->height/(double)SPRITES["targetCircle.png"]->sprite->height)},GREEN); @@ -2537,10 +2538,10 @@ This is a test message that lets us trigger straight from a cutscene! Cool!)"), MOVELIST[BattleMoveName::METEORRAIN_B]=new Battle::Move{"Meteor Rain","Causes fiery rocks to fall from the skies. Chance to burn trees.",BETA,baseDmg:110,randomDmg:30,PPCost:22,range:2,channelTime:0,friendly:false,composition:{0,0,20,0}}; MOVELIST[BattleMoveName::METEORRAIN_G]=new Battle::Move{"Meteor Rain","Causes fiery rocks to fall from the skies. Chance to burn trees.",GAMMA,baseDmg:200,randomDmg:50,PPCost:47,range:2,channelTime:0,friendly:false,composition:{0,0,20,0}}; MOVELIST[BattleMoveName::METEORRAIN_O]=new Battle::Move{"Meteor Rain","Causes fiery rocks to fall from the skies. Chance to burn trees.",OMEGA,baseDmg:390,randomDmg:60,PPCost:98,range:2,channelTime:0,friendly:false,composition:{0,0,20,0}}; - MOVELIST[BattleMoveName::PKFREEZE_A]=new Battle::Move{"PK Freeze","A powerful chilling attack causing frostbite and slow.",ALPHA,baseDmg:80,randomDmg:10,PPCost:4,range:1,channelTime:0,friendly:false,composition:{0,0,20,10}}; - MOVELIST[BattleMoveName::PKFREEZE_B]=new Battle::Move{"PK Freeze","A powerful chilling attack causing frostbite and slow.",BETA,baseDmg:120,randomDmg:20,PPCost:8,range:1,channelTime:0,friendly:false,composition:{0,0,20,0}}; - MOVELIST[BattleMoveName::PKFREEZE_G]=new Battle::Move{"PK Freeze","A powerful chilling attack causing frostbite and slow.",GAMMA,baseDmg:240,randomDmg:40,PPCost:12,range:1,channelTime:0,friendly:false,composition:{0,0,20,0}}; - MOVELIST[BattleMoveName::PKFREEZE_O]=new Battle::Move{"PK Freeze","A powerful chilling attack causing frostbite and slow.",OMEGA,baseDmg:480,randomDmg:50,PPCost:22,range:1,channelTime:0,friendly:false,composition:{0,0,20,0}}; + MOVELIST[BattleMoveName::PKFREEZE_A]=new Battle::Move{"PK Freeze","A powerful chilling attack causing frostbite and slow.",ALPHA,baseDmg:10,randomDmg:10,PPCost:4,range:1,channelTime:0,friendly:false,composition:{0,0,20,10},properties:{{Property::SLOW,4}}}; + MOVELIST[BattleMoveName::PKFREEZE_B]=new Battle::Move{"PK Freeze","A powerful chilling attack causing frostbite and slow.",BETA,baseDmg:120,randomDmg:20,PPCost:8,range:1,channelTime:0,friendly:false,composition:{0,0,20,0},properties:{{Property::SLOW,4}}}; + MOVELIST[BattleMoveName::PKFREEZE_G]=new Battle::Move{"PK Freeze","A powerful chilling attack causing frostbite and slow.",GAMMA,baseDmg:240,randomDmg:40,PPCost:12,range:1,channelTime:0,friendly:false,composition:{0,0,20,0},properties:{{Property::SLOW,4}}}; + MOVELIST[BattleMoveName::PKFREEZE_O]=new Battle::Move{"PK Freeze","A powerful chilling attack causing frostbite and slow.",OMEGA,baseDmg:480,randomDmg:50,PPCost:22,range:1,channelTime:0,friendly:false,composition:{0,0,20,0},properties:{{Property::SLOW,4}}}; MOVELIST[BattleMoveName::PKSHIELD_A]=new Battle::Move{"PK Shield","Protects against physical attacks.",ALPHA,baseDmg:0,randomDmg:0,PPCost:12,range:1,channelTime:0,friendly:true,composition:{0,0,20,0}}; MOVELIST[BattleMoveName::PKSHIELD_B]=new Battle::Move{"PK Shield","Protects against physical attacks.",BETA,baseDmg:0,randomDmg:0,PPCost:20,range:1,channelTime:0,friendly:true,composition:{0,0,20,0}}; MOVELIST[BattleMoveName::PKSHIELD_O]=new Battle::Move{"PK Shield","Protects against physical attacks.",OMEGA,baseDmg:0,randomDmg:0,PPCost:59,range:4,channelTime:0,friendly:true,composition:{0,0,20,0}}; @@ -2983,8 +2984,8 @@ This is a test message that lets us trigger straight from a cutscene! Cool!)"), return GAME_STATE==GameState::GAME_WORLD&&BATTLE_ENCOUNTER==nullptr&&!IsTextEntryEnabled()&&!messageBoxVisible&&PARTY_MEMBER_OBJ[0]!=nullptr&&CurrentCutscene==nullptr; } - void DisplayMessageBox(std::string targetText) { - this->targetText=targetText; + void DisplayMessageBox(std::string targetT) { + targetText=targetT; messageBoxText=""; messageBoxFinalText=""; messageBoxLoad=true; @@ -3294,12 +3295,22 @@ This is a test message that lets us trigger straight from a cutscene! Cool!)"), if (PARTY_MEMBER_STATS[PARTY_MEMBER_ID[i]]->GetHP()>0) { if (PARTY_MEMBER_STATS[PARTY_MEMBER_ID[i]]->selectedMove==nullptr) { if (PARTY_MEMBER_STATS[PARTY_MEMBER_ID[i]]->atb>=1000) { - printf("%s ready.\n",PARTY_MEMBER_OBJ[i]->name.c_str()); - CURRENT_TURN=-i-1; - BATTLE_STATE=BattleState::SELECT_ACTION; - BATTLE_SELECTION_CURSOR=0; - POWER_GRADE_CURSOR[-CURRENT_TURN-1]=0; - done=true; + bool turnAllowed=true; + for (std::map::iterator it=PARTY_MEMBER_STATS[PARTY_MEMBER_ID[i]]->statusEffects.begin();it!=PARTY_MEMBER_STATS[PARTY_MEMBER_ID[i]]->statusEffects.end();++it) { + if (!BATTLE_PROPERTIES[it->first]->OnTurnStart(PARTY_MEMBER_STATS[PARTY_MEMBER_ID[i]],it->second)) { + turnAllowed=false; + } + } + if (turnAllowed) { + printf("%s ready.\n",PARTY_MEMBER_OBJ[i]->name.c_str()); + CURRENT_TURN=-i-1; + BATTLE_STATE=BattleState::SELECT_ACTION; + BATTLE_SELECTION_CURSOR=0; + POWER_GRADE_CURSOR[-CURRENT_TURN-1]=0; + done=true; + } else { + PARTY_MEMBER_STATS[PARTY_MEMBER_ID[i]]->atb=0; + } break; } else { PARTY_MEMBER_STATS[PARTY_MEMBER_ID[i]]->atb+=PARTY_MEMBER_STATS[PARTY_MEMBER_ID[i]]->speed; @@ -3316,35 +3327,47 @@ This is a test message that lets us trigger straight from a cutscene! Cool!)"), if (BATTLE_ENCOUNTER->objs[i]->selectedMove==nullptr) { if (BATTLE_ENCOUNTER->objs[i]->atb>=1000) { printf("%s (%d) ready.\n",BATTLE_ENCOUNTER->objs[i]->obj->name.c_str(),i); - CURRENT_TURN=i; - //Enemy picks a random move from the movelist. And a random target. - BATTLE_ENCOUNTER->objs[i]->selectedMove=BATTLE_ENCOUNTER->objs[i]->moveSet[rand()%BATTLE_ENCOUNTER->objs[i]->moveSet.size()]; - BATTLE_ENCOUNTER->objs[i]->channelTimeRemaining=BATTLE_ENCOUNTER->objs[i]->selectedMove->channelTime; - if (BATTLE_ENCOUNTER->objs[i]->selectedMove->friendly) { - do { - BATTLE_ENCOUNTER->objs[i]->selectedTarget=rand()%BATTLE_ENCOUNTER->objs.size(); - } while (BATTLE_ENCOUNTER->objs[BATTLE_ENCOUNTER->objs[i]->selectedTarget]->GetHP()<=0); - BATTLE_ENCOUNTER->objs[i]->channelPos=BATTLE_ENCOUNTER->objs[BATTLE_ENCOUNTER->objs[i]->selectedTarget]->obj->GetPosWithOrigin(); - } else { - bool playerAlive=false; - for (int i=0;iGetHP()>0) { - playerAlive=true; - break; + bool turnAllowed=true; + for (std::map::iterator it=BATTLE_ENCOUNTER->objs[i]->statusEffects.begin();it!=BATTLE_ENCOUNTER->objs[i]->statusEffects.end();++it) { + if (BATTLE_ENCOUNTER->objs[i]->statusEffects[it->first]) { + if (!BATTLE_PROPERTIES[it->first]->OnTurnStart(BATTLE_ENCOUNTER->objs[i],it->second)) { + turnAllowed=false; } } - if (playerAlive) { + } + if (turnAllowed) { + CURRENT_TURN=i; + //Enemy picks a random move from the movelist. And a random target. + BATTLE_ENCOUNTER->objs[i]->selectedMove=BATTLE_ENCOUNTER->objs[i]->moveSet[rand()%BATTLE_ENCOUNTER->objs[i]->moveSet.size()]; + BATTLE_ENCOUNTER->objs[i]->channelTimeRemaining=BATTLE_ENCOUNTER->objs[i]->selectedMove->channelTime; + if (BATTLE_ENCOUNTER->objs[i]->selectedMove->friendly) { do { - BATTLE_ENCOUNTER->objs[i]->selectedTarget=-(rand()%PARTY_MEMBER_COUNT)-1; - } while (PARTY_MEMBER_STATS[PARTY_MEMBER_ID[-BATTLE_ENCOUNTER->objs[i]->selectedTarget-1]]->GetHP()<=0); - BATTLE_ENCOUNTER->objs[i]->channelPos=PARTY_MEMBER_STATS[PARTY_MEMBER_ID[-BATTLE_ENCOUNTER->objs[i]->selectedTarget-1]]->obj->GetPosWithOrigin(); - printf("Selected Target: %d\n",BATTLE_ENCOUNTER->objs[i]->selectedTarget); + BATTLE_ENCOUNTER->objs[i]->selectedTarget=rand()%BATTLE_ENCOUNTER->objs.size(); + } while (BATTLE_ENCOUNTER->objs[BATTLE_ENCOUNTER->objs[i]->selectedTarget]->GetHP()<=0); + BATTLE_ENCOUNTER->objs[i]->channelPos=BATTLE_ENCOUNTER->objs[BATTLE_ENCOUNTER->objs[i]->selectedTarget]->obj->GetPosWithOrigin(); + } else { + bool playerAlive=false; + for (int i=0;iGetHP()>0) { + playerAlive=true; + break; + } + } + if (playerAlive) { + do { + BATTLE_ENCOUNTER->objs[i]->selectedTarget=-(rand()%PARTY_MEMBER_COUNT)-1; + } while (PARTY_MEMBER_STATS[PARTY_MEMBER_ID[-BATTLE_ENCOUNTER->objs[i]->selectedTarget-1]]->GetHP()<=0); + BATTLE_ENCOUNTER->objs[i]->channelPos=PARTY_MEMBER_STATS[PARTY_MEMBER_ID[-BATTLE_ENCOUNTER->objs[i]->selectedTarget-1]]->obj->GetPosWithOrigin(); + printf("Selected Target: %d\n",BATTLE_ENCOUNTER->objs[i]->selectedTarget); + } } + printf(" %s chose move %s.\n",BATTLE_ENCOUNTER->objs[i]->obj->name.c_str(),BATTLE_ENCOUNTER->objs[i]->selectedMove->name.c_str()); + BATTLE_STATE=BattleState::WAIT; + BATTLE_SELECTION_CURSOR=0; + done=true; + } else { + BATTLE_ENCOUNTER->objs[i]->atb=0; } - printf(" %s chose move %s.\n",BATTLE_ENCOUNTER->objs[i]->obj->name.c_str(),BATTLE_ENCOUNTER->objs[i]->selectedMove->name.c_str()); - BATTLE_STATE=BattleState::WAIT; - BATTLE_SELECTION_CURSOR=0; - done=true; break; } else { BATTLE_ENCOUNTER->objs[i]->atb+=BATTLE_ENCOUNTER->objs[i]->speed; @@ -3419,9 +3442,6 @@ This is a test message that lets us trigger straight from a cutscene! Cool!)"), } if (CURRENT_EFFECT==nullptr&&BATTLE_ANIMATION_TIMER==90||CURRENT_EFFECT!=nullptr&&BATTLE_ANIMATION_TIMER>CURRENT_EFFECT->maxLifeTime) { if (CURRENT_TURN<0) { - for (std::map::iterator it=PARTY_MEMBER_STATS[PARTY_MEMBER_ID[-CURRENT_TURN-1]]->statusEffects.begin();it!=PARTY_MEMBER_STATS[PARTY_MEMBER_ID[-CURRENT_TURN-1]]->statusEffects.end();++it) { - BATTLE_PROPERTIES[it->first]->OnApplication(); - } if (PARTY_MEMBER_STATS[PARTY_MEMBER_ID[-CURRENT_TURN-1]]->selectedTarget!=NO_TARGET) { if (PARTY_MEMBER_STATS[PARTY_MEMBER_ID[-CURRENT_TURN-1]]->selectedMove->friendly) { if (PARTY_MEMBER_STATS[-PARTY_MEMBER_STATS[PARTY_MEMBER_ID[-CURRENT_TURN-1]]->selectedTarget-1]->GetHP()>0) { @@ -3434,6 +3454,9 @@ This is a test message that lets us trigger straight from a cutscene! Cool!)"), vi2d box = {(128-32*PARTY_MEMBER_COUNT)+memberID*64+29,170}; DAMAGE_NUMBERS.push_back(new DamageNumber(-healAmt,box+cameraPos)); } + for (std::map::iterator it=PARTY_MEMBER_STATS[PARTY_MEMBER_ID[-CURRENT_TURN-1]]->selectedMove->properties.begin();it!=PARTY_MEMBER_STATS[PARTY_MEMBER_ID[-CURRENT_TURN-1]]->selectedMove->properties.end();++it) { + BATTLE_PROPERTIES[it->first]->OnApplication(PARTY_MEMBER_STATS[PARTY_MEMBER_ID[PARTY_MEMBER_STATS[PARTY_MEMBER_ID[-CURRENT_TURN-1]]->selectedTarget]],it->second); + } } } else { std::cout << PARTY_MEMBER_OBJ[-CURRENT_TURN-1]->name << " uses " << PARTY_MEMBER_STATS[PARTY_MEMBER_ID[-CURRENT_TURN-1]]->selectedMove->name << " " << PARTY_MEMBER_STATS[PARTY_MEMBER_ID[-CURRENT_TURN-1]]->selectedMove->grade << " on " << PARTY_MEMBER_OBJ[-PARTY_MEMBER_STATS[PARTY_MEMBER_ID[-CURRENT_TURN-1]]->selectedTarget-1]->name << " but it failed.\n"; @@ -3453,15 +3476,15 @@ This is a test message that lets us trigger straight from a cutscene! Cool!)"), DAMAGE_NUMBERS.push_back(new DamageNumber(dmgAmt,ent->obj->GetPosWithOrigin())); } } + for (std::map::iterator it=PARTY_MEMBER_STATS[PARTY_MEMBER_ID[-CURRENT_TURN-1]]->selectedMove->properties.begin();it!=PARTY_MEMBER_STATS[PARTY_MEMBER_ID[-CURRENT_TURN-1]]->selectedMove->properties.end();++it) { + BATTLE_PROPERTIES[it->first]->OnApplication(BATTLE_ENCOUNTER->objs[PARTY_MEMBER_STATS[PARTY_MEMBER_ID[-CURRENT_TURN-1]]->selectedTarget],it->second); + } } else { std::cout << PARTY_MEMBER_OBJ[-CURRENT_TURN-1]->name << " uses " << PARTY_MEMBER_STATS[PARTY_MEMBER_ID[-CURRENT_TURN-1]]->selectedMove->name << " " << PARTY_MEMBER_STATS[PARTY_MEMBER_ID[-CURRENT_TURN-1]]->selectedMove->grade << " on " << BATTLE_ENCOUNTER->objs[PARTY_MEMBER_STATS[PARTY_MEMBER_ID[-CURRENT_TURN-1]]->selectedTarget]->obj->name << " but it failed.\n"; } } } } else { - for (std::map::iterator it=BATTLE_ENCOUNTER->objs[CURRENT_TURN]->statusEffects.begin();it!=BATTLE_ENCOUNTER->objs[CURRENT_TURN]->statusEffects.end();++it) { - BATTLE_PROPERTIES[it->first]->OnApplication(); - } if (BATTLE_ENCOUNTER->objs[CURRENT_TURN]->selectedTarget!=-NO_TARGET) { if (BATTLE_ENCOUNTER->objs[CURRENT_TURN]->selectedMove->friendly) { if (BATTLE_ENCOUNTER->objs[BATTLE_ENCOUNTER->objs[CURRENT_TURN]->selectedTarget]->GetHP()>0) { @@ -3476,6 +3499,9 @@ This is a test message that lets us trigger straight from a cutscene! Cool!)"), } else { std::cout << BATTLE_ENCOUNTER->objs[CURRENT_TURN]->obj->name << " uses " << BATTLE_ENCOUNTER->objs[CURRENT_TURN]->selectedMove->name << " " << BATTLE_ENCOUNTER->objs[CURRENT_TURN]->selectedMove->grade << " on " << BATTLE_ENCOUNTER->objs[BATTLE_ENCOUNTER->objs[CURRENT_TURN]->selectedTarget]->obj->name << " but it failed.\n"; } + for (std::map::iterator it=BATTLE_ENCOUNTER->objs[CURRENT_TURN]->selectedMove->properties.begin();it!=BATTLE_ENCOUNTER->objs[CURRENT_TURN]->selectedMove->properties.end();++it) { + BATTLE_PROPERTIES[it->first]->OnApplication(BATTLE_ENCOUNTER->objs[BATTLE_ENCOUNTER->objs[CURRENT_TURN]->selectedTarget],it->second); + } } else { if (PARTY_MEMBER_STATS[PARTY_MEMBER_ID[-BATTLE_ENCOUNTER->objs[CURRENT_TURN]->selectedTarget-1]]->GetHP()>0) { for (auto&ent:GetEntitiesInRange(BATTLE_ENCOUNTER->objs[CURRENT_TURN]->selectedTarget,BATTLE_ENCOUNTER->objs[CURRENT_TURN]->channelPos,BATTLE_ENCOUNTER->objs[CURRENT_TURN]->selectedMove)) { @@ -3493,6 +3519,9 @@ This is a test message that lets us trigger straight from a cutscene! Cool!)"), DAMAGE_NUMBERS.push_back(new DamageNumber(dmgAmt,box+cameraPos)); } } + for (std::map::iterator it=BATTLE_ENCOUNTER->objs[CURRENT_TURN]->selectedMove->properties.begin();it!=BATTLE_ENCOUNTER->objs[CURRENT_TURN]->selectedMove->properties.end();++it) { + BATTLE_PROPERTIES[it->first]->OnApplication(PARTY_MEMBER_STATS[PARTY_MEMBER_ID[BATTLE_ENCOUNTER->objs[CURRENT_TURN]->selectedTarget]],it->second); + } } else { std::cout << BATTLE_ENCOUNTER->objs[CURRENT_TURN]->obj->name << " uses " << BATTLE_ENCOUNTER->objs[CURRENT_TURN]->selectedMove->name << " " << BATTLE_ENCOUNTER->objs[CURRENT_TURN]->selectedMove->grade << " on " << PARTY_MEMBER_OBJ[-BATTLE_ENCOUNTER->objs[CURRENT_TURN]->selectedTarget-1]->name << " but it failed.\n"; } @@ -3514,12 +3543,22 @@ This is a test message that lets us trigger straight from a cutscene! Cool!)"), printf("Equipped item: %s\n",PARTY_MEMBER_STATS[PARTY_MEMBER_ID[-CURRENT_TURN-1]]->equipment[PrevEquip->stats.equip]->name.c_str()); previousEquip[-CURRENT_TURN-1]=-1; } + for (std::map::iterator it=PARTY_MEMBER_STATS[PARTY_MEMBER_ID[-CURRENT_TURN-1]]->statusEffects.begin();it!=PARTY_MEMBER_STATS[PARTY_MEMBER_ID[-CURRENT_TURN-1]]->statusEffects.end();++it) { + if (PARTY_MEMBER_STATS[PARTY_MEMBER_ID[-CURRENT_TURN-1]]->statusEffects[it->first]) { + BATTLE_PROPERTIES[it->first]->OnTurnEnd(PARTY_MEMBER_STATS[PARTY_MEMBER_ID[-CURRENT_TURN-1]],it->second); + } + } } else { BATTLE_ENCOUNTER->objs[CURRENT_TURN]->selectedMove=nullptr; BATTLE_ENCOUNTER->objs[CURRENT_TURN]->selectedTarget=NO_TARGET; BATTLE_ENCOUNTER->objs[CURRENT_TURN]->atb=0; BATTLE_ENCOUNTER->objs[CURRENT_TURN]->channelPos=DEFAULT_CHANNELPOS; BATTLE_STATE=BattleState::WAIT; + for (std::map::iterator it=BATTLE_ENCOUNTER->objs[CURRENT_TURN]->statusEffects.begin();it!=BATTLE_ENCOUNTER->objs[CURRENT_TURN]->statusEffects.end();++it) { + if (BATTLE_ENCOUNTER->objs[CURRENT_TURN]->statusEffects[it->first]) { + BATTLE_PROPERTIES[it->first]->OnTurnEnd(BATTLE_ENCOUNTER->objs[CURRENT_TURN],it->second); + } + } } bool enemyStillAlive=false; diff --git a/sig b/sig index 65804b4..1808869 100755 --- a/sig +++ b/sig @@ -3,7 +3,7 @@ export AUTO_UPDATE=true source utils/define.sh define PROJECT_NAME "C++ProjectTemplate" -define CUSTOM_PARAMS "-std=c++17 -lX11 -lGL -lpthread -lpng -lstdc++fs -lpulse -lpulse-simple" +define CUSTOM_PARAMS "-g -std=c++17 -lX11 -lGL -lpthread -lpng -lstdc++fs -lpulse -lpulse-simple" define LANGUAGE "C++" source utils/main.sh