olc::CodeJam 2022 Entry #olcCodeJam2022
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.
Seasons-Of-Loneliness/SeasonsOfLoneliness.cpp

787 lines
27 KiB

2 years ago
#define OLC_PGE_APPLICATION
#include "pixelGameEngine.h"
#include "data.h"
#define OLC_PGEX_SPLASHSCREEN
#include "splash.h"
2 years ago
using namespace std;
enum GAMESTATE{
CUTSCENE_1,
CUTSCENE_2,
CUTSCENE_3,
GAMEWORLD,
WAITING_FOR_CUTSCENE_3,
};
enum CUTSCENE{
NONE,
PAN_DOME,
PAUSE_TO_CUTSCENE_3,
CUTSCENE_4,
};
#define WIDTH 256
#define HEIGHT 224
#define ALPHA_SCREEN1 128
#define ALPHA_SCREEN2 20
#define FADE_SPD 6
#define MOVE_SPD 0.2
#define MESSAGE_SCROLL_WAIT_SPD 2 //Number of frames to wait.
class Animation{
public:
olc::Decal*spr;
std::vector<olc::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;
olc::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:
olc::Decal*spr;
bool hasanim=false;
Animation*anim;
ObjectLoadInfo(olc::Decal*spr) {
this->spr=spr;
}
ObjectLoadInfo(olc::Decal*spr,Animation*anim) {
this->spr=spr;
this->anim=anim;
this->hasanim=true;
updateAnimationsList.push_back(anim);
}
};
class Object{
public:
float x,y;
olc::Decal*spr;
std::string name;
bool hasAnim=false;
Animation*anim;
};
class Entity{
public:
bool ally;
int hp;
int maxhp;
};
class SeasonsOfLoneliness : public olc::PixelGameEngine
2 years ago
{
public:
SeasonsOfLoneliness()
2 years ago
{
sAppName = "Seasons of Loneliness";
2 years ago
}
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 CUTSCENE_CONSOLE_TEXT = "";
int**MAP=NULL;
int MAP_WIDTH=-1;
int MAP_HEIGHT=-1;
olc::Decal*TILES;
float PLAYER_COORDS[2] = {};
std::vector<Object> OBJECTS;
bool CUTSCENE_ACTIVE=false;
CUTSCENE CURRENT_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;
olc::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;
bool IN_BATTLE_ENCOUNTER = false;
olc::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;
std::map<std::string,ObjectLoadInfo*> BASE_OBJECTS;
2 years ago
bool OnUserCreate() override
{
SetPixelMode(olc::Pixel::ALPHA);
ConsoleCaptureStdOut(true);
//ConsoleShow(olc::F1,false);
2 years ago
// Called once at the start, so create things here
TILES=new olc::Decal(new olc::Sprite("assets/tiles.png"));
DOME_DECAL=new olc::Decal(new olc::Sprite("assets/dome.png"));
FOOD_METER_DECAL=new olc::Decal(new olc::Sprite("assets/corn.png"));
OXYGEN_METER_DECAL=new olc::Decal(new olc::Sprite("assets/co2.png"));
PLANT_DECAL=new olc::Decal(new olc::Sprite("assets/plant.png"));
PLAYER_DECAL=new olc::Decal(new olc::Sprite("assets/player.png"));
WEATHERNODE_EFFECT_DECAL=new olc::Decal(new olc::Sprite("assets/weathernode_effect.png"));
POWER_HAILSTORM_DECAL=new olc::Decal(new olc::Sprite("assets/hailstorm_icon.png"));
POWER_HURRICANE_DECAL=new olc::Decal(new olc::Sprite("assets/hurricane_icon.png"));
POWER_METEOR_SHOWER_DECAL=new olc::Decal(new olc::Sprite("assets/meteor_shower_icon.png"));
POWER_METEOR_STORM_DECAL=new olc::Decal(new olc::Sprite("assets/meteor_storm.png"));
POWER_SNOWSTORM_DECAL=new olc::Decal(new olc::Sprite("assets/snowstorm_icon.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;
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("assets/maps/map1");
2 years ago
return true;
}
void GetAnyKeyPress() override {
if (!GetKey(olc::W).bPressed&&!GetKey(olc::A).bPressed&&!GetKey(olc::S).bPressed&&!GetKey(olc::D).bPressed&&
!GetKey(olc::UP).bPressed&&!GetKey(olc::RIGHT).bPressed&&!GetKey(olc::DOWN).bPressed&&!GetKey(olc::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;
}
}
2 years ago
bool OnUserUpdate(float fElapsedTime) override
{
elapsedTime+=fElapsedTime;
while (elapsedTime>TARGET_RATE) {
elapsedTime-=TARGET_RATE;
updateGame();
}
if (GetKey(olc::F1).bPressed) {
ConsoleShow(olc::F1,false);
}
if (GetKey(olc::D).bPressed||GetKey(olc::RIGHT).bPressed||GetKey(olc::NP6).bPressed) {
changeAnimation(playerAnimWalkRight);
}
if (GetKey(olc::A).bPressed||GetKey(olc::LEFT).bPressed||GetKey(olc::NP4).bPressed) {
changeAnimation(playerAnimWalkLeft);
}
if (GetKey(olc::W).bPressed||GetKey(olc::UP).bPressed||GetKey(olc::NP8).bPressed) {
changeAnimation(playerAnimWalkUp);
}
if (GetKey(olc::S).bPressed||GetKey(olc::DOWN).bPressed||GetKey(olc::NP5).bPressed||GetKey(olc::NP2).bPressed) {
changeAnimation(playerAnimWalkDown);
}
if (!GetKey(olc::D).bHeld&&!GetKey(olc::RIGHT).bHeld&&!GetKey(olc::NP6).bHeld&&
!GetKey(olc::A).bHeld&&!GetKey(olc::LEFT).bHeld&&!GetKey(olc::NP4).bHeld&&
!GetKey(olc::S).bHeld&&!GetKey(olc::UP).bHeld&&!GetKey(olc::NP8).bHeld&&
!GetKey(olc::W).bHeld&&!GetKey(olc::DOWN).bHeld&&!GetKey(olc::NP5).bHeld&&!GetKey(olc::NP2).bHeld) {
if (GetKey(olc::D).bReleased||GetKey(olc::RIGHT).bReleased||GetKey(olc::NP6).bReleased) {
changeAnimation(playerAnimRight);
}
if (GetKey(olc::A).bReleased||GetKey(olc::LEFT).bReleased||GetKey(olc::NP4).bReleased) {
changeAnimation(playerAnimLeft);
}
if (GetKey(olc::W).bReleased||GetKey(olc::UP).bReleased||GetKey(olc::NP8).bReleased) {
changeAnimation(playerAnim);
}
if (GetKey(olc::S).bReleased||GetKey(olc::DOWN).bReleased||GetKey(olc::NP5).bReleased||GetKey(olc::NP2).bReleased) {
changeAnimation(playerAnimDown);
}
}
drawGame();
2 years ago
// called once per frame
return true;
}
void fadeOutCompleted() {
switch (GAME_STATE) {
case CUTSCENE_1:{
GAME_STATE=CUTSCENE_2;
PlayCutscene(PAN_DOME);
fadeIn();
}break;
case CUTSCENE_2:{
fadeIn();
PlayCutscene(CUTSCENE_4);
GAME_STATE=GAMEWORLD;
}break;
}
}
void fadeInCompleted() {
}
void PlayCutscene(CUTSCENE scene) {
CURRENT_CUTSCENE=scene;
switch (scene) {
case PAN_DOME:{
PLAYER_COORDS[0]=14;
PLAYER_COORDS[1]=18+(64/2/32);
}break;
case PAUSE_TO_CUTSCENE_3:{
CUTSCENE_CONSOLE_TEXT.clear();
textInd=0;
}break;
case 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=clamp(transparency+FADE_SPD,0,255);
if (transparency==255) {
fadeOutCompleted();
}
} else
if (!fade&&transparency>0) {
transparency=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(olc::D).bHeld||GetKey(olc::RIGHT).bHeld||GetKey(olc::NP6).bHeld) {
PLAYER_COORDS[0]=clamp(PLAYER_COORDS[0]+MOVE_SPD,0.1,(double)MAP_WIDTH);
ConsoleClear();
cout<<"("<<PLAYER_COORDS[0]<<","<<PLAYER_COORDS[1]<<+")";
if (!changed&&&current_playerAnim!=&playerAnimWalkRight) {
changeAnimation(playerAnimWalkRight);
changed=true;
}
}
if (GetKey(olc::A).bHeld||GetKey(olc::LEFT).bHeld||GetKey(olc::NP4).bHeld) {
PLAYER_COORDS[0]=clamp(PLAYER_COORDS[0]-MOVE_SPD,0.1,(double)MAP_WIDTH);
ConsoleClear();
cout<<"("<<PLAYER_COORDS[0]<<","<<PLAYER_COORDS[1]<<+")";
if (!changed&&&current_playerAnim!=&playerAnimWalkLeft) {
changeAnimation(playerAnimWalkLeft);
changed=true;
}
}
if (GetKey(olc::W).bHeld||GetKey(olc::UP).bHeld||GetKey(olc::NP8).bHeld) {
PLAYER_COORDS[1]=clamp(PLAYER_COORDS[1]-MOVE_SPD,0.1,(double)MAP_HEIGHT);
ConsoleClear();
cout<<"("<<PLAYER_COORDS[0]<<","<<PLAYER_COORDS[1]<<+")";
if (!changed&&&current_playerAnim!=&playerAnimWalkUp) {
changeAnimation(playerAnimWalkUp);
changed=true;
}
}
if (GetKey(olc::S).bHeld||GetKey(olc::DOWN).bHeld||GetKey(olc::NP5).bHeld||GetKey(olc::NP2).bHeld) {
PLAYER_COORDS[1]=clamp(PLAYER_COORDS[1]+MOVE_SPD,0.1,(double)MAP_HEIGHT);
ConsoleClear();
cout<<"("<<PLAYER_COORDS[0]<<","<<PLAYER_COORDS[1]<<+")";
if (!changed&&&current_playerAnim!=&playerAnimWalkDown) {
changeAnimation(playerAnimWalkDown);
changed=true;
}
}
}
switch (CURRENT_CUTSCENE) {
case 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,olc::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},olc::GREEN);
} else {
FillRectDecal({(float)(16+(cursorX)*8%(WIDTH-32)),(float)(8+GetTextSize(CUTSCENE_CONSOLE_TEXT).y+((cursorX==28)?8:0))},{4,8},olc::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(to_string(foodCount)).x*1-8,meterYOffset+2},to_string(foodCount),olc::BLUE,{1,1});
DrawStringDecal({WIDTH-36*0.4-GetTextSize(to_string(foodCount)).x*1-7,meterYOffset+2},to_string(foodCount),olc::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(to_string(oxygenQualityLevel)+"%").x*1-8,meterYOffset+2},to_string(oxygenQualityLevel)+"%",olc::BLUE,{1,1});
DrawStringDecal({WIDTH-36*0.4-GetTextSize(to_string(oxygenQualityLevel)+"%").x*1-7,meterYOffset+2},to_string(oxygenQualityLevel)+"%",olc::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});
}
}break;
case CUTSCENE_3:{
DrawStringDecal({48,16},CUTSCENE_CONSOLE_TEXT,olc::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},olc::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},olc::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;
}
if (messageBoxVisible) {
DrawDialogBox({4,HEIGHT-60},{WIDTH/2,16},olc::Pixel(18, 0, 33,180));
DrawDialogBox({0,HEIGHT-48},{WIDTH,48},olc::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",olc::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},olc::Pixel(0,0,0,transparency));
//FillRectDecal({WIDTH/2-2,HEIGHT/2-2},{4,4},olc::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},olc::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},olc::Pixel(0,0,0,0),olc::WHITE,olc::WHITE,olc::Pixel(0,0,0,0));
}
}
}
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 olc::vi2d &pos, const olc::vi2d &size, olc::Pixel p = olc::WHITE, olc::Pixel p2 = olc::DARK_GREY, olc::Pixel p3 = olc::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},olc::BLACK);
Draw({pos.x+size.x,pos.y+size.y},olc::BLACK);
Draw({pos.x+size.x,pos.y},olc::BLACK);
Draw({pos.x,pos.y+size.y},olc::BLACK);
}
void fadeOut() {
fade=true;
}
void fadeIn() {
fade=false;
}
void EndCutscene() {
CURRENT_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_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;
}
2 years ago
};
int main()
{
SeasonsOfLoneliness demo;
if (demo.Construct(256, 224, 4, 4))
2 years ago
demo.Start();
return 0;
}