Fixed a segfault with the ally selection system. Implemented battle properties into battle turns

Co-authored-by: sigonasr2 <sigonasr2@gmail.com>
master
sigonasr2 2 years ago
parent 4e293ff983
commit 300f77d51e
  1. BIN
      C++ProjectTemplate
  2. 45
      battle.h
  3. 0
      battleproperty.c
  4. 168
      battleproperty.h
  5. 15
      defines.h
  6. 158
      encounters.h
  7. 168
      entity.h
  8. 369
      main.cpp
  9. 2
      sig

Binary file not shown.

@ -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::array<int,4>composition={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<Property,int> 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::array<int,4>composition={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<Property,int> 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

@ -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(){
}
void OnTurnStart(){
:BattleProperty(Property::DEFENSE_UP,"DEFENSE_UP","Hardened"){}
void OnApplication(Entity*ent,int val){
}
void OnTurnEnd(){
//Return false to cancel the move.
bool OnTurnStart(Entity*ent,int val){
return true;
}
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

@ -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

@ -6,6 +6,7 @@ using namespace olc;
#include "object.h"
#include "battle.h"
#include "item.h"
#include "entity.h"
extern std::vector<Item*> 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::array<int,4>resistances={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<Battle::Move*> moveSet;
std::map<Property,int> 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<Item*> inventory; //Used mostly for enemy spoils.
std::array<Item*,3> 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::array<int,4>resistances,int speed,std::vector<Battle::Move*>moveSet,std::vector<Item*>items={},std::array<Item*,3>equipment={},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::array<int,4>resistances,int speed,std::vector<Battle::Move*>moveSet,std::vector<Item*>items={},std::array<Item*,3>equipment={},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<Property,int>::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;

@ -0,0 +1,168 @@
#ifndef ENTITY_H
#define ENTITY_H
#include "pixelGameEngine.h"
#include "object.h"
extern std::vector<Item*>PARTY_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::array<int,4>resistances={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<Battle::Move*> moveSet;
std::map<Property,int> 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<Item*> inventory; //Used mostly for enemy spoils.
std::array<Item*,3> 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::array<int,4>resistances,int speed,std::vector<Battle::Move*>moveSet,std::vector<Item*>items={},std::array<Item*,3>equipment={},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::array<int,4>resistances,int speed,std::vector<Battle::Move*>moveSet,std::vector<Item*>items={},std::array<Item*,3>equipment={},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<Property,int>::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

@ -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<Object*,4> PARTY_MEMBER_OBJ={};
std::array<int,4> PARTY_MEMBER_ID={};
std::array<Entity*,7> 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<int,vi2d> additionalChars={};
Cutscene*TestCutscene=nullptr;
Cutscene*CurrentCutscene=nullptr;
ActionType CurrentAction=ActionType::NONE;
double CUTSCENE_FADE_VALUE=0;
std::vector<CutsceneAction*>CUTSCENE_QUEUE={};
std::map<BattleMoveName,Battle::Move*>MOVELIST={};
std::array<vd2d,PARTY_TRAIL_LENGTH> partyTrail={vd2d{0,0}};
int PARTY_MEMBER_COUNT = 1;
int ENCOUNTER_SELECTED = 0;
int ENCOUNTER_OFFSET = 0;
std::vector<Encounter*>ENCOUNTER_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<std::vector<Battle::Move*>> BATTLE_MOVELIST_DISPLAY;
std::map<int,int> 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<CustomItemMessage> 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<Item*> BATTLE_SPOILS_LIST={};
std::string BATTLE_SPOILS_MESSAGE="";
int OVERWORLD_MENU_SELECTION=0;
std::vector<std::string> 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<int> EQUIP_ITEM_MENU_CONTENTS={};
bool MOUSE_PRESSED_DOWN=false,MOUSE_DOWN=false,MOUSE_RELEASED=false; //TODO Implement Mouse things.
std::vector<std::vector<TILE*>> MAP={}; //The foreground layer.
std::vector<std::vector<TILE*>> MAP2={};
std::vector<std::vector<TILE*>> MAP3={};
std::vector<std::vector<TILE*>> MAP4={};
std::vector<std::vector<TILE*>> MAP5={}; //Collision Layer
std::map<std::string,Decal*> SPRITES;
std::map<std::string,Animation*> ANIMATIONS={};
std::map<int,Object*> OBJ_INFO={};
std::map<Property,BattleProperty*> BATTLE_PROPERTIES={};
std::vector<Particle*> PARTICLES={};
std::vector<DamageNumber*> DAMAGE_NUMBERS={};
std::map<std::pair<int,int>,vd2d> MOVEMENT_GRID={};
std::map<ItemName,Item*>ITEMLIST={};
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<Object*,4> PARTY_MEMBER_OBJ={};
std::array<int,4> PARTY_MEMBER_ID={};
std::array<Entity*,7> 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<int,vi2d> additionalChars={};
Cutscene*TestCutscene=nullptr;
Cutscene*CurrentCutscene=nullptr;
ActionType CurrentAction=ActionType::NONE;
double CUTSCENE_FADE_VALUE=0;
std::vector<CutsceneAction*>CUTSCENE_QUEUE={};
std::map<BattleMoveName,Battle::Move*>MOVELIST={};
std::array<vd2d,PARTY_TRAIL_LENGTH> partyTrail={vd2d{0,0}};
int PARTY_MEMBER_COUNT = 1;
int ENCOUNTER_SELECTED = 0;
int ENCOUNTER_OFFSET = 0;
std::vector<Encounter*>ENCOUNTER_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<std::vector<Battle::Move*>> BATTLE_MOVELIST_DISPLAY;
std::map<int,int> 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<CustomItemMessage> 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<Item*> BATTLE_SPOILS_LIST={};
std::string BATTLE_SPOILS_MESSAGE="";
int OVERWORLD_MENU_SELECTION=0;
std::vector<std::string> 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<int> EQUIP_ITEM_MENU_CONTENTS={};
bool MOUSE_PRESSED_DOWN=false,MOUSE_DOWN=false,MOUSE_RELEASED=false; //TODO Implement Mouse things.
std::vector<std::vector<TILE*>> MAP={}; //The foreground layer.
std::vector<std::vector<TILE*>> MAP2={};
std::vector<std::vector<TILE*>> MAP3={};
std::vector<std::vector<TILE*>> MAP4={};
std::vector<std::vector<TILE*>> MAP5={}; //Collision Layer
std::map<std::string,Decal*> SPRITES;
std::map<std::string,Animation*> ANIMATIONS={};
std::map<int,Object*> OBJ_INFO={};
std::map<Property,BattleProperty*> BATTLE_PROPERTIES={};
std::vector<Particle*> PARTICLES={};
std::vector<DamageNumber*> DAMAGE_NUMBERS={};
std::map<std::pair<int,int>,vd2d> MOVEMENT_GRID={};
std::map<ItemName,Item*>ITEMLIST={};
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<float>(PARTY_MEMBER_OBJ[memberIndex]->spr->width/(double)SPRITES["targetCircle.png"]->sprite->width),static_cast<float>(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<Property,int>::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;i<PARTY_MEMBER_COUNT;i++) {
if (PARTY_MEMBER_STATS[PARTY_MEMBER_ID[i]]->GetHP()>0) {
playerAlive=true;
break;
bool turnAllowed=true;
for (std::map<Property,int>::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;i<PARTY_MEMBER_COUNT;i++) {
if (PARTY_MEMBER_STATS[PARTY_MEMBER_ID[i]]->GetHP()>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<Property,int>::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<Property,int>::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<Property,int>::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<Property,int>::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<Property,int>::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<Property,int>::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<Property,int>::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<Property,int>::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;

2
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

Loading…
Cancel
Save