|
|
|
#include "pixelGameEngine.h"
|
|
|
|
#include <cstdarg>
|
|
|
|
|
|
|
|
#define CAMERA_MOVESPD 5
|
|
|
|
|
|
|
|
using namespace olc;
|
|
|
|
|
|
|
|
enum PriorityDirection{
|
|
|
|
HORZ_FIRST,
|
|
|
|
VERT_FIRST,
|
|
|
|
BOTH
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class ActionType{
|
|
|
|
NONE,
|
|
|
|
PAN_CAMERA,
|
|
|
|
CREATE_OBJECTS,
|
|
|
|
CLEANUP,
|
|
|
|
SET_FLAG_WHEN_CUTSCENE_ENDS,
|
|
|
|
FADE,
|
|
|
|
DIALOG,
|
|
|
|
};
|
|
|
|
|
|
|
|
class CutsceneAction{
|
|
|
|
public:
|
|
|
|
virtual ActionType GetActionType(){};
|
|
|
|
};
|
|
|
|
|
|
|
|
class Cleanup:public CutsceneAction{
|
|
|
|
public:
|
|
|
|
ActionType GetActionType() override{return ActionType::CLEANUP;}
|
|
|
|
};
|
|
|
|
|
|
|
|
class Object;
|
|
|
|
|
|
|
|
class CreateObjects:public CutsceneAction{
|
|
|
|
private:
|
|
|
|
std::vector<Object*>objs;
|
|
|
|
public:
|
|
|
|
template <class T>
|
|
|
|
CreateObjects(std::initializer_list<T> objs) {
|
|
|
|
for( auto elem : objs )
|
|
|
|
{
|
|
|
|
this->objs.push_back(elem);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ActionType GetActionType() override{return ActionType::CREATE_OBJECTS;}
|
|
|
|
std::vector<Object*> GetObjects() {
|
|
|
|
return objs;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
class PanCamera:public CutsceneAction{
|
|
|
|
private:
|
|
|
|
vd2d targetPos;
|
|
|
|
PriorityDirection dir;
|
|
|
|
double cameraSpd;
|
|
|
|
public:
|
|
|
|
PanCamera(vd2d targetPos,PriorityDirection dir,double cameraSpd=CAMERA_MOVESPD) {
|
|
|
|
this->targetPos=targetPos;
|
|
|
|
this->dir=dir;
|
|
|
|
this->cameraSpd=cameraSpd;
|
|
|
|
}
|
|
|
|
ActionType GetActionType() override{return ActionType::PAN_CAMERA;}
|
|
|
|
vd2d GetCameraTargetPos() {
|
|
|
|
return targetPos;
|
|
|
|
}
|
|
|
|
PriorityDirection GetPriorityDirection() {
|
|
|
|
return dir;
|
|
|
|
}
|
|
|
|
double GetCameraSpeed() {
|
|
|
|
return cameraSpd;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class SetFlagWhenCutsceneEnds:public CutsceneAction{
|
|
|
|
private:
|
|
|
|
Flag flag;
|
|
|
|
bool val;
|
|
|
|
public:
|
|
|
|
SetFlagWhenCutsceneEnds(Flag flag,bool val=true) {
|
|
|
|
this->flag=flag;
|
|
|
|
this->val=val;
|
|
|
|
}
|
|
|
|
ActionType GetActionType() override{return ActionType::SET_FLAG_WHEN_CUTSCENE_ENDS;}
|
|
|
|
Flag GetCutsceneEndingFlag() {
|
|
|
|
return flag;
|
|
|
|
}
|
|
|
|
bool GetCutsceneEndingVal() {
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class Fade:public CutsceneAction{
|
|
|
|
private:
|
|
|
|
bool fadeIn=true; //If false, it fades out instead.
|
|
|
|
double fadeSpd=0;
|
|
|
|
public:
|
|
|
|
//If false, it fades out instead.
|
|
|
|
Fade(bool fadeIn=false,double fadeSpd=4) {
|
|
|
|
this->fadeIn=fadeIn;
|
|
|
|
this->fadeSpd=fadeSpd;
|
|
|
|
}
|
|
|
|
ActionType GetActionType() override{return ActionType::FADE;}
|
|
|
|
//If false, then it means we need to fade out instead.
|
|
|
|
bool FadeIn() {
|
|
|
|
return fadeIn;
|
|
|
|
}
|
|
|
|
double GetFadeSpd() {
|
|
|
|
return fadeSpd;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class DialogBox:public CutsceneAction{
|
|
|
|
private:
|
|
|
|
std::string message;
|
|
|
|
bool messageBoxVisible=false;
|
|
|
|
public:
|
|
|
|
//If false, it fades out instead.
|
|
|
|
DialogBox(std::string message) {
|
|
|
|
this->message=message;
|
|
|
|
}
|
|
|
|
ActionType GetActionType() override{return ActionType::DIALOG;}
|
|
|
|
//If false, then it means we need to fade out instead.
|
|
|
|
std::string GetMessage() {
|
|
|
|
return message;
|
|
|
|
}
|
|
|
|
void SetMessageBoxVisible() {
|
|
|
|
this->messageBoxVisible=true;
|
|
|
|
}
|
|
|
|
bool MessageHasBeenShown() {
|
|
|
|
return messageBoxVisible;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
To use this class, specify multiple actions back-to-back, filling their appropriate arguments.
|
|
|
|
|
|
|
|
In responsive events, poll what CurrentAction() is, and if it's suitable, then use LockAction()
|
|
|
|
to lock the event and perform whatever actions are required. When the cutscene action is complete,
|
|
|
|
you can advance the action using AdvanceAction().
|
|
|
|
*/
|
|
|
|
class Cutscene{
|
|
|
|
private:
|
|
|
|
int actionMarker=0;
|
|
|
|
std::vector<CutsceneAction*> actions;
|
|
|
|
bool actionIsActive=false;
|
|
|
|
std::vector<Object*>cutsceneObjs;
|
|
|
|
Flag storedFlag=Flag::NONE;
|
|
|
|
bool storedVal=true;
|
|
|
|
public:
|
|
|
|
template <class T>
|
|
|
|
Cutscene(std::initializer_list<T> actions) {
|
|
|
|
AddAction(actions);
|
|
|
|
};
|
|
|
|
template <class T>
|
|
|
|
void AddAction( std::initializer_list<T> actions )
|
|
|
|
{
|
|
|
|
for( auto elem : actions )
|
|
|
|
{
|
|
|
|
this->actions.push_back(elem);
|
|
|
|
}
|
|
|
|
this->actions.push_back(new Cleanup());
|
|
|
|
}
|
|
|
|
CutsceneAction*GetAction(){
|
|
|
|
return actions[actionMarker];
|
|
|
|
}
|
|
|
|
ActionType CurrentAction(){
|
|
|
|
if (!actionIsActive&&actionMarker<actions.size()) {
|
|
|
|
return actions[actionMarker]->GetActionType();
|
|
|
|
} else {
|
|
|
|
return ActionType::NONE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void LockAction() {
|
|
|
|
actionIsActive=true;
|
|
|
|
}
|
|
|
|
void AdvanceAction(){
|
|
|
|
actionIsActive=false;
|
|
|
|
actionMarker++;
|
|
|
|
}
|
|
|
|
void ResetCutscene(){
|
|
|
|
actionMarker=0;
|
|
|
|
actionIsActive=false;
|
|
|
|
}
|
|
|
|
Object*AddCutsceneObject(Object*obj) {
|
|
|
|
this->cutsceneObjs.push_back(obj);
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
std::vector<Object*> GetCutsceneObjects() {
|
|
|
|
return cutsceneObjs;
|
|
|
|
}
|
|
|
|
//Does things like reset cutscene flags and removing objects.
|
|
|
|
//
|
|
|
|
//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) {
|
|
|
|
storedFlag=flag;
|
|
|
|
storedVal=val;
|
|
|
|
}
|
|
|
|
Flag GetEndingCutsceneFlag() {
|
|
|
|
return storedFlag;
|
|
|
|
}
|
|
|
|
bool GetEndingCutsceneVal() {
|
|
|
|
return storedVal;
|
|
|
|
}
|
|
|
|
};
|