|
|
|
@ -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,21 +899,31 @@ goes on a very long time, I hope you can understand this is only for testing pur |
|
|
|
|
int id; |
|
|
|
|
split3>>id; |
|
|
|
|
|
|
|
|
|
bool enabled=true; |
|
|
|
|
if (OBJ_INFO[id]->disableFlag!=Flag::NONE) { |
|
|
|
|
if (GetGameFlag(OBJ_INFO[id]->disableFlag)) { |
|
|
|
|
enabled=false; |
|
|
|
|
if (data.find("OBJECT")!=std::string::npos) { |
|
|
|
|
bool enabled=true; |
|
|
|
|
if (OBJ_INFO[id]->disableFlag!=Flag::NONE) { |
|
|
|
|
if (GetGameFlag(OBJ_INFO[id]->disableFlag)) { |
|
|
|
|
enabled=false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (OBJ_INFO[id]->enableFlag!=Flag::NONE) { |
|
|
|
|
if (!GetGameFlag(OBJ_INFO[id]->enableFlag)) { |
|
|
|
|
enabled=false; |
|
|
|
|
if (OBJ_INFO[id]->enableFlag!=Flag::NONE) { |
|
|
|
|
if (!GetGameFlag(OBJ_INFO[id]->enableFlag)) { |
|
|
|
|
enabled=false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (enabled) { |
|
|
|
|
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); |
|
|
|
|
} |
|
|
|
|
if (enabled) { |
|
|
|
|
AddObjectToWorld(CreateObject(id,{x,y})); |
|
|
|
|
} |
|
|
|
|
printf("Object %s Loaded.\n",OBJ_INFO[id]->name.c_str()); |
|
|
|
|
} 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; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|