# define OLC_PGE_APPLICATION
# include "pixelGameEngine.h"
# include "data.h"
# define OLC_PGEX_SPLASHSCREEN
# include "splash.h"
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
{
public :
SeasonsOfLoneliness ( )
{
sAppName = " Seasons of Loneliness " ;
}
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 ;
bool OnUserCreate ( ) override
{
SetPixelMode ( olc : : Pixel : : ALPHA ) ;
ConsoleCaptureStdOut ( true ) ;
//ConsoleShow(olc::F1,false);
// 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 " ) ;
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 ;
}
}
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 ( ) ;
// 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 ;
}
} ;
int main ( )
{
SeasonsOfLoneliness demo ;
if ( demo . Construct ( 256 , 224 , 4 , 4 ) )
demo . Start ( ) ;
return 0 ;
}