Externalize various components to make clangd happy

Co-authored-by: sigonasr2 <sigonasr2@gmail.com>
master
sigonasr2 2 years ago
parent 8226b056e2
commit cb485e6336
  1. BIN
      C++ProjectTemplate
  2. 55
      battle.h
  3. 30
      defines.h
  4. 9
      effect.h
  5. 97
      encounters.h
  6. 5
      flags.h
  7. 64
      gameinit.h
  8. 43
      item.h
  9. 386
      main.cpp
  10. 42
      object.cpp
  11. 146
      object.h
  12. 9
      particle.h

Binary file not shown.

@ -0,0 +1,55 @@
#ifndef BATTLE_H
#define BATTLE_H
#include "effect.h"
#include "pixelGameEngine.h"
using namespace olc;
enum class Resistance{
WET,
DRY,
COLD,
HEAT,
};
enum class Property{
PETRIFY,
PARALYZE,
DIAMONDIZE,
CRYING,
SLOW,
MUSHROOMIZED,
CONFUSE,
POISON,
REGEN,
DEFENSE_UP,
REVIVE,
};
namespace Battle{
class Move{
public:
std::string name;
std::string desc;
std::array<int,4>composition;
int baseDmg; //The base damage of the attack.
int randomDmg; //Additional random roll damage to add onto the base damage.
bool pctDamage; //Uses % damage for the base damage instead of flat damage.
std::vector<std::pair<Property,int>> properties; //The int is used to determine the chance of something occurring.
//Properties order is WET, DRY, COLD, HEAT
int PPCost=0;
int grade=0; //If the name of a move name match, then the grade helps sort it into the same category on menus.
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.
Effect*eff=nullptr;
//Assumes friendly is false.
Move(std::string name,std::string desc,int baseDmg,int randomDmg,int PPCost,int range,std::array<int,4>composition,Effect*eff=nullptr,bool pctDamage=false,std::vector<std::pair<Property,int>> properties={})
:Move(name,desc,0,baseDmg,randomDmg,PPCost,range,0,false,composition,eff,pctDamage,properties){};
Move(std::string name,std::string desc,int baseDmg,int randomDmg,int PPCost,int range,int channelTime,bool friendly,std::array<int,4>composition,Effect*eff=nullptr,bool pctDamage=false,std::vector<std::pair<Property,int>> properties={})
:Move(name,desc,0,baseDmg,randomDmg,PPCost,range,channelTime,friendly,composition,eff,pctDamage,properties){};
Move(std::string name,std::string desc,int grade,int baseDmg,int randomDmg,int PPCost,int range,int channelTime,bool friendly,std::array<int,4>composition,Effect*eff=nullptr,bool pctDamage=false,std::vector<std::pair<Property,int>> properties={})
:name(name),grade(grade),PPCost(PPCost),desc(desc),randomDmg(randomDmg),baseDmg(baseDmg),range(range),friendly(friendly),eff(eff),channelTime(channelTime),composition(composition),pctDamage(pctDamage),properties(properties){}
};
}
#endif

@ -1,3 +1,8 @@
#ifndef DEFINES_H
#define DEFINES_H
#include "pixelGameEngine.h"
using namespace olc;
#define WIDTH 256 #define WIDTH 256
#define HEIGHT 224 #define HEIGHT 224
@ -7,4 +12,27 @@
#define TILEMAP_EDITOR_TILESIZE (32*TILEMAP_EDITOR_DRAW_MULT) #define TILEMAP_EDITOR_TILESIZE (32*TILEMAP_EDITOR_DRAW_MULT)
#define PARTY_TRAIL_LENGTH 48 #define PARTY_TRAIL_LENGTH 48
#define CAMERA_WAIT_TIME 60 #define CAMERA_WAIT_TIME 60
#define HEALTH_ROLLING_SPEED 2 #define HEALTH_ROLLING_SPEED 2
#define ㅎ
#define ㅍ
#define 아
#define α 0x391
#define β 0x392
#define γ 0x3b3
#define Ω 0x3a3
#define Σ 0x3a9
#define AddAsyncCutsceneAction(AsyncClass) \
if (!((AsyncClass*)CurrentCutscene->GetAction())->InQueue()) { \
CUTSCENE_QUEUE.push_back(CurrentCutscene->GetAction()); \
} \
((AsyncClass*)CurrentCutscene->GetAction())->SetQueued(); \
CurrentCutscene->AdvanceAction(); \
#define 액션 (CutsceneAction*)new
extern PixelGameEngine*GAME;
extern vd2d cameraPos;
#endif

@ -1,3 +1,9 @@
#ifndef EFFECT_H
#define EFFECT_H
#include "particle.h"
#include "pixelGameEngine.h"
using namespace olc;
class Effect{ class Effect{
public: public:
std::vector<Particle*> particles; std::vector<Particle*> particles;
@ -32,4 +38,5 @@ class FountainEffect:public Effect{
} }
}; };
FountainEffect*FOUNTAIN_EFFECT; FountainEffect*FOUNTAIN_EFFECT;
#endif

@ -1,3 +1,12 @@
#ifndef ENCOUNTERS_H
#define ENCOUNTERS_H
#include "pixelGameEngine.h"
using namespace olc;
#include "defines.h"
#include "object.h"
#include "battle.h"
#include "item.h"
namespace encounter{ namespace encounter{
enum{ enum{
ENCOUNTER_1, ENCOUNTER_1,
@ -5,4 +14,90 @@ namespace encounter{
ENCOUNTER_3, ENCOUNTER_3,
ENCOUNTER_4, ENCOUNTER_4,
}; };
} }
class Entity{
private:
int HP=0;
int targetHP=0;
public:
int maxHP=0;
int PP=0;
int targetPP=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;
int selectedTarget = 0;
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 = {0,0}; //Where our channel is happening.
std::vector<Item*> inventory; //Used mostly for enemy spoils.
std::array<Item*,3> equipment; //Equipment this character is using.
//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){}
//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;
}
//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;
}
//Sets the rolling counter target to this health value.
void SetTargetHP(int hp) {
targetHP=hp;
}
//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);
}
//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;
}
};
class Encounter{
public:
vd2d pos;
int chance; //Chance of the encounter existing.
std::vector<Entity*>objs;
std::array<vd2d,4> playerPos;
int id;
Encounter(int id,vd2d pos,std::array<vd2d,4> playerPos,std::vector<Entity*>objs,int chance=25)
:id(id),pos(pos),objs(objs),chance(chance),playerPos(playerPos){}
bool IsEncounterAlive() {
for (int i=0;i<objs.size();i++) {
if (objs[i]->GetHP()>0) {
return true;
}
}
return false;
}
bool IsInRange(vd2d pos) {
vd2d diff=pos-this->pos;
return diff.x>=0&&diff.x<=WIDTH&&diff.y>=0&&diff.y<=HEIGHT;
}
};
#endif

@ -1,3 +1,5 @@
#ifndef FLAGS_H
#define FLAGS_H
enum class Flag:int{ enum class Flag:int{
NONE, NONE,
TEST_FLAG1, TEST_FLAG1,
@ -18,4 +20,5 @@ template <typename Enumeration>
auto toint(Enumeration const value) -> typename std::underlying_type<Enumeration>::type auto toint(Enumeration const value) -> typename std::underlying_type<Enumeration>::type
{ {
return static_cast<typename std::underlying_type<Enumeration>::type>(value); return static_cast<typename std::underlying_type<Enumeration>::type>(value);
} }
#endif

@ -1,64 +0,0 @@
#ifndef GAME_INIT_H
#define GAME_INIT_H
#define PARTY_TRAIL_LENGTH 48
#include "pixelGameEngine.h"
#include "encounters.h"
#include "map.h"
#include "states.h"
#include "references.h"
#include "cutscene.h"
#include "tiles.h"
using namespace olc;
static PixelGameEngine*GAME;
static std::vector<Object*>OBJECTS;
static vd2d cameraPos;
static std::vector<Encounter*>ENCOUNTER_LIST;
static int frameCount=0;
static float elapsedTime=0;
static const float TARGET_RATE = 1/60.0;
static int MAP_WIDTH=-1;
static int MAP_HEIGHT=-1;
static Map*CURRENT_MAP;
static Map*MAP_ONETT;
static int GAME_STATE = GameState::EDITOR;
static vi2d SELECTED_TILE={0,0};
static vi2d HIGHLIGHTED_TILE={0,0};
static int EDITING_LAYER=layer::DYNAMIC;
static int SELECTED_OBJ_ID = PLAYER;
static int OBJ_DISPLAY_OFFSET = 0;
static bool GAME_FLAGS[128]={};
static std::array<Object*,4> PARTY_MEMBER_OBJ;
static std::array<Entity*,7> PARTY_MEMBER_STATS;
static bool messageBoxVisible=false;
static std::string messageBoxText="";
static std::string messageBoxTargetText="";
static std::string messageBoxFinalText="";
static int messageBoxMarker=0;
static int messageBoxStartMarker=0; //Start of text display.
static int messageBoxStopMarker=0; //End of text display for current printout.
static int messageBoxFrameWaitTime=1;
static bool messageBoxLoad=false; //Set to true when ready to load a message in.
static std::map<int,vi2d> additionalChars;
static Cutscene*TestCutscene;
static Cutscene*CurrentCutscene=nullptr;
static ActionType CurrentAction=ActionType::NONE;
static double CUTSCENE_FADE_VALUE=0;
static std::vector<CutsceneAction*>CUTSCENE_QUEUE;
static std::map<BattleMoveName,Battle::Move*>MOVELIST;
static std::array<vd2d,PARTY_TRAIL_LENGTH> partyTrail={vd2d{0,0}};
static int PARTY_MEMBER_COUNT = 1;
static int ENCOUNTER_SELECTED = 0;
static int ENCOUNTER_OFFSET = 0;
static bool MOUSE_PRESSED_DOWN=false,MOUSE_DOWN=false,MOUSE_RELEASED=false; //TODO Implement Mouse things.static
static std::vector<std::vector<TILE*>> MAP; //The foreground layer.
static std::vector<std::vector<TILE*>> MAP2;
static std::vector<std::vector<TILE*>> MAP3;
static std::vector<std::vector<TILE*>> MAP4;
static std::vector<std::vector<TILE*>> MAP5; //Collision Layer
static std::map<std::string,Decal*> SPRITES;
static std::map<std::string,Animation*> ANIMATIONS;
static std::map<int,Object*> OBJ_INFO;
#endif

@ -0,0 +1,43 @@
#ifndef ITEM_H
#define ITEM_H
#include "pixelGameEngine.h"
using namespace olc;
#include "battle.h"
enum class ItemName{
COOKIE,
EGG,
PIZZA,
CRACKED_BAT,
LIGHT_JACKET,
KEY_TO_THE_PALACE,
};
namespace EquipSlot{
enum Equip{
WEAPON,
ARMOR,
ACCESSORY,
NONE
};
}
struct ItemStatsStruct{
int hpRecovery=0;
int ppRecovery=0;
int attack=0;
int defense=0;
EquipSlot::Equip equip=EquipSlot::NONE; //Whether or not this is equipment.
bool important=false; //If an item's important it can't be discarded.
bool consumable=false; //Whether or not this item is consumed when used.
};
class Item{
public:
std::string name;
std::string description;
Battle::Move*battlemove=nullptr;
ItemStatsStruct stats;
Item(std::string name,std::string desc,ItemStatsStruct stats={0,0,0,0,EquipSlot::NONE,false,false},Battle::Move*battlemove=nullptr)
:name(name),description(desc),stats(stats),battlemove(battlemove){}
};
#endif

@ -15,28 +15,13 @@
#include "particle.h" #include "particle.h"
#include "effect.h" #include "effect.h"
#define ㅎ using namespace olc;
#define ㅍ
#define 아
#define α 0x391
#define β 0x392
#define γ 0x3b3
#define Ω 0x3a3
#define Σ 0x3a9
#define AddAsyncCutsceneAction(AsyncClass) \
if (!((AsyncClass*)CurrentCutscene->GetAction())->InQueue()) { \
CUTSCENE_QUEUE.push_back(CurrentCutscene->GetAction()); \
} \
((AsyncClass*)CurrentCutscene->GetAction())->SetQueued(); \
CurrentCutscene->AdvanceAction(); \
#define 액션 (CutsceneAction*)new
std::vector<Object*> OBJECTS; std::vector<Object*> OBJECTS;
const vd2d NO_NEIGHBOR = {-999,-999}; const vd2d NO_NEIGHBOR = {-999,-999};
using namespace olc; vd2d cameraPos={0,0};
PixelGameEngine*GAME;
enum{ enum{
ALPHA=α, ALPHA=α,
@ -59,215 +44,6 @@ namespace layer{
}; };
} }
class Animation{
public:
Decal*spr;
int frames=1;
int width=0;
Animation(Decal*spr,int width){
this->frames=spr->sprite->width/width;
this->width=width;
this->spr=spr;
}
};
vd2d cameraPos = {0,0};
PixelGameEngine*GAME;
class Object{
private:
vd2d scale={1,1};
vd2d pos;
public:
int id;
Animation*spr;
int frameIndex=0;
int frameCount=0;
int animationSpd=12; //How many frames to wait between each frame. Setting to 0 pauses the animation.
std::string name;
Pixel color=WHITE;
vd2d originPoint={0,0};
bool drawn=false;
Flag disableFlag=Flag::NONE;
Flag enableFlag=Flag::NONE;
int objArrElement; //Which element in the object array this object is located in. For sorting purposes.
bool temp=false; //If set to true, it's marked for deletion after cutscene handling.
bool enc=false; //If set to true, it's not included in the main list of entities for map saving because it's from an encounter.
bool dead=false; //If set to true, this object was properly part of an Entity and got declared as dead.
int blinkFrames=0; //Frame count of how much time is left for the image to be blinking. Used when enemies take damage.
//animationSpd is how long to wait before switching frames.
bool highlighted=false; //Whether or not this object has been declared as highlighted by a target range selector.
bool Collision(vd2d pos) {
GAME->SetDrawTarget(layer::COLLISION);
Pixel collisionData = GAME->GetDrawTarget()->GetPixel((int)pos.x-cameraPos.x,(int)pos.y-cameraPos.y);
return collisionData!=MAGENTA;
}
//A grid version of the constructor. used ONLY for battle setups.
Object(int id,std::string name,int gridx,int gridy,Animation*spr,vd2d scale={1,1},Pixel color=WHITE,int animationSpd=1,bool temp=false)
:Object(id,name,{gridx*32-(spr->width*0.5)*(scale.x-1),gridy*32-(spr->spr->sprite->height-4)*(scale.y-1)},spr,scale,color,animationSpd,temp) {}
Object(int id,std::string name,vd2d pos,Animation*spr,vd2d scale={1,1},Pixel color=WHITE,int animationSpd=1,bool temp=false) {
this->spr=spr;
this->pos=pos;
this->id=id;
this->name=name;
this->color=color;
this->animationSpd=animationSpd;
SetScale(scale);
this->temp=temp;
}
void SetScale(vd2d scale) {
this->scale=scale;
this->originPoint={spr->width/2*scale.x,(spr->spr->sprite->height-4)*scale.y};
}
vd2d GetScale() {
return scale;
}
vd2d GetPos() {
return pos;
}
void Move(vd2d move) {
if (move.y==0) {
pos+=move;
return;
} else {
if (move.y<0) {
while (objArrElement>0&&OBJECTS[objArrElement-1]->pos.y+OBJECTS[objArrElement-1]->originPoint.y>pos.y+originPoint.y+move.y) {
//printf("%p(%s)<->%p(%s)\n",OBJECTS[objArrElement],OBJECTS[objArrElement]->name.c_str(),OBJECTS[objArrElement-1],OBJECTS[objArrElement-1]->name.c_str());
OBJECTS[objArrElement]=OBJECTS[objArrElement-1];
//printf(" %p(%s)<->%p(%s)\n",OBJECTS[objArrElement],OBJECTS[objArrElement]->name.c_str(),OBJECTS[objArrElement-1],OBJECTS[objArrElement-1]->name.c_str());
OBJECTS[objArrElement-1]=this;
//printf(" %p(%s)<->%p(%s)\n",OBJECTS[objArrElement],OBJECTS[objArrElement]->name.c_str(),OBJECTS[objArrElement-1],OBJECTS[objArrElement-1]->name.c_str());
OBJECTS[objArrElement]->objArrElement=objArrElement;
//printf(" %p(%s)(%d)<->%p(%s)(%d)\n",OBJECTS[objArrElement],OBJECTS[objArrElement]->name.c_str(),OBJECTS[objArrElement]->objArrElement,OBJECTS[objArrElement-1],OBJECTS[objArrElement-1]->name.c_str(),objArrElement-1);
objArrElement--;
}
} else {
while (objArrElement<OBJECTS.size()-1&&OBJECTS[objArrElement+1]->pos.y+OBJECTS[objArrElement+1]->originPoint.y<pos.y+originPoint.y+move.y) {
//printf("%p(%s)<->%p(%s)\n",OBJECTS[objArrElement],OBJECTS[objArrElement]->name.c_str(),OBJECTS[objArrElement+1],OBJECTS[objArrElement+1]->name.c_str());
OBJECTS[objArrElement]=OBJECTS[objArrElement+1];
//printf(" %p(%s)<->%p(%s)\n",OBJECTS[objArrElement],OBJECTS[objArrElement]->name.c_str(),OBJECTS[objArrElement+1],OBJECTS[objArrElement+1]->name.c_str());
OBJECTS[objArrElement+1]=this;
//printf(" %p(%s)<->%p(%s)\n",OBJECTS[objArrElement],OBJECTS[objArrElement]->name.c_str(),OBJECTS[objArrElement+1],OBJECTS[objArrElement+1]->name.c_str());
OBJECTS[objArrElement]->objArrElement=objArrElement;
//printf(" %p(%s)(%d)<->%p(%s)(%d)\n",OBJECTS[objArrElement],OBJECTS[objArrElement]->name.c_str(),OBJECTS[objArrElement]->objArrElement,OBJECTS[objArrElement+1],OBJECTS[objArrElement+1]->name.c_str(),objArrElement+1);
objArrElement++;
}
}
pos+=move;
}
}
void SetPos(vd2d pos) {
Move(pos-this->pos);
}
vd2d GetPosWithOrigin() {
return GetPos()+originPoint;
}
bool SmoothMove(vd2d move) {
const int wiggleRoom=5;
vd2d originPos = {pos.x+originPoint.x,pos.y-1+originPoint.y};
if (!Collision(originPos+move)) {
Move(move);
return true;
} else
if (move.x!=0&&!Collision({originPos.x+move.x,originPos.y})) {
Move({move.x,0});
return true;
} else
if (move.y!=0&&!Collision({originPos.x,originPos.y+move.y})) {
Move({0,move.y});
return true;
}
else
if (move.x>0) {
for (int i=0;i<wiggleRoom;i++) { //Search Up.
if (!Collision({originPos.x+move.x,originPos.y-i})) {
//There is potentially to move up-right here, so we will do so.
Move({0,-1});
originPos.y+=-1;
return true;
}
}
for (int i=0;i<wiggleRoom;i++) { //Search Down.
if (!Collision({originPos.x+move.x,originPos.y+i})) {
//There is potentially to move down-right here, so we will do so.
Move({0,1});
return true;
}
}
} else
if (move.x<0) {
for (int i=0;i<wiggleRoom;i++) { //Search Up.
if (!Collision({originPos.x+move.x,originPos.y-i})) {
//There is potentially to move up-left here, so we will do so.
Move({0,-1});
return true;
}
}
for (int i=0;i<wiggleRoom;i++) { //Search Down.
if (!Collision({originPos.x+move.x,originPos.y+i})) {
//There is potentially to move down-left here, so we will do so.
Move({0,1});
return true;
}
}
}
if (move.y>0) {
for (int i=0;i<wiggleRoom;i++) { //Search Left.
if (!Collision({originPos.x-i,originPos.y+move.y})) {
//There is potentially to move down-left here, so we will do so.
Move({-1,0});
return true;
}
}
for (int i=0;i<wiggleRoom;i++) { //Search Right.
if (!Collision({originPos.x+i,originPos.y+move.y})) {
//There is potentially to move down-right here, so we will do so.
Move({1,0});
return true;
}
}
} else
if (move.y<0) {
for (int i=0;i<wiggleRoom;i++) { //Search Left.
if (!Collision({originPos.x-i,originPos.y+move.y})) {
//There is potentially to move up-left here, so we will do so.
Move({-1,0});
return true;
}
}
for (int i=0;i<wiggleRoom;i++) { //Search Right.
if (!Collision({originPos.x+i,originPos.y+move.y})) {
//There is potentially to move up-right here, so we will do so.
Move({1,0});
return true;
}
}
}
return false;
}
};
enum class Resistance{
WET,
DRY,
COLD,
HEAT,
};
enum class Property{
PETRIFY,
PARALYZE,
DIAMONDIZE,
CRYING,
SLOW,
MUSHROOMIZED,
CONFUSE,
POISON,
REGEN,
DEFENSE_UP,
REVIVE,
};
enum class BattleMoveName{ enum class BattleMoveName{
TESTMOVE1, TESTMOVE1,
TESTMOVE2, TESTMOVE2,
@ -308,159 +84,8 @@ enum class BattleMoveName{
PKFIRE_O, PKFIRE_O,
}; };
enum class ItemName{
COOKIE,
EGG,
PIZZA,
CRACKED_BAT,
LIGHT_JACKET,
KEY_TO_THE_PALACE,
};
template<typename T, typename F> inline T transform_to( F str ) noexcept{if (str.empty()) return {}; return { std::begin(str), std::end(str) };}; template<typename T, typename F> inline T transform_to( F str ) noexcept{if (str.empty()) return {}; return { std::begin(str), std::end(str) };};
namespace Battle{
class Move{
public:
std::string name;
std::string desc;
std::array<int,4>composition;
int baseDmg; //The base damage of the attack.
int randomDmg; //Additional random roll damage to add onto the base damage.
bool pctDamage; //Uses % damage for the base damage instead of flat damage.
std::vector<std::pair<Property,int>> properties; //The int is used to determine the chance of something occurring.
//Properties order is WET, DRY, COLD, HEAT
int PPCost=0;
int grade=0; //If the name of a move name match, then the grade helps sort it into the same category on menus.
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.
Effect*eff=nullptr;
//Assumes friendly is false.
Move(std::string name,std::string desc,int baseDmg,int randomDmg,int PPCost,int range,std::array<int,4>composition,Effect*eff=nullptr,bool pctDamage=false,std::vector<std::pair<Property,int>> properties={})
:Move(name,desc,0,baseDmg,randomDmg,PPCost,range,0,false,composition,eff,pctDamage,properties){};
Move(std::string name,std::string desc,int baseDmg,int randomDmg,int PPCost,int range,int channelTime,bool friendly,std::array<int,4>composition,Effect*eff=nullptr,bool pctDamage=false,std::vector<std::pair<Property,int>> properties={})
:Move(name,desc,0,baseDmg,randomDmg,PPCost,range,channelTime,friendly,composition,eff,pctDamage,properties){};
Move(std::string name,std::string desc,int grade,int baseDmg,int randomDmg,int PPCost,int range,int channelTime,bool friendly,std::array<int,4>composition,Effect*eff=nullptr,bool pctDamage=false,std::vector<std::pair<Property,int>> properties={})
:name(name),grade(grade),PPCost(PPCost),desc(desc),randomDmg(randomDmg),baseDmg(baseDmg),range(range),friendly(friendly),eff(eff),channelTime(channelTime),composition(composition),pctDamage(pctDamage),properties(properties){}
};
}
namespace EquipSlot{
enum Equip{
WEAPON,
ARMOR,
ACCESSORY,
NONE
};
}
struct ItemStatsStruct{
int hpRecovery=0;
int ppRecovery=0;
int attack=0;
int defense=0;
EquipSlot::Equip equip=EquipSlot::NONE; //Whether or not this is equipment.
bool important=false; //If an item's important it can't be discarded.
bool consumable=false; //Whether or not this item is consumed when used.
};
class Item{
public:
std::string name;
std::string description;
Battle::Move*battlemove=nullptr;
ItemStatsStruct stats;
Item(std::string name,std::string desc,ItemStatsStruct stats={0,0,0,0,EquipSlot::NONE,false,false},Battle::Move*battlemove=nullptr)
:name(name),description(desc),stats(stats),battlemove(battlemove){}
};
class Entity{
private:
int HP=0;
int targetHP=0;
public:
int maxHP=0;
int PP=0;
int targetPP=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;
int selectedTarget = 0;
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 = {0,0}; //Where our channel is happening.
std::vector<Item*> inventory; //Used mostly for enemy spoils.
std::array<Item*,3> equipment; //Equipment this character is using.
//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){}
//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;
}
//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;
}
//Sets the rolling counter target to this health value.
void SetTargetHP(int hp) {
targetHP=hp;
}
//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);
}
//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;
}
};
class Encounter{
public:
vd2d pos;
int chance; //Chance of the encounter existing.
std::vector<Entity*>objs;
std::array<vd2d,4> playerPos;
int id;
Encounter(int id,vd2d pos,std::array<vd2d,4> playerPos,std::vector<Entity*>objs,int chance=25)
:id(id),pos(pos),objs(objs),chance(chance),playerPos(playerPos){}
bool IsEncounterAlive() {
for (int i=0;i<objs.size();i++) {
if (objs[i]->GetHP()>0) {
return true;
}
}
return false;
}
bool IsInRange(vd2d pos) {
vd2d diff=pos-this->pos;
return diff.x>=0&&diff.x<=WIDTH&&diff.y>=0&&diff.y<=HEIGHT;
}
};
class Map{ class Map{
public: public:
std::string filename; std::string filename;
@ -587,6 +212,7 @@ public:
bool OnUserCreate() override bool OnUserCreate() override
{ {
srand(time(NULL)); srand(time(NULL));
GAME=this; GAME=this;
for (int i=1;i<6;i++) { for (int i=1;i<6;i++) {
@ -2049,7 +1675,7 @@ This is a test message that lets us trigger straight from a cutscene! Cool!)"),
LoadEncounter(map,{x,y},pct,id,rand()%100<pct); LoadEncounter(map,{x,y},pct,id,rand()%100<pct);
printf("Encounter %d (%d\%) Loaded.\n",id,pct); printf("Encounter %d (%d%c) Loaded.\n",id,pct,'%');
} }
} else { } else {
std::vector<TILE*> tiles; std::vector<TILE*> tiles;

@ -0,0 +1,42 @@
#include "object.h"
#include "layers.h"
#include "defines.h"
extern std::vector<Object*> OBJECTS;
bool Object::Collision(vd2d pos){
GAME->SetDrawTarget(layer::COLLISION);
Pixel collisionData = GAME->GetDrawTarget()->GetPixel((int)pos.x-cameraPos.x,(int)pos.y-cameraPos.y);
return collisionData!=MAGENTA;
}
void Object::Move(vd2d move) {
if (move.y==0) {
pos+=move;
return;
} else {
if (move.y<0) {
while (objArrElement>0&&OBJECTS[objArrElement-1]->pos.y+OBJECTS[objArrElement-1]->originPoint.y>pos.y+originPoint.y+move.y) {
//printf("%p(%s)<->%p(%s)\n",OBJECTS[objArrElement],OBJECTS[objArrElement]->name.c_str(),OBJECTS[objArrElement-1],OBJECTS[objArrElement-1]->name.c_str());
OBJECTS[objArrElement]=OBJECTS[objArrElement-1];
//printf(" %p(%s)<->%p(%s)\n",OBJECTS[objArrElement],OBJECTS[objArrElement]->name.c_str(),OBJECTS[objArrElement-1],OBJECTS[objArrElement-1]->name.c_str());
OBJECTS[objArrElement-1]=this;
//printf(" %p(%s)<->%p(%s)\n",OBJECTS[objArrElement],OBJECTS[objArrElement]->name.c_str(),OBJECTS[objArrElement-1],OBJECTS[objArrElement-1]->name.c_str());
OBJECTS[objArrElement]->objArrElement=objArrElement;
//printf(" %p(%s)(%d)<->%p(%s)(%d)\n",OBJECTS[objArrElement],OBJECTS[objArrElement]->name.c_str(),OBJECTS[objArrElement]->objArrElement,OBJECTS[objArrElement-1],OBJECTS[objArrElement-1]->name.c_str(),objArrElement-1);
objArrElement--;
}
} else {
while (objArrElement<OBJECTS.size()-1&&OBJECTS[objArrElement+1]->pos.y+OBJECTS[objArrElement+1]->originPoint.y<pos.y+originPoint.y+move.y) {
//printf("%p(%s)<->%p(%s)\n",OBJECTS[objArrElement],OBJECTS[objArrElement]->name.c_str(),OBJECTS[objArrElement+1],OBJECTS[objArrElement+1]->name.c_str());
OBJECTS[objArrElement]=OBJECTS[objArrElement+1];
//printf(" %p(%s)<->%p(%s)\n",OBJECTS[objArrElement],OBJECTS[objArrElement]->name.c_str(),OBJECTS[objArrElement+1],OBJECTS[objArrElement+1]->name.c_str());
OBJECTS[objArrElement+1]=this;
//printf(" %p(%s)<->%p(%s)\n",OBJECTS[objArrElement],OBJECTS[objArrElement]->name.c_str(),OBJECTS[objArrElement+1],OBJECTS[objArrElement+1]->name.c_str());
OBJECTS[objArrElement]->objArrElement=objArrElement;
//printf(" %p(%s)(%d)<->%p(%s)(%d)\n",OBJECTS[objArrElement],OBJECTS[objArrElement]->name.c_str(),OBJECTS[objArrElement]->objArrElement,OBJECTS[objArrElement+1],OBJECTS[objArrElement+1]->name.c_str(),objArrElement+1);
objArrElement++;
}
}
pos+=move;
}
}

@ -0,0 +1,146 @@
#ifndef OBJECT_H
#define OBJECT_H
#include "pixelGameEngine.h"
#include "flags.h"
#include "animation.h"
using namespace olc;
class Object{
private:
vd2d scale={1,1};
vd2d pos;
public:
int id;
Animation*spr;
int frameIndex=0;
int frameCount=0;
int animationSpd=12; //How many frames to wait between each frame. Setting to 0 pauses the animation.
std::string name;
Pixel color=WHITE;
vd2d originPoint={0,0};
bool drawn=false;
Flag disableFlag=Flag::NONE;
Flag enableFlag=Flag::NONE;
int objArrElement; //Which element in the object array this object is located in. For sorting purposes.
bool temp=false; //If set to true, it's marked for deletion after cutscene handling.
bool enc=false; //If set to true, it's not included in the main list of entities for map saving because it's from an encounter.
bool dead=false; //If set to true, this object was properly part of an Entity and got declared as dead.
int blinkFrames=0; //Frame count of how much time is left for the image to be blinking. Used when enemies take damage.
//animationSpd is how long to wait before switching frames.
bool highlighted=false; //Whether or not this object has been declared as highlighted by a target range selector.
bool Collision(vd2d pos);
//A grid version of the constructor. used ONLY for battle setups.
Object(int id,std::string name,int gridx,int gridy,Animation*spr,vd2d scale={1,1},Pixel color=WHITE,int animationSpd=1,bool temp=false)
:Object(id,name,{gridx*32-(spr->width*0.5)*(scale.x-1),gridy*32-(spr->spr->sprite->height-4)*(scale.y-1)},spr,scale,color,animationSpd,temp) {}
Object(int id,std::string name,vd2d pos,Animation*spr,vd2d scale={1,1},Pixel color=WHITE,int animationSpd=1,bool temp=false) {
this->spr=spr;
this->pos=pos;
this->id=id;
this->name=name;
this->color=color;
this->animationSpd=animationSpd;
SetScale(scale);
this->temp=temp;
}
void SetScale(vd2d scale) {
this->scale=scale;
this->originPoint={spr->width/2*scale.x,(spr->spr->sprite->height-4)*scale.y};
}
vd2d GetScale() {
return scale;
}
vd2d GetPos() {
return pos;
}
void Move(vd2d move);
void SetPos(vd2d pos) {
Move(pos-this->pos);
}
vd2d GetPosWithOrigin() {
return GetPos()+originPoint;
}
bool SmoothMove(vd2d move) {
const int wiggleRoom=5;
vd2d originPos = {pos.x+originPoint.x,pos.y-1+originPoint.y};
if (!Collision(originPos+move)) {
Move(move);
return true;
} else
if (move.x!=0&&!Collision({originPos.x+move.x,originPos.y})) {
Move({move.x,0});
return true;
} else
if (move.y!=0&&!Collision({originPos.x,originPos.y+move.y})) {
Move({0,move.y});
return true;
}
else
if (move.x>0) {
for (int i=0;i<wiggleRoom;i++) { //Search Up.
if (!Collision({originPos.x+move.x,originPos.y-i})) {
//There is potentially to move up-right here, so we will do so.
Move({0,-1});
originPos.y+=-1;
return true;
}
}
for (int i=0;i<wiggleRoom;i++) { //Search Down.
if (!Collision({originPos.x+move.x,originPos.y+i})) {
//There is potentially to move down-right here, so we will do so.
Move({0,1});
return true;
}
}
} else
if (move.x<0) {
for (int i=0;i<wiggleRoom;i++) { //Search Up.
if (!Collision({originPos.x+move.x,originPos.y-i})) {
//There is potentially to move up-left here, so we will do so.
Move({0,-1});
return true;
}
}
for (int i=0;i<wiggleRoom;i++) { //Search Down.
if (!Collision({originPos.x+move.x,originPos.y+i})) {
//There is potentially to move down-left here, so we will do so.
Move({0,1});
return true;
}
}
}
if (move.y>0) {
for (int i=0;i<wiggleRoom;i++) { //Search Left.
if (!Collision({originPos.x-i,originPos.y+move.y})) {
//There is potentially to move down-left here, so we will do so.
Move({-1,0});
return true;
}
}
for (int i=0;i<wiggleRoom;i++) { //Search Right.
if (!Collision({originPos.x+i,originPos.y+move.y})) {
//There is potentially to move down-right here, so we will do so.
Move({1,0});
return true;
}
}
} else
if (move.y<0) {
for (int i=0;i<wiggleRoom;i++) { //Search Left.
if (!Collision({originPos.x-i,originPos.y+move.y})) {
//There is potentially to move up-left here, so we will do so.
Move({-1,0});
return true;
}
}
for (int i=0;i<wiggleRoom;i++) { //Search Right.
if (!Collision({originPos.x+i,originPos.y+move.y})) {
//There is potentially to move up-right here, so we will do so.
Move({1,0});
return true;
}
}
}
return false;
}
};
#endif

@ -1,3 +1,9 @@
#ifndef PARTICLE_H
#include "pixelGameEngine.h"
#include "defines.h"
using namespace olc;
#define PARTICLE_H
class Particle{ class Particle{
public: public:
vd2d pos; vd2d pos;
@ -86,4 +92,5 @@ class WaterParticle:public Particle{
void render(PixelGameEngine*game)override{ void render(PixelGameEngine*game)override{
game->FillRectDecal(pos,size,col); game->FillRectDecal(pos,size,col);
} }
}; };
#endif
Loading…
Cancel
Save