generated from sigonasr2/CPlusPlusProjectTemplate
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1069 lines
38 KiB
1069 lines
38 KiB
#define OLC_PGE_APPLICATION
|
|
#include "pixelGameEngine.h"
|
|
#include "data.h"
|
|
#define OLC_PGEX_SPLASHSCREEN
|
|
#include "splash.h"
|
|
|
|
using namespace olc;
|
|
|
|
enum GAMESTATE{
|
|
CUTSCENE_1,
|
|
CUTSCENE_2,
|
|
CUTSCENE_3,
|
|
GAMEWORLD,
|
|
WAITING_FOR_CUTSCENE_3,
|
|
};
|
|
|
|
namespace cutscene{
|
|
enum CUTSCENE{
|
|
NONE,
|
|
PAN_DOME,
|
|
PAUSE_TO_CUTSCENE_3,
|
|
CUTSCENE_4,
|
|
TRANSITION_CUTSCENE,
|
|
};
|
|
}
|
|
|
|
namespace battle{
|
|
enum BATTLESTATE{
|
|
NONE,
|
|
WAITING_FOR_CAMERA,
|
|
PLAYER_SELECTION,
|
|
ENEMY_SELECTION,
|
|
MOVE_RESOLUTION,
|
|
PERFORM_TURN,
|
|
WAIT_TURN_ANIMATION
|
|
};
|
|
}
|
|
|
|
#define WIDTH 256
|
|
#define HEIGHT 224
|
|
#define ALPHA_SCREEN1 128
|
|
#define ALPHA_SCREEN2 20
|
|
#define FADE_SPD 6
|
|
#define MOVE_SPD 0.1
|
|
#define MESSAGE_SCROLL_WAIT_SPD 2 //Number of frames to wait.
|
|
#define BATTLE_CAMERA_SCROLL_SPD 0.05 //How fast to scroll over to the battle.
|
|
|
|
class Animation{
|
|
public:
|
|
Decal*spr;
|
|
std::vector<vi2d> frames;
|
|
int frame=0;
|
|
bool flipped=false;
|
|
int skip_frames=1; //Essentially the animation speed. Number of frames to wait for next frame.
|
|
int width=32;
|
|
int height=32;
|
|
|
|
vi2d getCurrentFrame() {
|
|
return frames[frame];
|
|
}
|
|
};
|
|
|
|
std::vector<Animation*> updateAnimationsList; //Used to store animations in the game that we need to keep track of and update. Probably don't touch this.
|
|
|
|
class ObjectLoadInfo{
|
|
public:
|
|
Decal*spr;
|
|
bool hasanim=false;
|
|
Animation*anim;
|
|
ObjectLoadInfo(Decal*spr) {
|
|
this->spr=spr;
|
|
}
|
|
ObjectLoadInfo(Decal*spr,Animation*anim) {
|
|
this->spr=spr;
|
|
this->anim=anim;
|
|
this->hasanim=true;
|
|
updateAnimationsList.push_back(anim);
|
|
}
|
|
};
|
|
|
|
class Object{
|
|
public:
|
|
float x,y;
|
|
Decal*spr;
|
|
std::string name;
|
|
bool hasAnim=false;
|
|
Animation*anim;
|
|
};
|
|
|
|
class WEATHER_POWER{
|
|
public:
|
|
std::string description;
|
|
std::string name;
|
|
Animation*anim;
|
|
Animation*effectAnim;
|
|
int damage;
|
|
int damageRoll;
|
|
int range;
|
|
int playerOwnCount;
|
|
WEATHER_POWER(std::string name,std::string desc,Animation*icon,Animation*effect,int dmg,int dmgRoll,int range) {
|
|
this->description=desc;
|
|
this->name=name;
|
|
this->anim=icon;
|
|
this->effectAnim=effect;
|
|
this->damage=dmg;
|
|
this->damageRoll=dmgRoll;
|
|
this->range=range;
|
|
}
|
|
};
|
|
|
|
class Entity{
|
|
public:
|
|
bool ally;
|
|
int hp;
|
|
int maxhp;
|
|
Decal*spr;
|
|
int x;
|
|
int y;
|
|
std::string name;
|
|
WEATHER_POWER*selectedMove;
|
|
Entity(Decal*spr,std::string name,int x,int y,int hp,int maxhp,bool isAlly=false) {
|
|
this->spr=spr;
|
|
this->name=name;
|
|
this->x=x;
|
|
this->y=y;
|
|
this->hp=hp;
|
|
this->maxhp=maxhp;
|
|
}
|
|
};
|
|
|
|
class Encounter{
|
|
public:
|
|
int x,y;
|
|
std::vector<Entity> entities;
|
|
std::vector<int> turnOrder;
|
|
};
|
|
|
|
class SeasonsOfLoneliness : public PixelGameEngine
|
|
{
|
|
public:
|
|
SeasonsOfLoneliness()
|
|
{
|
|
sAppName = "Seasons of Loneliness";
|
|
}
|
|
|
|
#define STARTING_MAP "assets/maps/map2"
|
|
|
|
public:
|
|
GAMESTATE GAME_STATE=GAMEWORLD;
|
|
int textInd=0;
|
|
int cursorX=0;
|
|
int transitionTime=0;
|
|
bool fade=false;
|
|
int transparency=0;
|
|
int frameCount=0;
|
|
float elapsedTime=0;
|
|
const float TARGET_RATE = 1/60.0;
|
|
std::string MAP_NAME = "";
|
|
std::string CUTSCENE_CONSOLE_TEXT = "";
|
|
int**MAP=NULL;
|
|
int MAP_WIDTH=-1;
|
|
int MAP_HEIGHT=-1;
|
|
Decal*TILES;
|
|
float PLAYER_COORDS[2] = {14,4};
|
|
std::vector<Object> OBJECTS;
|
|
bool CUTSCENE_ACTIVE=false;
|
|
cutscene::CUTSCENE CURRENT_CUTSCENE=cutscene::NONE;
|
|
int CUTSCENE_TIMER=0;
|
|
bool CUTSCENE_FLAGS[8];
|
|
bool messageBoxVisible=false;
|
|
int messageBoxCursor;
|
|
std::string messageBoxSpeaker;
|
|
std::string messageBoxText;
|
|
std::string messageBoxRefText;
|
|
bool firstNewline=false;
|
|
bool secondNewline=false;
|
|
bool foodMeterVisible=false;
|
|
int foodCount=3;
|
|
bool oxygenMeterVisible=false;
|
|
int oxygenQualityLevel=34;
|
|
int plantState=0b10010110101000101010100110101010;
|
|
SplashScreen splash;
|
|
Animation current_playerAnim;
|
|
Animation playerAnim;
|
|
Animation playerAnimRight;
|
|
Animation playerAnimLeft;
|
|
Animation playerAnimDown;
|
|
Animation playerAnimWalkUp;
|
|
Animation playerAnimWalkDown;
|
|
Animation playerAnimWalkRight;
|
|
Animation playerAnimWalkLeft;
|
|
Animation playerAnimPlantUp;
|
|
Animation playerAnimPlantDown;
|
|
Animation playerAnimPlantRight;
|
|
Animation playerAnimPlantLeft;
|
|
Animation POWER_HAILSTORM_ANIMATION;
|
|
Animation POWER_HURRICANE_ANIMATION;
|
|
Animation POWER_METEOR_SHOWER_ANIMATION;
|
|
Animation POWER_METEOR_STORM_ANIMATION;
|
|
Animation POWER_SNOWSTORM_ANIMATION;
|
|
std::vector<Entity> entityList;
|
|
WEATHER_POWER*HAILSTORM = new WEATHER_POWER("Hailstorm","Causes a flurry of hard cold rocks to be unleashed in target area. 60+30d",&POWER_HAILSTORM_ANIMATION,&POWER_HAILSTORM_ANIMATION,60,30,160);
|
|
WEATHER_POWER*HURRICANE = new WEATHER_POWER("Hurricane","Causes heavy winds, scattering seeds, heavy rain. 20+10d",&POWER_HURRICANE_ANIMATION,&POWER_HURRICANE_ANIMATION,20,10,200);
|
|
WEATHER_POWER*METEOR_SHOWER = new WEATHER_POWER("Meteor Shower","Causes space rocks to fall on target area. 50+50d",&POWER_METEOR_SHOWER_ANIMATION,&POWER_METEOR_SHOWER_ANIMATION,50,50,96);
|
|
WEATHER_POWER*METEOR_STORM = new WEATHER_POWER("Meteor Storm","Larger space rocks. 120+60d",&POWER_METEOR_STORM_ANIMATION,&POWER_METEOR_STORM_ANIMATION,120,60,140);
|
|
WEATHER_POWER*SNOWSTORM = new WEATHER_POWER("Snowstorm","Slows down targets and causes rapid temperature drops. 15+10d",&POWER_SNOWSTORM_ANIMATION,&POWER_SNOWSTORM_ANIMATION,15,10,140);
|
|
WEATHER_POWER*SANDSTORM = new WEATHER_POWER("Sandstorm","",&POWER_HAILSTORM_ANIMATION,&POWER_HAILSTORM_ANIMATION,5,10,64);
|
|
WEATHER_POWER*PETAL_BLOSSOM = new WEATHER_POWER("Petal Blossom","",&POWER_HAILSTORM_ANIMATION,&POWER_HAILSTORM_ANIMATION,8,20,164);
|
|
WEATHER_POWER*AVALANCHE = new WEATHER_POWER("Avalanche","",&POWER_HAILSTORM_ANIMATION,&POWER_HAILSTORM_ANIMATION,15,10,200);
|
|
bool IN_BATTLE_ENCOUNTER = false;
|
|
int BATTLE_ENTRY_TIMER = 0;
|
|
int EFFECT_TIMER = 0;
|
|
#define WEATHER_POWER_COUNT 5 //Number of powers that are in the game. Update storage array accordingly.
|
|
WEATHER_POWER*WEATHER_POWERS[WEATHER_POWER_COUNT] = {
|
|
HAILSTORM,
|
|
HURRICANE,
|
|
METEOR_SHOWER,
|
|
METEOR_STORM,
|
|
SNOWSTORM,};
|
|
battle::BATTLESTATE BATTLE_STATE=battle::NONE;
|
|
std::vector<WEATHER_POWER*> availablePowers;
|
|
WEATHER_POWER*BATTLE_CARD_SELECTION=HAILSTORM;
|
|
|
|
|
|
Decal*DOME_DECAL,*FOOD_METER_DECAL,*OXYGEN_METER_DECAL,*PLANT_DECAL,
|
|
*PLAYER_DECAL,
|
|
*WEATHERNODE_EFFECT_DECAL,*POWER_HAILSTORM_DECAL,*POWER_HURRICANE_DECAL,*POWER_METEOR_SHOWER_DECAL,*POWER_METEOR_STORM_DECAL,*POWER_SNOWSTORM_DECAL,
|
|
*SPIDEY_DECAL;
|
|
std::map<std::string,ObjectLoadInfo*> BASE_OBJECTS;
|
|
std::vector<Encounter> ENCOUNTERS;
|
|
Encounter ENCOUNTER_SPIDEY_1;
|
|
Encounter CURRENT_ENCOUNTER;
|
|
|
|
bool OnUserCreate() override
|
|
{
|
|
SetPixelMode(Pixel::ALPHA);
|
|
ConsoleCaptureStdOut(true);
|
|
//ConsoleShow(F1,false);
|
|
// Called once at the start, so create things here
|
|
TILES=new Decal(new Sprite("assets/tiles.png"));
|
|
DOME_DECAL=new Decal(new Sprite("assets/dome.png"));
|
|
FOOD_METER_DECAL=new Decal(new Sprite("assets/corn.png"));
|
|
OXYGEN_METER_DECAL=new Decal(new Sprite("assets/co2.png"));
|
|
PLANT_DECAL=new Decal(new Sprite("assets/plant.png"));
|
|
PLAYER_DECAL=new Decal(new Sprite("assets/player.png"));
|
|
WEATHERNODE_EFFECT_DECAL=new Decal(new Sprite("assets/weathernode_effect.png"));
|
|
POWER_HAILSTORM_DECAL=new Decal(new Sprite("assets/hailstorm_icon.png"));
|
|
POWER_HURRICANE_DECAL=new Decal(new Sprite("assets/hurricane_icon.png"));
|
|
POWER_METEOR_SHOWER_DECAL=new Decal(new Sprite("assets/meteor_shower_icon.png"));
|
|
POWER_METEOR_STORM_DECAL=new Decal(new Sprite("assets/meteor_storm.png"));
|
|
POWER_SNOWSTORM_DECAL=new Decal(new Sprite("assets/snowstorm_icon.png"));
|
|
SPIDEY_DECAL=new Decal(new Sprite("assets/spidey.png"));
|
|
|
|
current_playerAnim.spr=PLAYER_DECAL;
|
|
playerAnim.spr=PLAYER_DECAL;
|
|
playerAnimRight.spr=PLAYER_DECAL;
|
|
playerAnimLeft.spr=PLAYER_DECAL;
|
|
playerAnimLeft.flipped=true;
|
|
playerAnimDown.spr=PLAYER_DECAL;
|
|
playerAnimWalkUp.spr=PLAYER_DECAL;
|
|
playerAnimWalkDown.spr=PLAYER_DECAL;
|
|
playerAnimWalkRight.spr=PLAYER_DECAL;
|
|
playerAnimWalkLeft.spr=PLAYER_DECAL;
|
|
playerAnimWalkLeft.flipped=true;
|
|
playerAnimPlantUp.spr=PLAYER_DECAL;
|
|
playerAnimPlantDown.spr=PLAYER_DECAL;
|
|
playerAnimPlantRight.spr=PLAYER_DECAL;
|
|
playerAnimPlantLeft.spr=PLAYER_DECAL;
|
|
playerAnimPlantLeft.flipped=true;
|
|
playerAnim.frames.push_back({64,0});
|
|
playerAnimRight.frames.push_back({32,0});
|
|
playerAnimLeft.frames.push_back({32,0});
|
|
playerAnimDown.frames.push_back({0,0});
|
|
playerAnimWalkUp.frames.push_back({0,96});
|
|
playerAnimWalkUp.frames.push_back({32,96});
|
|
playerAnimWalkUp.frames.push_back({64,96});
|
|
playerAnimWalkRight.frames.push_back({0,64});
|
|
playerAnimWalkLeft.frames.push_back({0,64});
|
|
playerAnimWalkRight.frames.push_back({32,64});
|
|
playerAnimWalkLeft.frames.push_back({32,64});
|
|
playerAnimWalkRight.frames.push_back({64,64});
|
|
playerAnimWalkLeft.frames.push_back({64,64});
|
|
playerAnimWalkDown.frames.push_back({0,32});
|
|
playerAnimWalkDown.frames.push_back({32,32});
|
|
playerAnimWalkDown.frames.push_back({64,32});
|
|
playerAnimPlantUp.frames.push_back({64,128});
|
|
playerAnimPlantRight.frames.push_back({32,128});
|
|
playerAnimPlantLeft.frames.push_back({32,128});
|
|
playerAnimPlantDown.frames.push_back({0,128});
|
|
current_playerAnim=playerAnimWalkDown;
|
|
|
|
const int nodeAnimationSkipFrames=12;
|
|
|
|
POWER_HAILSTORM_ANIMATION.spr=POWER_HAILSTORM_DECAL;
|
|
POWER_HAILSTORM_ANIMATION.frames.push_back({0,0});
|
|
POWER_HAILSTORM_ANIMATION.frames.push_back({32,0});
|
|
POWER_HAILSTORM_ANIMATION.frames.push_back({64,0});
|
|
POWER_HAILSTORM_ANIMATION.skip_frames=nodeAnimationSkipFrames;
|
|
POWER_HURRICANE_ANIMATION.spr=POWER_HURRICANE_DECAL;
|
|
POWER_HURRICANE_ANIMATION.frames.push_back({0,0});
|
|
POWER_HURRICANE_ANIMATION.frames.push_back({32,0});
|
|
POWER_HURRICANE_ANIMATION.frames.push_back({64,0});
|
|
POWER_HURRICANE_ANIMATION.skip_frames=nodeAnimationSkipFrames;
|
|
POWER_METEOR_SHOWER_ANIMATION.spr=POWER_METEOR_SHOWER_DECAL;
|
|
POWER_METEOR_SHOWER_ANIMATION.frames.push_back({0,0});
|
|
POWER_METEOR_SHOWER_ANIMATION.frames.push_back({32,0});
|
|
POWER_METEOR_SHOWER_ANIMATION.frames.push_back({64,0});
|
|
POWER_METEOR_SHOWER_ANIMATION.skip_frames=nodeAnimationSkipFrames;
|
|
POWER_METEOR_STORM_ANIMATION.spr=POWER_METEOR_STORM_DECAL;
|
|
POWER_METEOR_STORM_ANIMATION.frames.push_back({0,0});
|
|
POWER_METEOR_STORM_ANIMATION.frames.push_back({32,0});
|
|
POWER_METEOR_STORM_ANIMATION.frames.push_back({64,0});
|
|
POWER_METEOR_STORM_ANIMATION.skip_frames=nodeAnimationSkipFrames;
|
|
POWER_SNOWSTORM_ANIMATION.spr=POWER_SNOWSTORM_DECAL;
|
|
POWER_SNOWSTORM_ANIMATION.frames.push_back({0,0});
|
|
POWER_SNOWSTORM_ANIMATION.frames.push_back({32,0});
|
|
POWER_SNOWSTORM_ANIMATION.frames.push_back({64,0});
|
|
POWER_SNOWSTORM_ANIMATION.skip_frames=nodeAnimationSkipFrames;
|
|
|
|
HAILSTORM->playerOwnCount=3;
|
|
HURRICANE->playerOwnCount=1;
|
|
METEOR_SHOWER->playerOwnCount=5;
|
|
|
|
ENCOUNTER_SPIDEY_1.entities.push_back(*new Entity(SPIDEY_DECAL,"Spidey",2,3,80,80,false));
|
|
ENCOUNTER_SPIDEY_1.entities.push_back(*new Entity(SPIDEY_DECAL,"Spidey",4,4,80,80,false));
|
|
ENCOUNTER_SPIDEY_1.entities.push_back(*new Entity(SPIDEY_DECAL,"Spidey",6,2,80,80,false));
|
|
ENCOUNTER_SPIDEY_1.x=79;
|
|
ENCOUNTER_SPIDEY_1.y=47;
|
|
ENCOUNTERS.push_back(ENCOUNTER_SPIDEY_1);
|
|
|
|
BASE_OBJECTS["DOME"]=new ObjectLoadInfo(DOME_DECAL);
|
|
BASE_OBJECTS["PLANT"]=new ObjectLoadInfo(PLANT_DECAL);
|
|
BASE_OBJECTS["EXIT"]=new ObjectLoadInfo(NULL);
|
|
BASE_OBJECTS["HAILSTORM_NODE"]=new ObjectLoadInfo(POWER_HAILSTORM_DECAL,&POWER_HAILSTORM_ANIMATION);
|
|
BASE_OBJECTS["HURRICANE_NODE"]=new ObjectLoadInfo(POWER_HURRICANE_DECAL,&POWER_HURRICANE_ANIMATION);
|
|
BASE_OBJECTS["METEORSHOWER_NODE"]=new ObjectLoadInfo(POWER_METEOR_SHOWER_DECAL,&POWER_METEOR_SHOWER_ANIMATION);
|
|
BASE_OBJECTS["METEORSTORM_NODE"]=new ObjectLoadInfo(POWER_METEOR_STORM_DECAL,&POWER_METEOR_STORM_ANIMATION);
|
|
BASE_OBJECTS["SNOWSTORM_NODE"]=new ObjectLoadInfo(POWER_SNOWSTORM_DECAL,&POWER_SNOWSTORM_ANIMATION);
|
|
LoadMap(STARTING_MAP);
|
|
return true;
|
|
}
|
|
|
|
void GetAnyKeyPress() override {
|
|
if (!GetKey(W).bPressed&&!GetKey(A).bPressed&&!GetKey(S).bPressed&&!GetKey(D).bPressed&&
|
|
!GetKey(UP).bPressed&&!GetKey(RIGHT).bPressed&&!GetKey(DOWN).bPressed&&!GetKey(LEFT).bPressed) {
|
|
ActionButtonPress();
|
|
}
|
|
if (messageBoxVisible) {
|
|
if (messageBoxCursor!=messageBoxRefText.length()) {
|
|
while (messageBoxCursor<messageBoxRefText.length()) {
|
|
advanceMessageBox();
|
|
}
|
|
} else {
|
|
messageBoxVisible=false;
|
|
}
|
|
}
|
|
switch (GAME_STATE) {
|
|
case CUTSCENE_1:{
|
|
if (textInd>=STORY_TEXT1.length()) {
|
|
fadeOut();
|
|
}
|
|
}break;
|
|
}
|
|
}
|
|
|
|
void ActionButtonPress() {
|
|
switch (GAME_STATE) {
|
|
case GAMEWORLD:{
|
|
if (PLAYER_COORDS[0]>=8&&PLAYER_COORDS[0]<12&&
|
|
PLAYER_COORDS[1]>=2&&PLAYER_COORDS[1]<6) {
|
|
//cout<<"You are standing over plant "<<getPlantId((int)PLAYER_COORDS[0],(int)PLAYER_COORDS[1])<<" in state "<<getPlantStatus((int)PLAYER_COORDS[0],(int)PLAYER_COORDS[1]);
|
|
if (getPlantStatus((int)PLAYER_COORDS[0],(int)PLAYER_COORDS[1])==2) {
|
|
setPlantStatus((int)PLAYER_COORDS[0],(int)PLAYER_COORDS[1],0);
|
|
}
|
|
}
|
|
}break;
|
|
}
|
|
}
|
|
|
|
bool OnUserUpdate(float fElapsedTime) override
|
|
{
|
|
elapsedTime+=fElapsedTime;
|
|
while (elapsedTime>TARGET_RATE) {
|
|
elapsedTime-=TARGET_RATE;
|
|
updateGame();
|
|
}
|
|
if (GetKey(F1).bPressed) {
|
|
ConsoleShow(F1,false);
|
|
}
|
|
if (GetKey(D).bPressed||GetKey(RIGHT).bPressed||GetKey(NP6).bPressed) {
|
|
changeAnimation(playerAnimWalkRight);
|
|
}
|
|
if (GetKey(A).bPressed||GetKey(LEFT).bPressed||GetKey(NP4).bPressed) {
|
|
changeAnimation(playerAnimWalkLeft);
|
|
}
|
|
if (GetKey(W).bPressed||GetKey(UP).bPressed||GetKey(NP8).bPressed) {
|
|
changeAnimation(playerAnimWalkUp);
|
|
}
|
|
if (GetKey(S).bPressed||GetKey(DOWN).bPressed||GetKey(NP5).bPressed||GetKey(NP2).bPressed) {
|
|
changeAnimation(playerAnimWalkDown);
|
|
}
|
|
if (!GetKey(D).bHeld&&!GetKey(RIGHT).bHeld&&!GetKey(NP6).bHeld&&
|
|
!GetKey(A).bHeld&&!GetKey(LEFT).bHeld&&!GetKey(NP4).bHeld&&
|
|
!GetKey(S).bHeld&&!GetKey(UP).bHeld&&!GetKey(NP8).bHeld&&
|
|
!GetKey(W).bHeld&&!GetKey(DOWN).bHeld&&!GetKey(NP5).bHeld&&!GetKey(NP2).bHeld) {
|
|
if (GetKey(D).bReleased||GetKey(RIGHT).bReleased||GetKey(NP6).bReleased) {
|
|
changeAnimation(playerAnimRight);
|
|
}
|
|
if (GetKey(A).bReleased||GetKey(LEFT).bReleased||GetKey(NP4).bReleased) {
|
|
changeAnimation(playerAnimLeft);
|
|
}
|
|
if (GetKey(W).bReleased||GetKey(UP).bReleased||GetKey(NP8).bReleased) {
|
|
changeAnimation(playerAnim);
|
|
}
|
|
if (GetKey(S).bReleased||GetKey(DOWN).bReleased||GetKey(NP5).bReleased||GetKey(NP2).bReleased) {
|
|
changeAnimation(playerAnimDown);
|
|
}
|
|
}
|
|
|
|
drawGame();
|
|
// called once per frame
|
|
return true;
|
|
}
|
|
|
|
void fadeOutCompleted() {
|
|
switch (GAME_STATE) {
|
|
case CUTSCENE_1:{
|
|
GAME_STATE=CUTSCENE_2;
|
|
PlayCutscene(cutscene::PAN_DOME);
|
|
fadeIn();
|
|
}break;
|
|
case CUTSCENE_2:{
|
|
fadeIn();
|
|
PlayCutscene(cutscene::CUTSCENE_4);
|
|
GAME_STATE=GAMEWORLD;
|
|
}break;
|
|
}
|
|
switch (CURRENT_CUTSCENE) {
|
|
case cutscene::TRANSITION_CUTSCENE:{
|
|
LoadMap("assets/maps/map1");
|
|
PLAYER_COORDS[0]=40;
|
|
PLAYER_COORDS[1]=37;
|
|
fadeIn();
|
|
EndCutscene();
|
|
}break;
|
|
}
|
|
}
|
|
|
|
void fadeInCompleted() {
|
|
|
|
}
|
|
|
|
void PlayCutscene(cutscene::CUTSCENE scene) {
|
|
CURRENT_CUTSCENE=scene;
|
|
switch (scene) {
|
|
case cutscene::PAN_DOME:{
|
|
PLAYER_COORDS[0]=14;
|
|
PLAYER_COORDS[1]=35+(64/2/32);
|
|
}break;
|
|
case cutscene::PAUSE_TO_CUTSCENE_3:{
|
|
CUTSCENE_CONSOLE_TEXT.clear();
|
|
textInd=0;
|
|
}break;
|
|
case cutscene::CUTSCENE_4:{
|
|
LoadMap("assets/maps/map2");
|
|
PLAYER_COORDS[0]=16;
|
|
PLAYER_COORDS[1]=6;
|
|
}break;
|
|
}
|
|
for (int i=0;i<8;i++) {
|
|
CUTSCENE_FLAGS[i]=false;
|
|
}
|
|
CUTSCENE_TIMER=0;
|
|
}
|
|
|
|
void updateGame(){
|
|
frameCount++;
|
|
if (CURRENT_CUTSCENE!=NONE) {
|
|
CUTSCENE_TIMER++;
|
|
}
|
|
if (fade&&transparency<255) {
|
|
transparency=std::clamp(transparency+FADE_SPD,0,255);
|
|
if (transparency==255) {
|
|
fadeOutCompleted();
|
|
}
|
|
} else
|
|
if (!fade&&transparency>0) {
|
|
transparency=std::clamp(transparency-FADE_SPD,0,255);
|
|
if (transparency==0) {
|
|
fadeInCompleted();
|
|
}
|
|
}
|
|
if (messageBoxVisible) {
|
|
if (frameCount%MESSAGE_SCROLL_WAIT_SPD==0) {
|
|
if (messageBoxCursor<messageBoxRefText.length()) {
|
|
advanceMessageBox();
|
|
}
|
|
}
|
|
}
|
|
if(frameCount%current_playerAnim.skip_frames==0) {
|
|
current_playerAnim.frame=(current_playerAnim.frame+1)%current_playerAnim.frames.size();
|
|
}
|
|
for (auto anim:updateAnimationsList) {
|
|
if (frameCount%anim->skip_frames==0) {
|
|
anim->frame=(anim->frame+1)%anim->frames.size();
|
|
}
|
|
}
|
|
|
|
if (CURRENT_CUTSCENE==NONE&&!messageBoxVisible&&!IN_BATTLE_ENCOUNTER) {
|
|
bool changed=false;
|
|
if (GetKey(D).bHeld||GetKey(RIGHT).bHeld||GetKey(NP6).bHeld) {
|
|
PLAYER_COORDS[0]=std::clamp(PLAYER_COORDS[0]+MOVE_SPD,0.1,(double)MAP_WIDTH);
|
|
//ConsoleClear();
|
|
//cout<<"("<<PLAYER_COORDS[0]<<","<<PLAYER_COORDS[1]<<+")";
|
|
if (!changed&&¤t_playerAnim!=&playerAnimWalkRight) {
|
|
changeAnimation(playerAnimWalkRight);
|
|
changed=true;
|
|
}
|
|
}
|
|
if (GetKey(A).bHeld||GetKey(LEFT).bHeld||GetKey(NP4).bHeld) {
|
|
PLAYER_COORDS[0]=std::clamp(PLAYER_COORDS[0]-MOVE_SPD,0.1,(double)MAP_WIDTH);
|
|
//ConsoleClear();
|
|
//cout<<"("<<PLAYER_COORDS[0]<<","<<PLAYER_COORDS[1]<<+")";
|
|
if (!changed&&¤t_playerAnim!=&playerAnimWalkLeft) {
|
|
changeAnimation(playerAnimWalkLeft);
|
|
changed=true;
|
|
}
|
|
}
|
|
if (GetKey(W).bHeld||GetKey(UP).bHeld||GetKey(NP8).bHeld) {
|
|
PLAYER_COORDS[1]=std::clamp(PLAYER_COORDS[1]-MOVE_SPD,0.1,(double)MAP_HEIGHT);
|
|
//ConsoleClear();
|
|
//cout<<"("<<PLAYER_COORDS[0]<<","<<PLAYER_COORDS[1]<<+")";
|
|
if (!changed&&¤t_playerAnim!=&playerAnimWalkUp) {
|
|
changeAnimation(playerAnimWalkUp);
|
|
changed=true;
|
|
}
|
|
}
|
|
if (GetKey(S).bHeld||GetKey(DOWN).bHeld||GetKey(NP5).bHeld||GetKey(NP2).bHeld) {
|
|
PLAYER_COORDS[1]=std::clamp(PLAYER_COORDS[1]+MOVE_SPD,0.1,(double)MAP_HEIGHT);
|
|
//ConsoleClear();
|
|
//cout<<"("<<PLAYER_COORDS[0]<<","<<PLAYER_COORDS[1]<<+")";
|
|
if (!changed&&¤t_playerAnim!=&playerAnimWalkDown) {
|
|
changeAnimation(playerAnimWalkDown);
|
|
changed=true;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (int i=0;i<OBJECTS.size();i++) {
|
|
Object obj = OBJECTS[i];
|
|
if (obj.name.compare("HAILSTORM_NODE")==0&&collidesWithPlayer(obj)) {
|
|
int amountGained=rand()%4+2;
|
|
HAILSTORM->playerOwnCount+=amountGained;
|
|
std::cout<<"Increased HAILSTORM power inventory count by "<<amountGained<<".\n";
|
|
OBJECTS.erase(OBJECTS.begin()+i--);
|
|
} else
|
|
if (obj.name.compare("HURRICANE_NODE")==0&&collidesWithPlayer(obj)) {
|
|
int amountGained=rand()%4+2;
|
|
HURRICANE->playerOwnCount+=amountGained;
|
|
std::cout<<"Increased HURRICANE power inventory count by "<<amountGained<<".\n";
|
|
OBJECTS.erase(OBJECTS.begin()+i--);
|
|
} else
|
|
if (obj.name.compare("METEORSHOWER_NODE")==0&&collidesWithPlayer(obj)) {
|
|
int amountGained=rand()%4+2;
|
|
METEOR_SHOWER->playerOwnCount+=amountGained;
|
|
std::cout<<"Increased METEORSHOWER power inventory count by "<<amountGained<<".\n";
|
|
OBJECTS.erase(OBJECTS.begin()+i--);
|
|
} else
|
|
if (obj.name.compare("METEORSTORM_NODE")==0&&collidesWithPlayer(obj)) {
|
|
int amountGained=rand()%4+2;
|
|
METEOR_STORM->playerOwnCount+=amountGained;
|
|
std::cout<<"Increased METEORSTORM power inventory count by "<<amountGained<<".\n";
|
|
OBJECTS.erase(OBJECTS.begin()+i--);
|
|
} else
|
|
if (obj.name.compare("SNOWSTORM_NODE")==0&&collidesWithPlayer(obj)) {
|
|
int amountGained=rand()%4+2;
|
|
SNOWSTORM->playerOwnCount+=amountGained;
|
|
std::cout<<"Increased SNOWSTORM power inventory count by "<<amountGained<<".\n";
|
|
OBJECTS.erase(OBJECTS.begin()+i--);
|
|
}
|
|
if (obj.name.compare("EXIT")==0&&collidesWithPlayer(obj)) {
|
|
fadeOut();
|
|
PlayCutscene(cutscene::TRANSITION_CUTSCENE);
|
|
}
|
|
}
|
|
|
|
if (!IN_BATTLE_ENCOUNTER&&MAP_NAME.compare("assets/maps/map1")==0) {
|
|
for (int i=0;i<ENCOUNTERS.size();i++) {
|
|
Encounter enc = ENCOUNTERS[i];
|
|
if (collidesWithPlayer(enc)) {
|
|
availablePowers.erase(availablePowers.begin(),availablePowers.end());
|
|
IN_BATTLE_ENCOUNTER=true;
|
|
CURRENT_ENCOUNTER=enc;
|
|
BATTLE_ENTRY_TIMER=0;
|
|
BATTLE_STATE=battle::WAITING_FOR_CAMERA;
|
|
for (int i=0;i<WEATHER_POWER_COUNT;i++) {
|
|
if (WEATHER_POWERS[i]->playerOwnCount>0) {
|
|
availablePowers.push_back(WEATHER_POWERS[i]);
|
|
//cout<<"There are x"<<WEATHER_POWERS[i]->playerOwnCount<<" of "<<WEATHER_POWERS[i]->name<<"\n";
|
|
}
|
|
}
|
|
BATTLE_CARD_SELECTION=availablePowers[0];
|
|
}
|
|
}
|
|
}
|
|
|
|
if (IN_BATTLE_ENCOUNTER) {
|
|
BATTLE_ENTRY_TIMER++;
|
|
switch (BATTLE_STATE) {
|
|
case battle::WAITING_FOR_CAMERA: {
|
|
if (BATTLE_ENTRY_TIMER>45) {
|
|
int TARGET_COORDS_X=CURRENT_ENCOUNTER.x+WIDTH/32/2;
|
|
int TARGET_COORDS_Y=CURRENT_ENCOUNTER.y+HEIGHT/32/2;
|
|
if (PLAYER_COORDS[0]==TARGET_COORDS_X&&PLAYER_COORDS[1]==TARGET_COORDS_Y) {
|
|
BATTLE_STATE = battle::PLAYER_SELECTION;
|
|
EFFECT_TIMER = 0;
|
|
} else
|
|
if (PLAYER_COORDS[0]!=TARGET_COORDS_X) {
|
|
if (PLAYER_COORDS[0]<TARGET_COORDS_X) {
|
|
PLAYER_COORDS[0]+=BATTLE_CAMERA_SCROLL_SPD;
|
|
if (PLAYER_COORDS[0]>TARGET_COORDS_X) {
|
|
PLAYER_COORDS[0]=TARGET_COORDS_X;
|
|
}
|
|
} else {
|
|
PLAYER_COORDS[0]-=BATTLE_CAMERA_SCROLL_SPD;
|
|
if (PLAYER_COORDS[0]<TARGET_COORDS_X) {
|
|
PLAYER_COORDS[0]=TARGET_COORDS_X;
|
|
}
|
|
}
|
|
}
|
|
if (PLAYER_COORDS[1]!=TARGET_COORDS_Y) {
|
|
if (PLAYER_COORDS[1]<TARGET_COORDS_Y) {
|
|
PLAYER_COORDS[1]+=BATTLE_CAMERA_SCROLL_SPD;
|
|
if (PLAYER_COORDS[1]>TARGET_COORDS_Y) {
|
|
PLAYER_COORDS[1]=TARGET_COORDS_Y;
|
|
}
|
|
} else {
|
|
PLAYER_COORDS[1]-=BATTLE_CAMERA_SCROLL_SPD;
|
|
if (PLAYER_COORDS[1]<TARGET_COORDS_Y) {
|
|
PLAYER_COORDS[1]=TARGET_COORDS_Y;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}break;
|
|
}
|
|
}
|
|
|
|
switch (CURRENT_CUTSCENE) {
|
|
case cutscene::CUTSCENE_4:{
|
|
if (!messageBoxVisible) {
|
|
if (!CUTSCENE_FLAGS[0]) {
|
|
CUTSCENE_FLAGS[0]=true;
|
|
DisplayMessageBox(0);
|
|
} else
|
|
if (!CUTSCENE_FLAGS[1]) {
|
|
CUTSCENE_FLAGS[1]=true;
|
|
DisplayMessageBox(1);
|
|
} else
|
|
if (!CUTSCENE_FLAGS[2]) {
|
|
CUTSCENE_FLAGS[2]=true;
|
|
DisplayMessageBox(2);
|
|
foodMeterVisible=true;
|
|
} else
|
|
if (!CUTSCENE_FLAGS[3]) {
|
|
CUTSCENE_FLAGS[3]=true;
|
|
DisplayMessageBox(3);
|
|
oxygenMeterVisible=true;
|
|
}
|
|
}
|
|
}break;
|
|
}
|
|
|
|
switch (GAME_STATE) {
|
|
case CUTSCENE_1:
|
|
case CUTSCENE_3:{
|
|
std::string refText;
|
|
switch (GAME_STATE) {
|
|
case CUTSCENE_1:{
|
|
refText=STORY_TEXT1;
|
|
}break;
|
|
case CUTSCENE_3:{
|
|
refText=STORY_TEXT2;
|
|
}break;
|
|
}
|
|
if (GAME_STATE==CUTSCENE_3&&frameCount%4!=0) {break;}
|
|
if (textInd<refText.length()) {
|
|
char c = refText[textInd++];
|
|
CUTSCENE_CONSOLE_TEXT+=c;
|
|
if (c!='\n') {
|
|
cursorX++;
|
|
} else {
|
|
cursorX=0;
|
|
}
|
|
if (GetTextSize(CUTSCENE_CONSOLE_TEXT).x>WIDTH-32) {
|
|
int tempIndex=textInd;
|
|
while (CUTSCENE_CONSOLE_TEXT[--tempIndex]!=' ') {
|
|
CUTSCENE_CONSOLE_TEXT.erase(tempIndex);
|
|
cursorX--;
|
|
}
|
|
CUTSCENE_CONSOLE_TEXT.erase(tempIndex++);
|
|
CUTSCENE_CONSOLE_TEXT+='\n';
|
|
cursorX=0;
|
|
while (tempIndex<textInd) {
|
|
CUTSCENE_CONSOLE_TEXT+=refText[tempIndex++];
|
|
cursorX++;
|
|
}
|
|
}
|
|
}
|
|
}break;
|
|
case CUTSCENE_2:{
|
|
//FLAG 0 - When flipped on, camera stops.
|
|
if (!CUTSCENE_FLAGS[0]) {
|
|
PLAYER_COORDS[0]+=0.06;
|
|
} else {
|
|
if (CUTSCENE_TIMER>120) {
|
|
fadeOut();
|
|
}
|
|
}
|
|
if (PLAYER_COORDS[0]>38+(128/2/32)) {
|
|
PLAYER_COORDS[0]=38+(128/2/32);
|
|
CUTSCENE_FLAGS[0]=true;
|
|
CUTSCENE_TIMER=0;
|
|
}
|
|
}break;
|
|
case WAITING_FOR_CUTSCENE_3:{
|
|
if (transparency>200) {
|
|
GAME_STATE=CUTSCENE_3;
|
|
}
|
|
}break;
|
|
}
|
|
}
|
|
|
|
void advanceMessageBox() {
|
|
char c = messageBoxRefText[messageBoxCursor++];
|
|
printf("%c",c);
|
|
if (c=='\n') {
|
|
if (!firstNewline) {
|
|
firstNewline=true;
|
|
return;
|
|
} else if (!secondNewline) {
|
|
secondNewline=true;
|
|
return;
|
|
}
|
|
}
|
|
if (firstNewline&&!secondNewline) {
|
|
messageBoxSpeaker+=c;
|
|
return;
|
|
}
|
|
messageBoxText+=c;
|
|
if (GetTextSizeProp(messageBoxText).x>WIDTH-16) {
|
|
int tempIndex=messageBoxCursor;
|
|
while (messageBoxText[--tempIndex]!=' ') {
|
|
messageBoxText.erase(tempIndex);
|
|
}
|
|
messageBoxText.erase(tempIndex++);
|
|
messageBoxText+='\n';
|
|
while (tempIndex<messageBoxCursor) {
|
|
messageBoxText+=messageBoxRefText[tempIndex++];
|
|
}
|
|
}
|
|
}
|
|
|
|
void drawGame(){
|
|
switch (GAME_STATE) {
|
|
case CUTSCENE_1:{
|
|
DrawStringDecal({16,16},CUTSCENE_CONSOLE_TEXT,GREEN,{1,1});
|
|
if (textInd<STORY_TEXT1.length()) {
|
|
FillRectDecal({(float)(16+(cursorX)*8%(WIDTH-32)),(float)(8+GetTextSize(CUTSCENE_CONSOLE_TEXT).y+((cursorX==28)?8:0))},{4,8},GREEN);
|
|
} else {
|
|
FillRectDecal({(float)(16+(cursorX)*8%(WIDTH-32)),(float)(8+GetTextSize(CUTSCENE_CONSOLE_TEXT).y+((cursorX==28)?8:0))},{4,8},Pixel(0,255,0,(0.5*sin(frameCount*4/60.0)+0.5)*256));
|
|
}
|
|
GradientFillRectDecal({0,0},{WIDTH/2,HEIGHT/2},{20, 28, 22,ALPHA_SCREEN1},{20, 28, 22,ALPHA_SCREEN1},{20, 28, 22,ALPHA_SCREEN2},{20, 28, 22,ALPHA_SCREEN1});
|
|
GradientFillRectDecal({WIDTH/2,0},{WIDTH/2,HEIGHT/2},{20, 28, 22,ALPHA_SCREEN1},{20, 28, 22,ALPHA_SCREEN2},{20, 28, 22,ALPHA_SCREEN1},{20, 28, 22,ALPHA_SCREEN1});
|
|
GradientFillRectDecal({0,HEIGHT/2},{WIDTH/2,HEIGHT/2},{20, 28, 22,ALPHA_SCREEN1},{20, 28, 22,ALPHA_SCREEN1},{20, 28, 22,ALPHA_SCREEN1},{20, 28, 22,ALPHA_SCREEN2});
|
|
GradientFillRectDecal({WIDTH/2,HEIGHT/2},{WIDTH/2,HEIGHT/2},{20, 28, 22,ALPHA_SCREEN2},{20, 28, 22,ALPHA_SCREEN1},{20, 28, 22,ALPHA_SCREEN1},{20, 28, 22,ALPHA_SCREEN1});
|
|
}break;
|
|
case CUTSCENE_2:
|
|
case GAMEWORLD:{
|
|
DrawGameWorld();
|
|
int meterYOffset=2;
|
|
if (CURRENT_CUTSCENE==NONE) {
|
|
if (foodMeterVisible) {
|
|
DrawStringDecal({WIDTH-36*0.4-GetTextSize(std::to_string(foodCount)).x*1-8,meterYOffset+2},std::to_string(foodCount),BLUE,{1,1});
|
|
DrawStringDecal({WIDTH-36*0.4-GetTextSize(std::to_string(foodCount)).x*1-7,meterYOffset+2},std::to_string(foodCount),BLACK,{1,1});
|
|
DrawDecal({WIDTH-52*0.4,meterYOffset},FOOD_METER_DECAL,{0.4,0.4});
|
|
meterYOffset+=(2+48*0.4);
|
|
}
|
|
if (oxygenMeterVisible) {
|
|
DrawStringDecal({WIDTH-36*0.4-GetTextSize(std::to_string(oxygenQualityLevel)+"%").x*1-8,meterYOffset+2},std::to_string(oxygenQualityLevel)+"%",BLUE,{1,1});
|
|
DrawStringDecal({WIDTH-36*0.4-GetTextSize(std::to_string(oxygenQualityLevel)+"%").x*1-7,meterYOffset+2},std::to_string(oxygenQualityLevel)+"%",BLACK,{1,1});
|
|
DrawDecal({WIDTH-52*0.4,meterYOffset},OXYGEN_METER_DECAL,{0.4,0.4});
|
|
meterYOffset+=(2+48*0.4);
|
|
}
|
|
DrawPartialDecal({WIDTH/2-16+(current_playerAnim.flipped?32:0),HEIGHT/2-16},current_playerAnim.spr,current_playerAnim.getCurrentFrame(),{32,32},{current_playerAnim.flipped?-1:1,1});
|
|
if (IN_BATTLE_ENCOUNTER&&BATTLE_ENTRY_TIMER<45) {
|
|
DrawStringDecal({WIDTH/2-16+(current_playerAnim.flipped?32:0)+8,HEIGHT/2-16-sin(frameCount*12/60.0)*4-12},"!!",RED);
|
|
}
|
|
}
|
|
}break;
|
|
case CUTSCENE_3:{
|
|
DrawStringDecal({48,16},CUTSCENE_CONSOLE_TEXT,Pixel(100, 10, 255),{2,2});
|
|
if (textInd<STORY_TEXT2.length()) {
|
|
FillRectDecal({(float)(48+(cursorX)*16%(WIDTH-32)),(float)(GetTextSize(CUTSCENE_CONSOLE_TEXT).y*2+((cursorX==28)?16:0))},{4*2,8*2},Pixel(100, 10, 255));
|
|
} else {
|
|
FillRectDecal({(float)(48+(cursorX)*16%(WIDTH-32)),(float)(GetTextSize(CUTSCENE_CONSOLE_TEXT).y*2+((cursorX==28)?16:0))},{4*2,8*2},Pixel(100, 10, 255,(0.5*sin(frameCount*4/60.0)+0.5)*256));
|
|
}
|
|
GradientFillRectDecal({0,0},{WIDTH/2,HEIGHT/2},{100, 10, 255,ALPHA_SCREEN1},{100, 10, 255,ALPHA_SCREEN1},{100, 10, 255,ALPHA_SCREEN2},{100, 10, 255,ALPHA_SCREEN1});
|
|
GradientFillRectDecal({WIDTH/2,0},{WIDTH/2,HEIGHT/2},{100, 10, 255,ALPHA_SCREEN1},{100, 10, 255,ALPHA_SCREEN2},{100, 10, 255,ALPHA_SCREEN1},{100, 10, 255,ALPHA_SCREEN1});
|
|
GradientFillRectDecal({0,HEIGHT/2},{WIDTH/2,HEIGHT/2},{100, 10, 255,ALPHA_SCREEN1},{100, 10, 255,ALPHA_SCREEN1},{100, 10, 255,ALPHA_SCREEN1},{100, 10, 255,ALPHA_SCREEN2});
|
|
GradientFillRectDecal({WIDTH/2,HEIGHT/2},{WIDTH/2,HEIGHT/2},{100, 10, 255,ALPHA_SCREEN2},{100, 10, 255,ALPHA_SCREEN1},{100, 10, 255,ALPHA_SCREEN1},{100, 10, 255,ALPHA_SCREEN1});
|
|
}break;
|
|
}
|
|
switch (BATTLE_STATE) {
|
|
case battle::PLAYER_SELECTION:{
|
|
GradientFillRectDecal({WIDTH/6,HEIGHT/6},{WIDTH/3,HEIGHT/6*2},Pixel(72, 160, 212,255),Pixel(72, 160, 212,255),Pixel(72, 160, 212,0),Pixel(72, 160, 212,255));
|
|
GradientFillRectDecal({WIDTH/6*3+1,HEIGHT/6},{WIDTH/3,HEIGHT/6*2},Pixel(72, 160, 212,255),Pixel(72, 160, 212,0),Pixel(72, 160, 212,255),Pixel(72, 160, 212,255));
|
|
GradientFillRectDecal({WIDTH/6,HEIGHT/6*3},{WIDTH/3,HEIGHT/6*2},Pixel(72, 160, 212,255),Pixel(72, 160, 212,255),Pixel(72, 160, 212,255),Pixel(72, 160, 212,0));
|
|
GradientFillRectDecal({WIDTH/6*3+1,HEIGHT/6*3},{WIDTH/3,HEIGHT/6*2},Pixel(72, 160, 212,0),Pixel(72, 160, 212,255),Pixel(72, 160, 212,255),Pixel(72, 160, 212,255));
|
|
DrawPartialDecal({WIDTH/2-BATTLE_CARD_SELECTION->anim->width/2*3,HEIGHT/6+16-BATTLE_CARD_SELECTION->anim->height/2},BATTLE_CARD_SELECTION->anim->spr,BATTLE_CARD_SELECTION->anim->getCurrentFrame(),{BATTLE_CARD_SELECTION->anim->width,BATTLE_CARD_SELECTION->anim->height},{3,3});
|
|
for (int x=-1;x<=1;x++) {
|
|
for (int y=-1;y<=1;y++) {
|
|
if (x!=0&&y!=0) {
|
|
DrawStringPropDecal({WIDTH/6+4+x,HEIGHT/2+8+y},BATTLE_CARD_SELECTION->name,BLACK,{2,2});
|
|
}
|
|
}
|
|
}
|
|
DrawStringPropDecal({WIDTH/6+4,HEIGHT/2+8},BATTLE_CARD_SELECTION->name,Pixel(93, 161, 163,255),{2,2});
|
|
DrawWrappedPropText({WIDTH/6+4+1,HEIGHT/2+24+1},BATTLE_CARD_SELECTION->description,WIDTH/3*2-8,BLACK,{1,1});
|
|
DrawWrappedPropText({WIDTH/6+4,HEIGHT/2+24},BATTLE_CARD_SELECTION->description,WIDTH/3*2-8,Pixel(227, 245, 255,255),{1,1});
|
|
for (int x=-1;x<=1;x++) {
|
|
for (int y=-1;y<=1;y++) {
|
|
if (x!=0&&y!=0) {
|
|
DrawStringPropDecal({WIDTH/6+4+WIDTH/3*2-8-GetTextSizeProp(std::to_string(BATTLE_CARD_SELECTION->playerOwnCount)+" uses remaining.").x*1.5+x,HEIGHT/6*3+HEIGHT/6*2-GetTextSizeProp(std::to_string(BATTLE_CARD_SELECTION->playerOwnCount)+" uses remaining.").y*1.5-4+y},std::to_string(BATTLE_CARD_SELECTION->playerOwnCount)+" uses remaining.",olc::BLACK,{1.5,1.5});
|
|
}
|
|
}
|
|
}
|
|
DrawStringPropDecal({WIDTH/6+4+WIDTH/3*2-8-GetTextSizeProp(std::to_string(BATTLE_CARD_SELECTION->playerOwnCount)+" uses remaining.").x*1.5,HEIGHT/6*3+HEIGHT/6*2-GetTextSizeProp(std::to_string(BATTLE_CARD_SELECTION->playerOwnCount)+" uses remaining.").y*1.5-4},std::to_string(BATTLE_CARD_SELECTION->playerOwnCount)+" uses remaining.",olc::WHITE,{1.5,1.5});
|
|
}break;
|
|
}
|
|
if (messageBoxVisible) {
|
|
DrawDialogBox({4,HEIGHT-60},{WIDTH/2,16},Pixel(18, 0, 33,180));
|
|
DrawDialogBox({0,HEIGHT-48},{WIDTH,48},Pixel(18, 0, 33,180));
|
|
DrawStringPropDecal({8,HEIGHT-40},messageBoxText);
|
|
DrawStringPropDecal({8,HEIGHT-57},messageBoxSpeaker);
|
|
if (messageBoxCursor==messageBoxRefText.length()) {
|
|
DrawStringPropDecal({WIDTH-16-(float)sin(frameCount*8/60.0)*3,HEIGHT-8+(float)(cos(frameCount*6/60.0)*0.6)},"v",Pixel(173, 74, 255,(0.5*sin(frameCount*8/60.0)+0.5)*128+128),{(float)sin(frameCount*8/60.0),0.5});
|
|
}
|
|
}
|
|
FillRectDecal({0,0},{WIDTH,HEIGHT},Pixel(0,0,0,transparency));
|
|
//FillRectDecal({WIDTH/2-2,HEIGHT/2-2},{4,4},WHITE);
|
|
}
|
|
|
|
void DrawGameWorld() {
|
|
for (int y=-1;y<=HEIGHT/32+1;y++) {
|
|
for (int x=-1;x<=WIDTH/32+1;x++) {
|
|
float xOffset=PLAYER_COORDS[0]-(WIDTH/32/2);
|
|
float yOffset=PLAYER_COORDS[1]-(HEIGHT/32/2);
|
|
srand((int)(yOffset+y)*MAP_WIDTH+(int)(xOffset+x));
|
|
int tileX=0;
|
|
int tileRot=0;
|
|
while (tileX<3&&rand()%4==0) {
|
|
tileX++;
|
|
}
|
|
while (tileRot<3&&rand()%8<5) {
|
|
tileRot++;
|
|
}
|
|
if ((int)(xOffset+x)>=0&&(int)(xOffset+x)<MAP_WIDTH&&(int)(yOffset+y)>=0&&(int)(yOffset+y)<MAP_HEIGHT) {
|
|
DrawPartialRotatedDecal({(x-(PLAYER_COORDS[0]-(int)PLAYER_COORDS[0])+1)*32-16,(y-(PLAYER_COORDS[1]-(int)PLAYER_COORDS[1])+1)*32},TILES,tileRot*M_PI_2,{16,16},{tileX*32,0},{32,32},{1,1},TILE_COLORS[MAP[(int)(yOffset+y)][(int)(xOffset+x)]]);
|
|
}
|
|
}
|
|
}
|
|
for (auto&obj:OBJECTS) {
|
|
if (obj.spr!=NULL) {
|
|
if (obj.name.compare("PLANT")==0) {
|
|
DrawPartialDecal({(obj.x-PLAYER_COORDS[0])*32+WIDTH/2,(obj.y-PLAYER_COORDS[1])*32+HEIGHT/2},{32,32},obj.spr,{getPlantStatus(obj.x,obj.y)*32,0},{32,32});
|
|
} else {
|
|
if (obj.name.find("NODE")!=std::string::npos) {
|
|
DrawDecal({(obj.x-PLAYER_COORDS[0])*32+WIDTH/2-32+18,(obj.y-PLAYER_COORDS[1])*32+HEIGHT/2-32+26},WEATHERNODE_EFFECT_DECAL);
|
|
DrawPartialDecal({(obj.x-PLAYER_COORDS[0])*32+WIDTH/2-16*(float)sin(frameCount*2/60.0)+16,(obj.y-PLAYER_COORDS[1])*32+HEIGHT/2},obj.anim->spr,{obj.anim->getCurrentFrame().x,obj.anim->getCurrentFrame().y},{obj.anim->width,obj.anim->height},{(float)sin(frameCount*2/60.0),1},Pixel((float)sin(frameCount*4/60.0)*55+200,(float)sin(frameCount*4/60.0)*55+200,(float)sin(frameCount*4/60.0+M_PI)+65*125,255));
|
|
} else
|
|
if (obj.hasAnim) {
|
|
DrawPartialDecal({(obj.x-PLAYER_COORDS[0])*32+WIDTH/2+(obj.anim->flipped?32:0),(obj.y-PLAYER_COORDS[1])*32+HEIGHT/2},obj.anim->spr,{obj.anim->getCurrentFrame().x,obj.anim->getCurrentFrame().y},{obj.anim->width,obj.anim->height},{obj.anim->flipped?-1:1,1});
|
|
} else {
|
|
DrawDecal({(obj.x-PLAYER_COORDS[0])*32+WIDTH/2,(obj.y-PLAYER_COORDS[1])*32+HEIGHT/2},obj.spr);
|
|
}
|
|
}
|
|
} else
|
|
if (obj.name.compare("EXIT")==0) {
|
|
GradientFillRectDecal({(obj.x-PLAYER_COORDS[0])*32+WIDTH/2,(obj.y-PLAYER_COORDS[1])*32+HEIGHT/2},{32,32},Pixel(0,0,0,0),WHITE,WHITE,Pixel(0,0,0,0));
|
|
}
|
|
}
|
|
for (auto&enc:ENCOUNTERS) {
|
|
for (auto&ent:enc.entities) {
|
|
DrawDecal({(enc.x+ent.x-PLAYER_COORDS[0])*32+WIDTH/2,(enc.y+ent.y-PLAYER_COORDS[1])*32+HEIGHT/2},ent.spr);
|
|
}
|
|
}
|
|
}
|
|
|
|
int getPlantId(int x, int y) {
|
|
return ((int)x-8)%4+((int)y-2)*4;
|
|
}
|
|
|
|
int getPlantStatus(int x,int y) {
|
|
return plantState>>getPlantId(x,y)*2&0b11;
|
|
}
|
|
|
|
void setPlantStatus(int x,int y,char state) {
|
|
int numb=0b11111111111111111111111111111111;
|
|
int numb2=0;
|
|
numb-=3<<getPlantId(x,y)*2;
|
|
plantState&=numb;
|
|
}
|
|
|
|
void DrawDialogBox(const vi2d &pos, const vi2d &size, Pixel p = WHITE, Pixel p2 = DARK_GREY, Pixel p3 = VERY_DARK_GREY) {
|
|
FillRectDecal({(float)pos.x,(float)pos.y},size,p2);
|
|
FillRectDecal({(float)pos.x+1,(float)pos.y+1},{(float)size.x-2,(float)size.y-2},p);
|
|
FillRectDecal({(float)pos.x+2,(float)pos.y+2},{(float)size.x-4,(float)size.y-4},p3);
|
|
FillRectDecal({(float)pos.x+3,(float)pos.y+3},{(float)size.x-5,(float)size.y-5},p);
|
|
Draw({pos.x,pos.y},BLACK);
|
|
Draw({pos.x+size.x,pos.y+size.y},BLACK);
|
|
Draw({pos.x+size.x,pos.y},BLACK);
|
|
Draw({pos.x,pos.y+size.y},BLACK);
|
|
}
|
|
|
|
void fadeOut() {
|
|
fade=true;
|
|
}
|
|
void fadeIn() {
|
|
fade=false;
|
|
}
|
|
|
|
void EndCutscene() {
|
|
CURRENT_CUTSCENE=cutscene::NONE;
|
|
}
|
|
|
|
void DisplayMessageBox(int dialogNumber) {
|
|
messageBoxVisible=true;
|
|
messageBoxCursor=0;
|
|
std::string split1=STORY_DIALOG[dialogNumber].substr(0,STORY_DIALOG[dialogNumber].find('\n')); //Unused for now.
|
|
std::string split2=STORY_DIALOG[dialogNumber].substr(STORY_DIALOG[dialogNumber].find('\n')+1,STORY_DIALOG[dialogNumber].find('\n',STORY_DIALOG[dialogNumber].find('\n')+1)-(STORY_DIALOG[dialogNumber].find('\n')+1));
|
|
std::string split3=STORY_DIALOG[dialogNumber].substr(STORY_DIALOG[dialogNumber].find('\n',STORY_DIALOG[dialogNumber].find('\n')+1)+1,STORY_DIALOG[dialogNumber].length()-(STORY_DIALOG[dialogNumber].find('\n',STORY_DIALOG[dialogNumber].find('\n')+1)+1));
|
|
messageBoxSpeaker=split2;
|
|
messageBoxText="";
|
|
messageBoxRefText=split3;
|
|
}
|
|
|
|
void LoadMap(char*mapName) {
|
|
std::ifstream f(mapName);
|
|
std::string data;
|
|
MAP_NAME=mapName;
|
|
MAP_WIDTH=MAP_HEIGHT=-1;
|
|
if (MAP!=NULL) {
|
|
for (int y=0;y<MAP_HEIGHT;y++) {
|
|
free(MAP[y]);
|
|
}
|
|
free(MAP);
|
|
MAP=NULL;
|
|
}
|
|
OBJECTS.clear();
|
|
|
|
int y=0;
|
|
if (f.is_open()) {
|
|
while (f.good()) {
|
|
f>>data;
|
|
if (MAP_WIDTH==-1) {
|
|
std::stringstream stream(data);
|
|
stream>>MAP_WIDTH;
|
|
} else
|
|
if (MAP_HEIGHT==-1) {
|
|
std::stringstream stream(data);
|
|
stream>>MAP_HEIGHT;
|
|
} else
|
|
if (y<MAP_HEIGHT) {
|
|
if (MAP==NULL) {
|
|
MAP=(int**)malloc(sizeof(int**)*MAP_HEIGHT);
|
|
}
|
|
MAP[y]=(int*)malloc(sizeof(int*)*MAP_WIDTH);
|
|
for (int i=0;i<data.length();i++) {
|
|
MAP[y][i]=data[i]-'0';
|
|
}
|
|
y++;
|
|
} else {
|
|
Object obj;
|
|
std::stringstream split1(data.substr(0,data.find(';')));
|
|
split1>>obj.x;
|
|
std::stringstream split2(data.substr(data.find(';')+1,data.find(';',data.find(";")+1)-(data.find(';')+1)));
|
|
split2>>obj.y;
|
|
std::string split3 = data.substr(data.find(';',data.find(";")+1)+1,data.length()-(data.find(';',data.find(";")+1)+1));
|
|
if (split3.compare("NULL")!=0) {
|
|
obj.spr=BASE_OBJECTS[split3]->spr;
|
|
if (BASE_OBJECTS[split3]->hasanim) {
|
|
obj.hasAnim=true;
|
|
obj.anim=BASE_OBJECTS[split3]->anim;
|
|
}
|
|
} else {
|
|
obj.spr=NULL;
|
|
}
|
|
obj.name=split3;
|
|
printf("Loaded object %s: (%f,%f)\n",split3.c_str(),obj.x,obj.y);
|
|
OBJECTS.push_back(obj);
|
|
}
|
|
}
|
|
}
|
|
printf("Loaded %dx%d map:\n",MAP_WIDTH,MAP_HEIGHT);
|
|
for (int y=0;y<MAP_HEIGHT;y++) {
|
|
for (int x=0;x<MAP_WIDTH;x++) {
|
|
printf("%d",MAP[y][x]);
|
|
}
|
|
printf("\n");
|
|
}
|
|
}
|
|
|
|
void changeAnimation(Animation anim) {
|
|
current_playerAnim=anim;
|
|
current_playerAnim.frame=0;
|
|
}
|
|
|
|
bool collidesWithPlayer(Object obj) {
|
|
if (obj.hasAnim) {
|
|
return PLAYER_COORDS[0]>=obj.x&&PLAYER_COORDS[0]<=obj.x+obj.anim->width/32.0&&
|
|
PLAYER_COORDS[1]>=obj.y&&PLAYER_COORDS[1]<=obj.y+obj.anim->height/32.0;
|
|
} else {
|
|
if (obj.spr==NULL) {
|
|
return PLAYER_COORDS[0]>=obj.x&&PLAYER_COORDS[0]<=obj.x+1&&
|
|
PLAYER_COORDS[1]>=obj.y&&PLAYER_COORDS[1]<=obj.y+1;
|
|
} else {
|
|
return PLAYER_COORDS[0]>=obj.x&&PLAYER_COORDS[0]<=obj.x+obj.spr->sprite->width/32.0&&
|
|
PLAYER_COORDS[1]>=obj.y&&PLAYER_COORDS[1]<=obj.y+obj.spr->sprite->height/32.0;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool collidesWithPlayer(Encounter obj) {
|
|
return PLAYER_COORDS[0]>=obj.x&&PLAYER_COORDS[0]<=obj.x+WIDTH/32&&
|
|
PLAYER_COORDS[1]>=obj.y&&PLAYER_COORDS[1]<=obj.y+HEIGHT/32;
|
|
}
|
|
|
|
void DrawWrappedPropText(vf2d pos,std::string text,int targetWidth,Pixel col,vf2d scale) {
|
|
std::string wrappedText;
|
|
int marker=0;
|
|
while (marker<text.length()) {
|
|
wrappedText+=text[marker];
|
|
if (GetTextSizeProp(wrappedText).x>targetWidth*scale.x) {
|
|
int tempMarker=marker;
|
|
while (wrappedText[tempMarker]!=' ') {
|
|
wrappedText.erase(tempMarker--);
|
|
}
|
|
wrappedText.erase(tempMarker++);
|
|
wrappedText+='\n';
|
|
while (tempMarker<marker+1) {
|
|
wrappedText+=text[tempMarker++];
|
|
}
|
|
}
|
|
marker++;
|
|
}
|
|
DrawStringPropDecal(pos,wrappedText,col,scale);
|
|
}
|
|
};
|
|
|
|
|
|
int main()
|
|
{
|
|
SeasonsOfLoneliness demo;
|
|
if (demo.Construct(256, 224, 4, 4))
|
|
demo.Start();
|
|
|
|
return 0;
|
|
} |