Prep implementation of battle moves.

Co-authored-by: sigonasr2 <sigonasr2@gmail.com>
master
sigonasr2 2 years ago
parent ec34c66382
commit 8cb3198549
  1. BIN
      C++ProjectTemplate
  2. 3
      assets/maps/map0
  3. 5
      cutscene.h
  4. 7
      encounters.h
  5. 2
      flags.h
  6. 24
      ideas
  7. 171
      main.cpp

Binary file not shown.

@ -80,3 +80,6 @@ OBJECT256.000000;256.000000;2
OBJECT224.000000;256.000000;2
OBJECT192.000000;256.000000;2
OBJECT160.000000;256.000000;2
ENCOUNTER64;64;75;0
ENCOUNTER64;256;30;1
ENCOUNTER64;512;40;2

@ -29,7 +29,7 @@ enum class ActionType{
class CutsceneAction{
bool queued=false; //Set to true when added to action asynchronous queue.
public:
virtual ActionType GetActionType(){};
virtual ActionType GetActionType()=0;
bool InQueue() {
return queued;
}
@ -310,9 +310,6 @@ class Cutscene{
//MAKE SURE TO DELETE ALL OBJECTS IN THE OBJECTS WORLD ARRAY BEFORE CALLING THIS!
//THIS FUNCTION WILL DELETE THE POINTERS FOR YOU!
void CleanupCutscene() {
for (int i=0;i<cutsceneObjs.size();i++) {
delete cutsceneObjs[i];
}
cutsceneObjs.clear();
}
void SetupEndingCutsceneFlag(Flag flag,bool val=true) {

@ -0,0 +1,7 @@
namespace encounter{
enum{
ENCOUNTER_1,
ENCOUNTER_2,
ENCOUNTER_3,
};
}

@ -8,7 +8,7 @@ enum class Flag:int{
template <typename Enumeration>
auto flagint(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);
}

24
ideas

@ -115,3 +115,27 @@ Pan the Camera
Fade the game In/Out
Start Dialog
Set Game Flags
Moveset Selection:
There will be a couple of AI sets that enemies can use:
-> Random - As the name implies, every move will be picked at random.
-> Ordered - Orderered just goes down the list in order.
-> Weighted - There is a 50% chance to do the top move, and everytime it's not picked,
there's a 50% chance for the next move to be picked, and this continues down and down.
If the end is reached, that move is picked.
Example scenario: There are 5 moves.
50% Move 1
25% Move 2
12.5% Move 3
6.25% Move 4
6.25% Move 5
There will be a smart flag toggle. If smart is turned on, the AI will sometimes
try to use debuffs and healing moves when appropriate: Debuffs are attempted more
often in smart mode when players doesn't have said debuff yet and will try to avoid
the move if there's something better. Likewise, with smart mode if the enemy has a
healing move and is dying, it will attempt to use that.
There is also a dumb flag. The dumb flag will make the enemy try to use PP draining moves
even if they don't have enough PP for that move. This will mean they will waste turns after
they run out of PP.

@ -10,6 +10,7 @@
#include "flags.h"
#include <assert.h>
#include "cutscene.h"
#include "encounters.h"
#define WIDTH 256
#define HEIGHT 224
@ -25,6 +26,8 @@
((AsyncClass*)CurrentCutscene->GetAction())->SetQueued(); \
CurrentCutscene->AdvanceAction(); \
#define 액션 (CutsceneAction*)new
using namespace olc;
namespace layer{
@ -39,24 +42,6 @@ namespace layer{
};
}
class Map{
public:
std::string filename;
std::string l2filename;
std::string l3filename;
std::string l4filename;
std::string l5filename;
Decal*tileset;
Map(std::string fname,std::string layer2_fname,std::string layer3_fname,std::string layer4_fname,std::string layer5_fname,Decal*tileset) {
this->filename=fname;
this->l2filename=layer2_fname;
this->l3filename=layer3_fname;
this->l4filename=layer4_fname;
this->l5filename=layer5_fname;
this->tileset=tileset;
}
};
class Animation{
public:
Decal*spr;
@ -107,6 +92,103 @@ class Object{
}
};
enum class Resistance{
WET,
DRY,
COLD,
HEAT,
};
enum class Property{
PETRIFY,
PARALYZE,
DIAMONDIZE,
CRYING,
SLOW,
MUSHROOMIZED,
CONFUSE,
POISON,
REGEN,
DEFENSE_UP,
};
namespace Battle{
class Move{
public:
std::string name;
int composition[4];
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.
Move(std::string name,int baseDmg,int randomDmg,int composition[4]={},bool pctDamage=false,std::vector<std::pair<Property,int>> properties={})
:name(name),randomDmg(randomDmg),baseDmg(baseDmg),pctDamage(pctDamage),properties(properties){
for (int i=0;i<4;i++) {
this->composition[i]=composition[i];
}
}
};
}
class Entity{
public:
int HP=0;
int targetHP=0;
int maxHP=0;
int resistances[4]={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;
Object* obj;
std::vector<Battle::Move*> moveSet;
Entity(Object*obj,int HP,int maxHP,int baseAtk,std::array<int,4>resistances,int speed,std::vector<Battle::Move*>moveSet,int damageReduction=0,bool smart=false,bool dumb=false) {
this->obj=obj;
this->HP=this->targetHP=HP;
this->maxHP=maxHP;
for (int i=0;i<4;i++) {
this->resistances[i]=resistances[i];
}
this->speed=speed;
this->moveSet=moveSet;
this->smart=smart;
this->dumb=dumb;
this->baseAtk=baseAtk;
this->damageReduction=damageReduction;
}
};
class Encounter{
public:
vd2d pos;
int chance; //Chance of the encounter existing.
std::vector<Entity*>objs;
Encounter(vd2d pos,std::vector<Entity*>objs,int chance=25)
:pos(pos),objs(objs),chance(chance){}
};
class Map{
public:
std::string filename;
std::string l2filename;
std::string l3filename;
std::string l4filename;
std::string l5filename;
Decal*tileset;
std::vector<Encounter*> encounters;
Map(std::string fname,std::string layer2_fname,std::string layer3_fname,std::string layer4_fname,std::string layer5_fname,Decal*tileset) {
this->filename=fname;
this->l2filename=layer2_fname;
this->l3filename=layer3_fname;
this->l4filename=layer4_fname;
this->l5filename=layer5_fname;
this->tileset=tileset;
}
};
class SeasonI : public PixelGameEngine
{
public:
@ -194,21 +276,21 @@ public:
LoadMap(MAP_ONETT);
TestCutscene=new Cutscene({
(CutsceneAction*)new Fade(),
(CutsceneAction*)new CreateObjects({
Fade(),
CreateObjects({
new Object(PLAYER,"player",{64,64},ANIMATIONS["player.png"],{1,1},MAGENTA),
new Object(PLAYER,"player",{136,136},ANIMATIONS["player.png"],{1,1},RED),
new Object(PLAYER,"player",{96,96},ANIMATIONS["player.png"],{1,1},DARK_GREEN),
}),
(CutsceneAction*)new Fade(true),
(CutsceneAction*)new SetFlagWhenCutsceneEnds(Flag::TEST_FLAG1),
(CutsceneAction*)new PanCamera({128,128},BOTH,1),
(CutsceneAction*)new MoveCutsceneObjectAsync(1,{80,64},5),
(CutsceneAction*)new PanCamera({64,0},BOTH),
(CutsceneAction*)new DialogBoxAsync(R"(Hello!
Fade(true),
SetFlagWhenCutsceneEnds(Flag::TEST_FLAG1),
PanCamera({128,128},BOTH,1),
MoveCutsceneObjectAsync(1,{80,64},5),
PanCamera({64,0},BOTH),
DialogBoxAsync(R"(Hello!
This is a test message that lets us trigger straight from a cutscene! Cool!)"),
(CutsceneAction*)new ModifyObject(0,ANIMATIONS["player.png"],{5,5},MAGENTA),
(CutsceneAction*)new MoveCutsceneObject(1,{320,64},1),});
ModifyObject(0,ANIMATIONS["player.png"],{5,5},MAGENTA),
MoveCutsceneObject(1,{320,64},1),});
/*DisplayMessageBox(R"(Hello World!
This is a rather long message, but I hope it reaches you well
in some form or capacity or another. Even though it
@ -312,6 +394,7 @@ goes on a very long time, I hope you can understand this is only for testing pur
if (CUTSCENE_QUEUE.size()==0) {
for (int i=0;i<OBJECTS.size();i++) {
if (OBJECTS[i]->temp) {
delete OBJECTS[i];
OBJECTS.erase(OBJECTS.begin()+i--);
}
}
@ -798,7 +881,7 @@ goes on a very long time, I hope you can understand this is only for testing pur
if (MAP_WIDTH==-1) {
MAP_WIDTH=data.length()/2;
}
if (data.find("OBJECT")!=std::string::npos) {
if (data.find("OBJECT")!=std::string::npos||data.find("ENCOUNTER")!=std::string::npos) {
int marker=data.find_first_of(';');
int lastMarker=marker;
std::stringstream split1(data.substr(6,marker-6));
@ -816,6 +899,7 @@ goes on a very long time, I hope you can understand this is only for testing pur
int id;
split3>>id;
if (data.find("OBJECT")!=std::string::npos) {
bool enabled=true;
if (OBJ_INFO[id]->disableFlag!=Flag::NONE) {
if (GetGameFlag(OBJ_INFO[id]->disableFlag)) {
@ -831,6 +915,15 @@ goes on a very long time, I hope you can understand this is only for testing pur
AddObjectToWorld(CreateObject(id,{x,y}));
}
printf("Object %s Loaded.\n",OBJ_INFO[id]->name.c_str());
} else
if (data.find("ENCOUNTER")!=std::string::npos) {
marker=data.find_first_of(';',marker+1);
std::stringstream split4(data.substr(lastMarker+1,marker-lastMarker-1));
lastMarker=marker;
int pct=id;
split4>>id;
printf("Encounter %d (%d%) Loaded.\n",id,pct);
}
} else {
std::vector<TILE*> tiles;
printf("%s\n",data.c_str());
@ -1428,11 +1521,27 @@ goes on a very long time, I hope you can understand this is only for testing pur
}
void SetGameFlag(Flag flag,bool val) {
GAME_FLAGS[flagint(flag)]=val;
GAME_FLAGS[toint(flag)]=val;
}
bool GetGameFlag(Flag flag) {
return GAME_FLAGS[flagint(flag)];
return GAME_FLAGS[toint(flag)];
}
void LoadEncounter(Map*map,vd2d pos,int chance,int id) {
switch (id) {
case encounter::ENCOUNTER_1:{
map->encounters.push_back(
new Encounter(pos,
std::vector<Entity*>{new Entity(
new Object(
NPC1_4,"Test Obj",{pos.x+20,pos.y+48},ANIMATIONS["player.png"]
),70,70,14,std::array<int,4>{0,0,0,0},0,std::vector<Battle::Move*>{}
)}
,chance)
);
}break;
}
}
};

Loading…
Cancel
Save