#define OLC_PGE_APPLICATION #include "pixelGameEngine.h" #include "data.h" #define OLC_PGEX_SPLASHSCREEN #include "splash.h" #include #define OLC_SOUNDWAVE #include "soundwaveEngine.h" using namespace olc; //#define TEST_MAP1 //Toggle to just play around on map 1. //#define TEST_MAP2 //Toggle on to just play around on map 2. #define SKIP_INTRO true #define SKIP_CHAPTER1 true #define SKIP_CHAPTER2 false #define SKIP_CHAPTER3 false #define STARTING_MAP "assets/maps/map1" #define STARTING_STATE CUTSCENE_3 #define MOVE_SPD 0.075 #define PLAYER_X 14 #define PLAYER_Y 4 #ifdef TEST_MAP1 #define STARTING_MAP "assets/maps/map1" #define STARTING_STATE GAMEWORLD #define MOVE_SPD 0.1 #define PLAYER_X 40 #define PLAYER_Y 31 #endif #ifdef TEST_MAP2 #define STARTING_MAP "assets/maps/map2" #define STARTING_STATE GAMEWORLD #define MOVE_SPD 0.1 #define PLAYER_X 16 #define PLAYER_Y 5 #endif enum GAMESTATE{ CUTSCENE_1, CUTSCENE_2, CUTSCENE_3, GAMEWORLD, WAITING_FOR_CUTSCENE_3, GAME_OVER, COLLECTED_SILICON, CUTSCENE_4, //First rover repaired. CUTSCENE_4_DONE, LATER_THAT_NIGHTFADEIN, LATER_THAT_NIGHTWAIT, LATER_THAT_NIGHTFADEOUT, }; namespace cutscene{ enum CUTSCENE{ NONE, PAN_DOME, PAUSE_TO_CUTSCENE_3, CUTSCENE_4, TRANSITION_CUTSCENE, //Exit the dome. TRANSITION_CUTSCENE_2, //Enter the dome. NODE_COLLECT_CUTSCENE, PAN_OVER_TO_CROPS, RAINING_IN_DOME, AFTER_RAIN, WALK_TO_COMPUTER, INPUT_USERNAME, GO_OUTSIDE, WALK_TO_ROVER, DISPLAY_VOLCANIC_AREA, END_VOLCANIC_AREA_CUTSCENE, REPAIR_ROVER_1, GET_SOME_REST, IN_BED, SHAKE, INVESTIGATE_X_X, }; } namespace battle{ enum BATTLESTATE{ NONE, WAITING_FOR_CAMERA, PLAYER_SELECTION, PLAYER_TARGET_SELECTION, ENEMY_SELECTION, MOVE_RESOLUTION, PERFORM_TURN, WAIT_TURN_ANIMATION, WAIT_TURN_ANIMATION2, DAMAGE_RESOLUTION, }; } namespace gameflag{ enum FLAG{ TUTORIAL_WALKED_OFF_FARM, VISIT_BROKEN_ROVER, COLLECTED_SILICON_1, REPAIRED_ROVER_1, REST_IN_DOME, SLEEP, FIRST_ENCOUNTER_X_X, ANALYSIS_X_X, TUTORIAL1_X_X, TUTORIAL2_X_X, }; } enum MOVEMENT_PRIORITY{ HORZ_FIRST, VERT_FIRST, BOTH }; class Seed{ public: vf2d pos; Seed(vf2d pos) { this->pos=pos; } }; namespace reasoncode{ enum Code{ SEED_GROWTH, TREE_BURN }; } #define MAX_TERMINAL_NAME_LENGTH 6 #define WIDTH 256 #define HEIGHT 224 #define ALPHA_SCREEN1 128 #define ALPHA_SCREEN2 20 #define FADE_SPD 6 #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 DisplayNumber{ public: int number; //Negative means healing. int frame; //Frame it was created. float x,y; int alpha=255; DisplayNumber(int numb,float x,float y,int frameCount) { this->number=numb; this->x=x; this->y=y; this->frame=frameCount; } }; class Animation{ public: Decal*spr; std::vector 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 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; vi2d spos; vi2d size; Pixel col; bool hascut=false; ObjectLoadInfo(Decal*spr,Pixel col=WHITE) { this->spr=spr; this->col=col; } ObjectLoadInfo(Decal*spr,Animation*anim,Pixel col=WHITE) { this->spr=spr; this->anim=anim; this->hasanim=true; bool matches=false; for (int i=0;icol=col; } ObjectLoadInfo(Decal*spr,vi2d spos,vi2d size,Pixel col=WHITE) { this->spr=spr; this->hascut=true; this->spos=spos; this->size=size; this->col=col; } }; class Object{ public: float x,y; Decal*spr; std::string name; bool hasAnim=false; Animation*anim; vi2d spos; vi2d size; bool flipped=false; bool hascut=false; bool tempObj=false; Pixel col; Object(){}; Object(Decal*spr,Pixel col=WHITE) { this->spr=spr; this->col=col; } Object(Decal*spr,Animation*anim,Pixel col=WHITE) { this->spr=spr; this->anim=anim; this->hasAnim=true; bool matches=false; for (int i=0;icol=col; } Object(Decal*spr,vi2d spos,vi2d size,Pixel col=WHITE) { this->spr=spr; this->hascut=true; this->spos=spos; this->size=size; this->col=col; } }; class ParticleEffect{ public: vf2d effectPos; vf2d effectSize; vf2d pos_low; vf2d pos_high; vf2d size_low; vf2d size_high; vf2d spd_low; vf2d spd_high; olc::Pixel col_low; olc::Pixel col_high; int amt; olc::Pixel foregroundColor; ParticleEffect(vf2d effectPos,vf2d effectSize,vf2d pos_low,vf2d pos_high,vf2d size_low,vf2d size_high,vf2d spd_low,vf2d spd_high,olc::Pixel col_low,olc::Pixel col_high,int amt,olc::Pixel foregroundColor) { this->effectPos=effectPos; this->effectSize=effectSize; this->pos_low=pos_low; this->pos_high=pos_high; this->size_low=size_high; this->spd_low=spd_low; this->spd_high=spd_high; this->col_low=col_low; this->col_high=col_high; this->amt=amt; this->foregroundColor=foregroundColor; } }; class WEATHER_POWER{ public: std::string description; std::string name; Animation*anim; Animation*effectAnim; int damage; int damageRoll; int range; int playerOwnCount=0; Pixel bgcol; Pixel textcol; int effectTime=0; ParticleEffect*effect; int seedProduction=0; //Number of seeds to add to field. float seedScatter=1; //Multiplier of current seeds on field. bool growSeeds=false; //If set to true, will trigger a growth of all seeds. bool burnTrees=false; //If set to true, will trigger a burning of trees. float treeBurnChance=1; //% chance of trees getting burned by this attack. WEATHER_POWER(std::string name,std::string desc,Animation*icon,Animation*effect,int dmg,int dmgRoll,int range,Pixel bgcol,Pixel textcol,int effectTime,ParticleEffect*parteff) { this->description=desc; this->name=name; this->anim=icon; this->effectAnim=effect; this->damage=dmg; this->damageRoll=dmgRoll; this->range=range; this->bgcol=bgcol; this->textcol=textcol; this->effectTime=effectTime; this->effect=parteff; } }; class Entity{ public: bool ally=false; int hp; int maxhp; Decal*spr; float x; float y; std::string name; WEATHER_POWER*selectedMove; std::vector moveSet; bool turnComplete=false; bool slowed=false; int damageFrame=0; int fixedTurnOrderInd=0; bool fixedTurnOrder=false; //If this is turned on, the selected move will increment in order of the move set (and loop accordingly.) vf2d sprScale; Entity(Decal*spr,std::string name,float x,float y,int hp,int maxhp,std::vectormoveset,vf2d sprScale={1,1},bool fixedMoveset=false) { this->spr=spr; this->name=name; this->x=x; this->y=y; this->maxhp=hp; this->hp=hp; this->maxhp=maxhp; this->moveSet=moveset; this->fixedTurnOrder=fixedMoveset; this->sprScale=sprScale; } }; class Encounter{ public: int x,y; float playerX,playerY; std::vector entities; std::vector turnOrder; }; class Zone{ public: vi2d pos; //In tile coordinates. vi2d size; //In tile coordinates. ParticleEffect*eff; Zone(vi2d pos,vi2d size,vf2d effectPos,vf2d effectSize,vf2d pos_low,vf2d pos_high,vf2d size_low,vf2d size_high,vf2d spd_low,vf2d spd_high,olc::Pixel col_low,olc::Pixel col_high,int amt,olc::Pixel foregroundColor) { this->pos=pos; this->size=size; this->eff=new ParticleEffect(effectPos,effectSize,pos_low,pos_high,size_low,size_high,spd_low,spd_high,col_low,col_high,amt,foregroundColor); } }; namespace effect { class Pixel{ public: vf2d pos, size, spd; int r,g,b,a; int o_r,o_g,o_b,o_a; Pixel() { pos={0,0}; size={0,0}; spd={0,0}; }; Pixel(vf2d pos,vf2d size,vf2d spd,olc::Pixel col) { this->pos=pos; this->size=size; this->spd=spd; this->r=this->o_r=col.r; this->g=this->o_g=col.g; this->b=this->o_b=col.b; this->a=this->o_a=col.a; } }; }; class SeasonsOfLoneliness : public PixelGameEngine { public: SeasonsOfLoneliness() { sAppName = "Seasons of Loneliness"; } public: sound::WaveEngine engine; GAMESTATE GAME_STATE=STARTING_STATE; int textInd=0; int cursorX=0; int transitionTime=0; int TIMER=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 = ""; bool GAME_FLAGS[128]={}; int**MAP=NULL; int MAP_WIDTH=-1; int MAP_HEIGHT=-1; Decal*TILES; float PLAYER_COORDS[2] = {PLAYER_X,PLAYER_Y}; std::vector OBJECTS; bool CUTSCENE_ACTIVE=false; cutscene::CUTSCENE CURRENT_CUTSCENE=cutscene::NONE; int CUTSCENE_TIMER=0; bool CUTSCENE_FLAGS[8]; Object*CUTSCENE_OBJS[8]; int CUTSCENE_OBJ_INDICES[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=0b01001010010100010101010010010101; SplashScreen splash; Animation*current_playerAnim=new Animation(); Animation*playerAnim=new Animation(); Animation*playerAnimRight=new Animation(); Animation*playerAnimLeft=new Animation(); Animation*playerAnimDown=new Animation(); Animation*playerAnimWalkUp=new Animation(); Animation*playerAnimWalkDown=new Animation(); Animation*playerAnimWalkRight=new Animation(); Animation*playerAnimWalkLeft=new Animation(); Animation*playerAnimPlantUp=new Animation(); Animation*playerAnimPlantDown=new Animation(); Animation*playerAnimPlantRight=new Animation(); Animation*playerAnimPlantLeft=new Animation(); Animation*POWER_HAILSTORM_ANIMATION=new Animation(); Animation*POWER_HURRICANE_ANIMATION=new Animation(); Animation*POWER_METEOR_SHOWER_ANIMATION=new Animation(); Animation*POWER_METEOR_STORM_ANIMATION=new Animation(); Animation*POWER_SNOWSTORM_ANIMATION=new Animation(); Animation*CONSUME_SNACK_ANIMATION=new Animation(); Animation*CONSUME_MEAL_ANIMATION=new Animation(); Animation*NADO_ANIMATION=new Animation(); Animation*PETAL_STORM_ANIMATION=new Animation(); Animation*SLEEP_ANIMATION=new Animation(); Animation*EMPTY_BED_ANIMATION=new Animation(); ParticleEffect*HAILSTORM_EFF = new ParticleEffect({0,0},{WIDTH,HEIGHT},{0,0},{WIDTH,HEIGHT},{1,1},{4,4},{-2,0.5},{-0.5,2},Pixel(143, 242, 255,255),Pixel(255,255,255,255),300,Pixel(220, 226, 227,0)); ParticleEffect*HURRICANE_EFF = new ParticleEffect({0,0},{WIDTH,HEIGHT},{0,0},{WIDTH,HEIGHT},{1,1},{2,2},{-4,1},{-1,4},Pixel(225, 248, 252,64),Pixel(255,255,255,128),300,Pixel(220, 226, 227,0)); ParticleEffect*METEOR_RAIN_EFF = new ParticleEffect({0,0},{WIDTH,HEIGHT},{0,0},{WIDTH,HEIGHT},{3,3},{6,6},{-1,0.2},{-0.2,1},Pixel(46, 31, 31,255),Pixel(43, 31, 46,255),50,Pixel(30, 10, 36,0)); ParticleEffect*METEOR_STORM_EFF = new ParticleEffect({0,0},{WIDTH,HEIGHT},{0,0},{WIDTH,HEIGHT},{3,3},{10,10},{-2,0.1},{-0.1,2},Pixel(46, 31, 31,255),Pixel(181, 72, 46,255),75,Pixel(30, 10, 36,48)); ParticleEffect*SNOWSTORM_EFF = new ParticleEffect({0,0},{WIDTH,HEIGHT},{0,0},{WIDTH,HEIGHT},{1,1},{3,3},{-1,0.5},{1,2},Pixel(193, 198, 201,200),Pixel(255,255,255,255),400,Pixel(220, 226, 227,0)); ParticleEffect*SANDSTORM_EFF = new ParticleEffect({0,0},{WIDTH,HEIGHT},{0,0},{WIDTH,HEIGHT},{1,1},{3,3},{-20,1},{20,3},Pixel(133, 98, 66,130),Pixel(158, 93, 33,210),300,Pixel(87, 78, 69,0)); ParticleEffect*SEED_STORM_EFF = new ParticleEffect({0,0},{WIDTH,HEIGHT},{0,0},{WIDTH,HEIGHT},{1,1},{2,2},{-0.5,-1},{0.5,-0.2},Pixel(65, 98, 66,130),Pixel(65, 117, 60,210),100,Pixel(70, 158, 62,0)); ParticleEffect*AVALANCHE_EFF = new ParticleEffect({0,0},{WIDTH,HEIGHT},{0,0},{WIDTH,HEIGHT},{1,1},{8,8},{-4,2},{4,4},Pixel(143, 242, 255,255),Pixel(255,255,255,255),300,Pixel(220, 226, 227,0)); ParticleEffect*CONSUME_SNACK_EFF = new ParticleEffect({0,0},{64,64},{64,64},{64,64},{1,1},{2,2},{-0.1,-0.5},{0.1,-0.05},Pixel(255,255,255,130),Pixel(255,255,255,210),30,Pixel(147, 161, 90,0)); //Used for CONSUME_MEAL too. ParticleEffect*PETAL_STORM_EFF = new ParticleEffect({0,0},{WIDTH,HEIGHT},{0,0},{WIDTH,HEIGHT},{1,1},{3,3},{-4,0.6},{4,2},Pixel(127, 27, 130,130),Pixel(227, 218, 227,240),160,Pixel(147, 161, 90,0)); ParticleEffect*LIGHT_STORM_EFF = new ParticleEffect({0,0},{WIDTH,HEIGHT},{0,0},{WIDTH,HEIGHT},{1,HEIGHT/2},{2,HEIGHT},{0,4},{0,25},Pixel(214, 233, 255,130),Pixel(255, 255, 255,255),30,Pixel(0, 0, 0,32)); ParticleEffect*SEED_BULLET_EFF = new ParticleEffect({0,0},{64,64},{0,0},{WIDTH,HEIGHT},{1,1},{3,3},{-5,-5},{5,5},Pixel(138, 255, 153,200),Pixel(193, 245, 200,210),40,Pixel(70, 158, 62,0)); ParticleEffect*SEED_PELLET_EFF = new ParticleEffect({0,0},{64,64},{0,0},{WIDTH,HEIGHT},{1,1},{1,1},{-3,-3},{3,3},Pixel(138, 255, 153,200),Pixel(193, 245, 200,210),10,Pixel(70, 158, 62,0)); ParticleEffect*SUMMON_MINION_EFF = new ParticleEffect({0,0},{WIDTH,HEIGHT},{0,0},{WIDTH,HEIGHT},{4,4},{12,12},{0,-6},{0,-20},Pixel(223, 242, 0,130),Pixel(223, 255, 114,210),50,Pixel(70, 158, 62,0)); ParticleEffect*SEED_OF_LIFE_EFF = new ParticleEffect({0,0},{WIDTH,HEIGHT},{0,0},{WIDTH,HEIGHT},{2,2},{2,2},{-1,-2},{1,-0.2},Pixel(65, 98, 66,210),Pixel(65, 117, 60,255),140,Pixel(70, 158, 62,0)); ParticleEffect*FIRESTORM_EFF = new ParticleEffect({0,0},{WIDTH,HEIGHT},{0,0},{WIDTH,HEIGHT},{4,4},{12,12},{-12,-8},{12,-4},Pixel(209, 90, 69,130),Pixel(209, 141, 69,255),140,Pixel(255, 0, 0,32)); 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,Pixel(72, 160, 212,255),Pixel(93, 161, 163,255),120,HAILSTORM_EFF); 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,Pixel(99, 148, 132,255),Pixel(121, 132, 140,255),120,HURRICANE_EFF); WEATHER_POWER*METEOR_RAIN = new WEATHER_POWER("Meteor Rain","Causes fiery space rocks to fall on target area. 50+50d",POWER_METEOR_SHOWER_ANIMATION,POWER_METEOR_SHOWER_ANIMATION,50,50,96,Pixel(96, 86, 153,255),Pixel(170, 103, 201,255),120,METEOR_STORM_EFF); WEATHER_POWER*METEOR_STORM = new WEATHER_POWER("Meteor Storm","Larger burning space rocks. 120+60d",POWER_METEOR_STORM_ANIMATION,POWER_METEOR_STORM_ANIMATION,120,60,140,Pixel(89, 4, 33,255),Pixel(130, 56, 1,255),120,METEOR_RAIN_EFF); 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,Pixel(183, 196, 194,255),Pixel(222, 255, 254,255),120,SNOWSTORM_EFF); WEATHER_POWER*SANDSTORM = new WEATHER_POWER("Sandstorm","",POWER_HAILSTORM_ANIMATION,POWER_HAILSTORM_ANIMATION,5,10,64,Pixel(93, 161, 163,255),Pixel(72, 160, 212,255),120,SANDSTORM_EFF); WEATHER_POWER*SEED_STORM = new WEATHER_POWER("Seed Storm","",POWER_HAILSTORM_ANIMATION,POWER_HAILSTORM_ANIMATION,-10,15,30,Pixel(93, 161, 163,255),Pixel(72, 160, 212,255),120,SEED_STORM_EFF); WEATHER_POWER*AVALANCHE = new WEATHER_POWER("Avalanche","",POWER_HAILSTORM_ANIMATION,POWER_HAILSTORM_ANIMATION,15,10,200,Pixel(93, 161, 163,255),Pixel(72, 160, 212,255),120,AVALANCHE_EFF); WEATHER_POWER*LIGHT_STORM = new WEATHER_POWER("Light Storm","",POWER_HAILSTORM_ANIMATION,POWER_HAILSTORM_ANIMATION,50,9,64,Pixel(171, 151, 53,255),Pixel(237, 237, 237,255),120,LIGHT_STORM_EFF); WEATHER_POWER*SEED_BULLET = new WEATHER_POWER("Seed Bullet","",POWER_HAILSTORM_ANIMATION,POWER_HAILSTORM_ANIMATION,10,15,30,Pixel(57, 92, 63,255),Pixel(95, 232, 119,255),120,SEED_BULLET_EFF); WEATHER_POWER*SEED_PELLET = new WEATHER_POWER("Seed Pellet","",POWER_HAILSTORM_ANIMATION,POWER_HAILSTORM_ANIMATION,5,10,30,Pixel(57, 92, 63,255),Pixel(95, 232, 119,255),120,SEED_PELLET_EFF); WEATHER_POWER*SEED_OF_LIFE = new WEATHER_POWER("Seed of Life","",POWER_HAILSTORM_ANIMATION,POWER_HAILSTORM_ANIMATION,-10,15,30,Pixel(93, 161, 163,255),Pixel(72, 160, 212,255),120,SEED_OF_LIFE_EFF); WEATHER_POWER*SUMMON_MINIONS = new WEATHER_POWER("Summon Minions","",POWER_HAILSTORM_ANIMATION,POWER_HAILSTORM_ANIMATION,-75,15,255,Pixel(57, 92, 63,255),Pixel(95, 232, 119,255),120,SUMMON_MINION_EFF); WEATHER_POWER*CONSUME_SNACK = new WEATHER_POWER("Snack","Restores 33% health for 5 turns. If battle ends before effect ends, food is not consumed.",CONSUME_SNACK_ANIMATION,CONSUME_SNACK_ANIMATION,-1001,1,200,Pixel(147, 173, 66,255),Pixel(255, 188, 3,255),120,CONSUME_SNACK_EFF); WEATHER_POWER*CONSUME_MEAL = new WEATHER_POWER("Meal","Restores all health. Increases Maximum Health by 5.",CONSUME_MEAL_ANIMATION,CONSUME_MEAL_ANIMATION,-1002,1,200,Pixel(147, 173, 66,255),Pixel(255, 188, 3,255),120,CONSUME_SNACK_EFF); WEATHER_POWER*PETAL_STORM = new WEATHER_POWER("Petal Storm","Places seeds, causes minor healing. 20+20d",PETAL_STORM_ANIMATION,PETAL_STORM_ANIMATION,20,20,110,Pixel(189, 132, 189,255),Pixel(235, 75, 235,255),120,PETAL_STORM_EFF); bool IN_BATTLE_ENCOUNTER = false; int BATTLE_ENTRY_TIMER = 0; int EFFECT_TIMER = 0; #define WEATHER_POWER_COUNT 8 //Number of powers that are in the game. Update storage array accordingly. WEATHER_POWER*WEATHER_POWERS[WEATHER_POWER_COUNT] = { HAILSTORM, PETAL_STORM, HURRICANE, METEOR_RAIN, METEOR_STORM, SNOWSTORM, CONSUME_SNACK, CONSUME_MEAL}; battle::BATTLESTATE BATTLE_STATE=battle::NONE; std::vector availablePowers; WEATHER_POWER*BATTLE_CARD_SELECTION=HAILSTORM; int BATTLE_CARD_SELECTION_IND=0; int PLAYER_SELECTED_TARGET=-1; int PLAYER_MAXHP=60; int PLAYER_HP=PLAYER_MAXHP; int BATTLE_CURRENT_TURN_ENTITY=-1; int CURRENT_ENCOUNTER_IND=-1; unsigned int RAND_CALLS=0; std::vector BATTLE_DISPLAY_NUMBERS; bool PLAYER_TURN_COMPLETE=false; int FOOD_REGEN_TURNS=0; WEATHER_POWER* CUTSCENE_DISPLAYED_CARD; Pixel FOREGROUND_EFFECT_COLOR; Pixel ORIGINAL_FOREGROUND_EFFECT_COLOR; int PIXEL_LIMIT=0; vf2d PIXEL_POS; vf2d PIXEL_SIZE; float PIXEL_EFFECT_TRANSPARENCY=0; int CUTSCENE_OBJ_COUNT=0; int TERMINAL_SELECTED_CHAR=0; std::string TERMINAL_INPUT=""; std::string PLAYER_NAME="..."; std::vectorZONES; std::vectorCOLLECTED_ITEMS; Zone*ACTIVE_ZONE=nullptr; std::vectorREPAIRED_ROVERS; std::string CONSOLE_REF_TEXT; bool SOUND_IS_PLAYING=false; int MAIN_MENU_SELECTION=0; std::string MENU_OPTIONS[4]={"NEW GAME","CONTINUE","MUTE SOUND","EXIT"}; int BATTLE_REASON_CODE=-1; 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,*TARGETING_CIRCLE,*TARGETING_RANGE_CIRCLE,*HEALTHBAR_DECAL, *CONSUME_SNACK_DECAL,*CONSUME_MEAL_DECAL,*COMPUTER_DECAL,*BROKEN_ROVER_DECAL, *NADO_DECAL,*SILICON_ROCK_DECAL,*PETAL_STORM_DECAL,*ROVER_DECAL,*X_X_DECAL, *LATER_THAT_NIGHT_DECAL,*SLEEP_DECAL,*SEED_DECAL,*TREE_DECAL,*X_X_UNCHARGED_DECAL; std::map BASE_OBJECTS; std::vector ENCOUNTERS; Encounter ENCOUNTER_SPIDEY_1; Encounter ENCOUNTER_X_X; Encounter CURRENT_ENCOUNTER; std::vectorMOVESET_SPIDEY; std::vectorMOVESET_X_X; std::vectorMOVESET_XMINION; std::vectorSEEDS; std::vectorTREES; bool SOUND_IS_MUTED=false; bool END_THE_GAME=false; bool audioFade=false; float audioLevel=0.6; int SEED_COUNT=0; vf2d BATTLE_PLAYER_COORDS; sound::Wave SONG_MAIN; std::queue turnOrder; #define MAX_PIXELS 500 effect::Pixel*pixels[MAX_PIXELS]; bool OnUserCreate() override { SetPixelMode(Pixel::ALPHA); ConsoleCaptureStdOut(true); engine.InitialiseAudio(); #define LAYERS 3 //How many layers exist. for (int i=1;ispr=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; CONSUME_SNACK_ANIMATION->spr=CONSUME_SNACK_DECAL; CONSUME_SNACK_ANIMATION->frames.push_back({0,0}); CONSUME_SNACK_ANIMATION->frames.push_back({32,0}); CONSUME_SNACK_ANIMATION->frames.push_back({64,0}); CONSUME_SNACK_ANIMATION->skip_frames=nodeAnimationSkipFrames; CONSUME_MEAL_ANIMATION->spr=CONSUME_MEAL_DECAL; CONSUME_MEAL_ANIMATION->frames.push_back({0,0}); CONSUME_MEAL_ANIMATION->frames.push_back({32,0}); CONSUME_MEAL_ANIMATION->frames.push_back({64,0}); CONSUME_MEAL_ANIMATION->skip_frames=nodeAnimationSkipFrames; NADO_ANIMATION->spr=NADO_DECAL; for (int i=0;i<8;i++) { NADO_ANIMATION->frames.push_back({i*32,0}); } CONSUME_MEAL_ANIMATION->skip_frames=3; PETAL_STORM_ANIMATION->spr=PETAL_STORM_DECAL; for (int i=0;i<3;i++) { PETAL_STORM_ANIMATION->frames.push_back({i*32,0}); } PETAL_STORM_ANIMATION->skip_frames=nodeAnimationSkipFrames; SLEEP_ANIMATION->spr=SLEEP_DECAL; for (int i=0;i<3;i++) { SLEEP_ANIMATION->frames.push_back({i*32+32,0}); } SLEEP_ANIMATION->skip_frames=15; SLEEP_ANIMATION->height=64; EMPTY_BED_ANIMATION->spr=SLEEP_DECAL; EMPTY_BED_ANIMATION->frames.push_back({0,0}); EMPTY_BED_ANIMATION->skip_frames=1; EMPTY_BED_ANIMATION->height=64; HAILSTORM->playerOwnCount=3; HURRICANE->playerOwnCount=1; METEOR_RAIN->playerOwnCount=5; PETAL_STORM->seedProduction=2; //Produce two seeds. HURRICANE->seedScatter=2; HURRICANE->growSeeds=true; METEOR_STORM->burnTrees=true; METEOR_RAIN->burnTrees=true; METEOR_RAIN->treeBurnChance=0.5; MOVESET_SPIDEY.push_back(SANDSTORM); MOVESET_SPIDEY.push_back(SEED_STORM); MOVESET_SPIDEY.push_back(AVALANCHE); MOVESET_X_X.push_back(LIGHT_STORM); MOVESET_X_X.push_back(SEED_BULLET); MOVESET_X_X.push_back(SEED_OF_LIFE); MOVESET_X_X.push_back(SEED_BULLET); MOVESET_X_X.push_back(SEED_BULLET); MOVESET_X_X.push_back(SEED_BULLET); MOVESET_X_X.push_back(SUMMON_MINIONS); MOVESET_X_X.push_back(SEED_OF_LIFE); MOVESET_X_X.push_back(SEED_BULLET); MOVESET_X_X.push_back(SEED_BULLET); MOVESET_X_X.push_back(SEED_PELLET); MOVESET_XMINION.push_back(SEED_PELLET); MOVESET_XMINION.push_back(SEED_PELLET); MOVESET_XMINION.push_back(SEED_STORM); COLLECTED_ITEMS.push_back({20,5}); COLLECTED_ITEMS.push_back({20,6}); ENCOUNTER_SPIDEY_1.entities.push_back(new Entity(SPIDEY_DECAL,"Spidey",2,3,80,80,MOVESET_SPIDEY)); ENCOUNTER_SPIDEY_1.entities.push_back(new Entity(SPIDEY_DECAL,"Spidey",4,4,80,80,MOVESET_SPIDEY)); ENCOUNTER_SPIDEY_1.entities.push_back(new Entity(SPIDEY_DECAL,"Spidey",6,2,80,80,MOVESET_SPIDEY)); ENCOUNTER_SPIDEY_1.x=79; ENCOUNTER_SPIDEY_1.y=47; ENCOUNTER_SPIDEY_1.playerX=4; ENCOUNTER_SPIDEY_1.playerY=3; ENCOUNTERS.push_back(ENCOUNTER_SPIDEY_1); ENCOUNTER_X_X.entities.push_back(new Entity(X_X_DECAL,"X_X",3,2.5,590,590,MOVESET_X_X,{2,2},true)); ENCOUNTER_X_X.entities.push_back(new Entity(X_X_DECAL,"X Minion",1,4,0,80,MOVESET_XMINION,{0.7,0.7})); ENCOUNTER_X_X.entities.push_back(new Entity(X_X_DECAL,"X Minion",0,2,0,80,MOVESET_XMINION,{0.7,0.7})); ENCOUNTER_X_X.entities.push_back(new Entity(X_X_DECAL,"X Minion",4,2,0,80,MOVESET_XMINION,{0.7,0.7})); ENCOUNTER_X_X.x=38; ENCOUNTER_X_X.y=35; ENCOUNTER_X_X.playerX=3; ENCOUNTER_X_X.playerY=2; //ENCOUNTERS.push_back(ENCOUNTER_X_X); //Activate at beginning of Chapter 2. 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); BASE_OBJECTS["PETALSTORM_NODE"]=new ObjectLoadInfo(PETAL_STORM_DECAL,PETAL_STORM_ANIMATION); BASE_OBJECTS["COMPUTER"]=new ObjectLoadInfo(COMPUTER_DECAL); BASE_OBJECTS["BROKEN_ROVER"]=new ObjectLoadInfo(BROKEN_ROVER_DECAL); BASE_OBJECTS["NADO"]=new ObjectLoadInfo(NADO_DECAL,NADO_ANIMATION,Pixel(153, 137, 75,230)); BASE_OBJECTS["SILICON_PIECE"]=new ObjectLoadInfo(SILICON_ROCK_DECAL); Zone*SILICON_DEPOSIT_ZONE = new Zone({109,7},{26,9},{0,0},{WIDTH,HEIGHT},{0,0},{WIDTH,HEIGHT},{1,1},{3,3},{-30,-3},{30,3},Pixel(133, 98, 66,180),Pixel(220, 120, 90,230),300,Pixel(87, 78, 69,64)); ZONES.push_back(SILICON_DEPOSIT_ZONE); for (int i=0;i=CONSOLE_REF_TEXT.length()) { fadeOut(); } }break; case CUTSCENE_4:{ if (textInd>=CONSOLE_REF_TEXT.length()) { GAME_STATE=CUTSCENE_4_DONE; fadeOut(); } }break; } } void ActionButtonPress() { if (playerCanMove()) { 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 "<playerOwnCount>0) { BATTLE_STATE=battle::PLAYER_TARGET_SELECTION; if (!(BATTLE_CARD_SELECTION->name.compare("Meal")==0||BATTLE_CARD_SELECTION->name.compare("Snack")==0)) { if (PLAYER_SELECTED_TARGET==-1||CURRENT_ENCOUNTER.entities[PLAYER_SELECTED_TARGET]->hp<=0) { for (int i=0;ially&&ent->hp>0) { PLAYER_SELECTED_TARGET=i; break; } } } } else { PLAYER_SELECTED_TARGET=-2; setupBattleTurns(); } } }break; case battle::PLAYER_TARGET_SELECTION:{ setupBattleTurns(); }break; } switch (CURRENT_CUTSCENE) { case cutscene::NODE_COLLECT_CUTSCENE:{ EndCutscene(); }break; case cutscene::INPUT_USERNAME:{ if (TERMINAL_SELECTED_CHAR<26&&TERMINAL_INPUT.length()0) { TERMINAL_INPUT.erase(TERMINAL_INPUT.length()-1); } else if (TERMINAL_SELECTED_CHAR==27&&TERMINAL_INPUT.length()>0) { PLAYER_NAME=TERMINAL_INPUT; PlayCutscene(cutscene::GO_OUTSIDE); } }break; } } bool OnUserUpdate(float fElapsedTime) override { elapsedTime+=fElapsedTime; while (elapsedTime>TARGET_RATE) { elapsedTime-=TARGET_RATE; updateGame(); rand(); } if (GetKey(F1).bPressed) { ConsoleShow(F1,false); } if (playerCanMove()) { 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); } } } else if (IN_BATTLE_ENCOUNTER) { switch (BATTLE_STATE) { case battle::PLAYER_SELECTION:{ if (GetKey(D).bPressed||GetKey(RIGHT).bPressed||GetKey(NP6).bPressed) { BATTLE_CARD_SELECTION_IND=(BATTLE_CARD_SELECTION_IND+1)%availablePowers.size(); BATTLE_CARD_SELECTION=availablePowers[BATTLE_CARD_SELECTION_IND]; } if (GetKey(A).bPressed||GetKey(LEFT).bPressed||GetKey(NP4).bPressed) { if (--BATTLE_CARD_SELECTION_IND<0) { BATTLE_CARD_SELECTION_IND=availablePowers.size()-1; } BATTLE_CARD_SELECTION=availablePowers[BATTLE_CARD_SELECTION_IND]; } }break; case battle::PLAYER_TARGET_SELECTION:{ if (GetKey(D).bPressed||GetKey(RIGHT).bPressed||GetKey(NP6).bPressed) { while (true) { PLAYER_SELECTED_TARGET=(PLAYER_SELECTED_TARGET+1)%CURRENT_ENCOUNTER.entities.size(); if (CURRENT_ENCOUNTER.entities[PLAYER_SELECTED_TARGET]->hp>0) { break; } } } if (GetKey(W).bPressed||GetKey(UP).bPressed||GetKey(NP8).bPressed) { PLAYER_SELECTED_TARGET=-1; BATTLE_STATE=battle::PLAYER_SELECTION; } if (GetKey(A).bPressed||GetKey(LEFT).bPressed||GetKey(NP4).bPressed) { while (true) { if (--PLAYER_SELECTED_TARGET<0) { PLAYER_SELECTED_TARGET=CURRENT_ENCOUNTER.entities.size()-1; } if (CURRENT_ENCOUNTER.entities[PLAYER_SELECTED_TARGET]->hp>0) { break; } } } }break; } } else { if (GAME_STATE==CUTSCENE_3) { if (GetKey(A).bPressed||GetKey(LEFT).bPressed||GetKey(NP4).bPressed|GetKey(W).bPressed||GetKey(UP).bPressed||GetKey(NP8).bPressed) { MAIN_MENU_SELECTION--; if (MAIN_MENU_SELECTION<0) { MAIN_MENU_SELECTION=3; } } if (GetKey(D).bPressed||GetKey(RIGHT).bPressed||GetKey(NP6).bPressed||GetKey(S).bPressed||GetKey(DOWN).bPressed||GetKey(NP5).bPressed||GetKey(NP2).bPressed) { MAIN_MENU_SELECTION=(MAIN_MENU_SELECTION+1)%4; } } switch (CURRENT_CUTSCENE) { case cutscene::INPUT_USERNAME:{ if (GetKey(W).bPressed||GetKey(UP).bPressed||GetKey(NP8).bPressed) { TERMINAL_SELECTED_CHAR=TERMINAL_SELECTED_CHAR-7; if (TERMINAL_SELECTED_CHAR<0) { TERMINAL_SELECTED_CHAR+=28; } } if (GetKey(D).bPressed||GetKey(RIGHT).bPressed||GetKey(NP6).bPressed) { if ((TERMINAL_SELECTED_CHAR+1)%7==0) { TERMINAL_SELECTED_CHAR-=6; } else { TERMINAL_SELECTED_CHAR++; } } if (GetKey(A).bPressed||GetKey(LEFT).bPressed||GetKey(NP4).bPressed) { if ((TERMINAL_SELECTED_CHAR-1)%7==6||TERMINAL_SELECTED_CHAR-1<0) { TERMINAL_SELECTED_CHAR+=6; } else { TERMINAL_SELECTED_CHAR--; } } if (GetKey(S).bPressed||GetKey(DOWN).bPressed||GetKey(NP5).bPressed||GetKey(NP2).bPressed) { if (TERMINAL_SELECTED_CHAR+7>=28) { TERMINAL_SELECTED_CHAR=(TERMINAL_SELECTED_CHAR+7)%28; } else { TERMINAL_SELECTED_CHAR+=7; } } }break; } } SetDrawTarget(nullptr); Clear(BLANK); SetDrawTarget(1); Clear(BLANK); SetDrawTarget(2); drawGame(); // called once per frame return !END_THE_GAME; } 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; case CUTSCENE_3:{ GAME_STATE=CUTSCENE_1; fadeIn(); ResetTerminal(STORY_TEXT1); }break; case CUTSCENE_4:{ fadeIn(); }break; case CUTSCENE_4_DONE:{ GAME_STATE=GAMEWORLD; PlayCutscene(cutscene::GET_SOME_REST); fadeIn(); }break; case LATER_THAT_NIGHTFADEIN:{ fadeIn(); }break; case LATER_THAT_NIGHTFADEOUT:{ fadeIn(); GAME_STATE=GAMEWORLD; PlayCutscene(cutscene::IN_BED); PLAYER_HP=PLAYER_MAXHP; }break; } switch (CURRENT_CUTSCENE) { case cutscene::TRANSITION_CUTSCENE:{ LoadMap("assets/maps/map1"); PLAYER_COORDS[0]=40.5; PLAYER_COORDS[1]=37.5; fadeIn(); EndCutscene(); if (!GAME_FLAGS[gameflag::VISIT_BROKEN_ROVER]) { GAME_FLAGS[gameflag::VISIT_BROKEN_ROVER]=true; PlayCutscene(cutscene::WALK_TO_ROVER); } }break; case cutscene::TRANSITION_CUTSCENE_2:{ if (GAME_FLAGS[gameflag::REST_IN_DOME]&&!GAME_FLAGS[gameflag::SLEEP]) { for (int i=0;iflipped=true; }break; case cutscene::REPAIR_ROVER_1:{ CUTSCENE_OBJS[0]=CreateObject({PLAYER_COORDS[0],PLAYER_COORDS[1]},PLAYER_DECAL,{64,0},{32,32},true); }break; case cutscene::GET_SOME_REST:{ DisplayMessageBox(18); }break; case cutscene::IN_BED:{ CUTSCENE_OBJS[0]=CreateObject({20,2},SLEEP_DECAL,SLEEP_ANIMATION,true); }break; case cutscene::INVESTIGATE_X_X:{ CUTSCENE_OBJS[0]->anim=EMPTY_BED_ANIMATION; CUTSCENE_OBJS[1]=CreateObject({19,3},PLAYER_DECAL,{32,0},{32,32},true); CUTSCENE_OBJS[1]->flipped=true; DisplayMessageBox(20); }break; } for (int i=0;i<8;i++) { CUTSCENE_FLAGS[i]=false; } CUTSCENE_TIMER=0; } void updateGame(){ frameCount++; TIMER++; if (CURRENT_CUTSCENE!=cutscene::NONE) { CUTSCENE_TIMER++; } if (audioFade&&audioLevel>0) { audioLevel-=0.01; engine.SetOutputVolume(audioLevel); } else if (!audioFade&&audioLevel<0.6) { audioLevel+=0.01; engine.SetOutputVolume(audioLevel); } 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 (messageBoxCursorskip_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 (!IN_BATTLE_ENCOUNTER) { bool zoneEffectActive=false; for (int i=0;i=z->pos.x&&PLAYER_COORDS[0]<=z->pos.x+z->size.x&& PLAYER_COORDS[1]>=z->pos.y&&PLAYER_COORDS[1]<=z->pos.y+z->size.y) { if (ACTIVE_ZONE==nullptr) { applyPixelEffect(z->eff,{PLAYER_COORDS[0],PLAYER_COORDS[1]},0.9); ACTIVE_ZONE=z; } zoneEffectActive=true; } } if (!zoneEffectActive&&ACTIVE_ZONE!=nullptr) { clearPixelEffect(); ACTIVE_ZONE=nullptr; } } if (playerCanMove()) { bool animationchanged=false; bool positionModified=false; if (GetKey(D).bHeld||GetKey(RIGHT).bHeld||GetKey(NP6).bHeld) { if (MAP[(int)PLAYER_COORDS[1]][(int)std::clamp(PLAYER_COORDS[0]+MOVE_SPD,0.1,(double)MAP_WIDTH)]!=4) { PLAYER_COORDS[0]=std::clamp(PLAYER_COORDS[0]+MOVE_SPD,0.1,(double)MAP_WIDTH); positionModified=true; } //ConsoleClear(); //cout<<"("<name.compare("HAILSTORM_NODE")==0&&collidesWithPlayer(obj)) { int amountGained=rand()%4+2; HAILSTORM->playerOwnCount+=amountGained; std::cout<<"Increased HAILSTORM power inventory count by "<x,(int)obj->y}); OBJECTS.erase(OBJECTS.begin()+i--); delete obj; performCropUpdate(8); displayPowerInfo(HAILSTORM); } 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 "<x,(int)obj->y}); OBJECTS.erase(OBJECTS.begin()+i--); delete obj; performCropUpdate(8); displayPowerInfo(HURRICANE); } else if (obj->name.compare("METEORSHOWER_NODE")==0&&collidesWithPlayer(obj)) { int amountGained=rand()%4+2; METEOR_RAIN->playerOwnCount+=amountGained; std::cout<<"Increased METEORSHOWER power inventory count by "<x,(int)obj->y}); OBJECTS.erase(OBJECTS.begin()+i--); delete obj; performCropUpdate(8); displayPowerInfo(METEOR_RAIN); } 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 "<x,(int)obj->y}); OBJECTS.erase(OBJECTS.begin()+i--); delete obj; performCropUpdate(8); displayPowerInfo(METEOR_STORM); } 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 "<x,(int)obj->y}); OBJECTS.erase(OBJECTS.begin()+i--); delete obj; performCropUpdate(8); displayPowerInfo(SNOWSTORM); } else if (obj->name.compare("PETALSTORM_NODE")==0&&collidesWithPlayer(obj)) { int amountGained=rand()%4+2; PETAL_STORM->playerOwnCount+=amountGained; std::cout<<"Increased PETALSTORM power inventory count by "<x,(int)obj->y}); OBJECTS.erase(OBJECTS.begin()+i--); delete obj; performCropUpdate(8); displayPowerInfo(PETAL_STORM); } else if (obj->name.compare("SILICON_PIECE")==0&&collidesWithPlayer(obj)) { GAME_STATE=COLLECTED_SILICON; DisplayMessageBox(14); COLLECTED_ITEMS.push_back({(int)obj->x,(int)obj->y}); OBJECTS.erase(OBJECTS.begin()+i--); delete obj; } else if (obj->name.compare("EXIT")==0&&collidesWithPlayer(obj)) { fadeOut(); PlayCutscene(cutscene::TRANSITION_CUTSCENE); } else if (obj->name.compare("DOME")==0&&collidesWithPlayer(obj)) { fadeOut(); PlayCutscene(cutscene::TRANSITION_CUTSCENE_2); } } } if (!IN_BATTLE_ENCOUNTER&&MAP_NAME.compare("assets/maps/map1")==0) { for (int i=0;iname.compare("Snack")==0||WEATHER_POWERS[i]->name.compare("Meal")==0) { WEATHER_POWERS[i]->playerOwnCount=foodCount; } } availablePowers.erase(availablePowers.begin(),availablePowers.end()); IN_BATTLE_ENCOUNTER=true; CURRENT_ENCOUNTER=enc; CURRENT_ENCOUNTER_IND=i; BATTLE_ENTRY_TIMER=0; BATTLE_STATE=battle::WAITING_FOR_CAMERA; for (int i=0;iplayerOwnCount>0) { availablePowers.push_back(WEATHER_POWERS[i]); } } BATTLE_PLAYER_COORDS={PLAYER_COORDS[0],PLAYER_COORDS[1]}; BATTLE_CARD_SELECTION_IND=0; BATTLE_CARD_SELECTION=availablePowers[BATTLE_CARD_SELECTION_IND]; PLAYER_SELECTED_TARGET=-1; } } } for (int i=0;iframe>60) { BATTLE_DISPLAY_NUMBERS.erase(BATTLE_DISPLAY_NUMBERS.begin()+i--); delete numb; } else { numb->y-=0.01; numb->alpha-=4; } } if (IN_BATTLE_ENCOUNTER&&!messageBoxVisible) { 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_PLAYER_COORDS.x==CURRENT_ENCOUNTER.x+CURRENT_ENCOUNTER.playerX&&BATTLE_PLAYER_COORDS.y==CURRENT_ENCOUNTER.y+CURRENT_ENCOUNTER.playerY) { if (!GAME_FLAGS[gameflag::FIRST_ENCOUNTER_X_X]&&GAME_FLAGS[gameflag::SLEEP]) { GAME_FLAGS[gameflag::FIRST_ENCOUNTER_X_X]=true; DisplayMessageBox(22); break; } BATTLE_STATE = battle::PLAYER_SELECTION; clearPixelEffect(); EFFECT_TIMER = 0; } if (PLAYER_COORDS[0]!=TARGET_COORDS_X) { 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_Y) { PLAYER_COORDS[1]=TARGET_COORDS_Y; } } else { PLAYER_COORDS[1]-=BATTLE_CAMERA_SCROLL_SPD; if (PLAYER_COORDS[1]CURRENT_ENCOUNTER.x+CURRENT_ENCOUNTER.playerX) { BATTLE_PLAYER_COORDS.x=CURRENT_ENCOUNTER.x+CURRENT_ENCOUNTER.playerX; } } else { BATTLE_PLAYER_COORDS.x-=BATTLE_CAMERA_SCROLL_SPD; if (BATTLE_PLAYER_COORDS.xCURRENT_ENCOUNTER.y+CURRENT_ENCOUNTER.playerY) { BATTLE_PLAYER_COORDS.y=CURRENT_ENCOUNTER.y+CURRENT_ENCOUNTER.playerY; } } else { BATTLE_PLAYER_COORDS.y-=BATTLE_CAMERA_SCROLL_SPD; if (BATTLE_PLAYER_COORDS.yx),(float)(CURRENT_ENCOUNTER.y+CURRENT_ENCOUNTER.entities[PLAYER_SELECTED_TARGET]->y)},0); } } else { if (CURRENT_ENCOUNTER.entities[BATTLE_CURRENT_TURN_ENTITY]->selectedMove->damage<0) { applyPixelEffect(CURRENT_ENCOUNTER.entities[BATTLE_CURRENT_TURN_ENTITY]->selectedMove,{(float)CURRENT_ENCOUNTER.x+CURRENT_ENCOUNTER.entities[BATTLE_CURRENT_TURN_ENTITY]->x,(float)CURRENT_ENCOUNTER.y+CURRENT_ENCOUNTER.entities[BATTLE_CURRENT_TURN_ENTITY]->y},0); } else { applyPixelEffect(CURRENT_ENCOUNTER.entities[BATTLE_CURRENT_TURN_ENTITY]->selectedMove,{CURRENT_ENCOUNTER.x+CURRENT_ENCOUNTER.playerX,CURRENT_ENCOUNTER.y+CURRENT_ENCOUNTER.playerY},0); } } } EFFECT_TIMER++; WEATHER_POWER*ref; if (BATTLE_CURRENT_TURN_ENTITY==-1) { ref=BATTLE_CARD_SELECTION; } else { ref=CURRENT_ENCOUNTER.entities[BATTLE_CURRENT_TURN_ENTITY]->selectedMove; } PIXEL_EFFECT_TRANSPARENCY=(0.5*cos(((M_PI/(30.0*(ref->effectTime/120.0)))/2)*EFFECT_TIMER-M_PI)+0.5); if (EFFECT_TIMER==30&&ref->name.compare("Petal Storm")==0) { int healPower=30; int healRoll=healPower+rand()%ref->damageRoll*sign(healPower); if (BATTLE_CURRENT_TURN_ENTITY==-1) { effectRadius({(int)BATTLE_PLAYER_COORDS.x,(int)BATTLE_PLAYER_COORDS.y},ref,-healRoll,true); } else { effectRadius({CURRENT_ENCOUNTER.entities[BATTLE_CURRENT_TURN_ENTITY]->x+CURRENT_ENCOUNTER.x,CURRENT_ENCOUNTER.entities[BATTLE_CURRENT_TURN_ENTITY]->y+CURRENT_ENCOUNTER.y},ref,-healRoll,false); } } if (EFFECT_TIMER==30&&ref->name.compare("Seed Storm")==0) { if (BATTLE_CURRENT_TURN_ENTITY==-1) { effectRadius({(int)BATTLE_PLAYER_COORDS.x,(int)BATTLE_PLAYER_COORDS.y},ref,true); } else { effectRadius({CURRENT_ENCOUNTER.entities[BATTLE_CURRENT_TURN_ENTITY]->x+CURRENT_ENCOUNTER.x,CURRENT_ENCOUNTER.entities[BATTLE_CURRENT_TURN_ENTITY]->y+CURRENT_ENCOUNTER.y},ref,false); } } else if (EFFECT_TIMER==ref->effectTime-10){ if (BATTLE_CURRENT_TURN_ENTITY==-1) { if (FOOD_REGEN_TURNS>0) { FOOD_REGEN_TURNS--; PLAYER_HP=std::clamp(PLAYER_HP+(int)(PLAYER_MAXHP*0.33),0,PLAYER_MAXHP); CreateDisplayNumber((int)(-PLAYER_MAXHP*0.33),CURRENT_ENCOUNTER.x+CURRENT_ENCOUNTER.playerX,CURRENT_ENCOUNTER.y+CURRENT_ENCOUNTER.playerY,frameCount); } if (PLAYER_SELECTED_TARGET==-2) { effectRadius({CURRENT_ENCOUNTER.x+CURRENT_ENCOUNTER.playerX,CURRENT_ENCOUNTER.y+CURRENT_ENCOUNTER.playerY},ref,true); } else { effectRadius({CURRENT_ENCOUNTER.entities[PLAYER_SELECTED_TARGET]->x+CURRENT_ENCOUNTER.x,CURRENT_ENCOUNTER.entities[PLAYER_SELECTED_TARGET]->y+CURRENT_ENCOUNTER.y},ref,true); } } else { effectRadius({CURRENT_ENCOUNTER.x+CURRENT_ENCOUNTER.playerX,CURRENT_ENCOUNTER.y+CURRENT_ENCOUNTER.playerY},ref,false); if (ref==LIGHT_STORM&&CURRENT_ENCOUNTER.entities[BATTLE_CURRENT_TURN_ENTITY]->name.compare("X_X")==0) { CURRENT_ENCOUNTER.entities[BATTLE_CURRENT_TURN_ENTITY]->spr=X_X_UNCHARGED_DECAL; } else if (ref==SEED_PELLET&&CURRENT_ENCOUNTER.entities[BATTLE_CURRENT_TURN_ENTITY]->name.compare("X_X")==0) { CURRENT_ENCOUNTER.entities[BATTLE_CURRENT_TURN_ENTITY]->spr=X_X_DECAL; } } } else if (EFFECT_TIMER==ref->effectTime/2){ addSeeds(ref->seedProduction); int newSeedCount=SEEDS.size()*ref->seedScatter; while (SEEDS.size()ref->effectTime) { EFFECT_TIMER=0; clearPixelEffect(); if (ref->growSeeds&&SEEDS.size()>0) { BATTLE_REASON_CODE=reasoncode::SEED_GROWTH; BATTLE_STATE=battle::WAIT_TURN_ANIMATION2; } else if (ref->burnTrees&&TREES.size()>0&&ref->treeBurnChance>range(0,1)){ BATTLE_REASON_CODE=reasoncode::TREE_BURN; BATTLE_STATE=battle::WAIT_TURN_ANIMATION2; } else { BATTLE_REASON_CODE=-1; BATTLE_STATE=battle::DAMAGE_RESOLUTION; } } }break; case battle::WAIT_TURN_ANIMATION2:{ EFFECT_TIMER++; if (EFFECT_TIMER==10) { switch (BATTLE_REASON_CODE) { case reasoncode::SEED_GROWTH:{ applyPixelEffect(SEED_STORM,BATTLE_PLAYER_COORDS,0); }break; case reasoncode::TREE_BURN:{ applyPixelEffect(FIRESTORM_EFF,BATTLE_PLAYER_COORDS,0); }break; } } if (EFFECT_TIMER==60) { switch (BATTLE_REASON_CODE) { case reasoncode::SEED_GROWTH:{ int healAmt=-10*SEEDS.size(); CreateDisplayNumber(healAmt,BATTLE_PLAYER_COORDS.x,BATTLE_PLAYER_COORDS.y,frameCount); PLAYER_HP=std::clamp(PLAYER_HP+healAmt*-1,0,PLAYER_MAXHP); addTrees(SEEDS.size()); clearSeeds(); }break; case reasoncode::TREE_BURN:{ int dmgAmt=10*TREES.size(); for (int i=0;ihp>0) { CreateDisplayNumber(dmgAmt,CURRENT_ENCOUNTER.x+CURRENT_ENCOUNTER.entities[i]->x+CURRENT_ENCOUNTER.entities[i]->spr->sprite->width*CURRENT_ENCOUNTER.entities[i]->sprScale.x/2/32,CURRENT_ENCOUNTER.y+CURRENT_ENCOUNTER.entities[i]->y+CURRENT_ENCOUNTER.entities[i]->spr->sprite->height*CURRENT_ENCOUNTER.entities[i]->sprScale.y/2/32,frameCount); CURRENT_ENCOUNTER.entities[i]->hp=std::clamp(CURRENT_ENCOUNTER.entities[i]->hp-dmgAmt,0,CURRENT_ENCOUNTER.entities[i]->maxhp); } } clearTrees(); }break; } } if (EFFECT_TIMER==120) { EFFECT_TIMER=0; clearPixelEffect(); BATTLE_REASON_CODE=-1; BATTLE_STATE=battle::DAMAGE_RESOLUTION; } }break; case battle::DAMAGE_RESOLUTION:{ EFFECT_TIMER++; if (EFFECT_TIMER>60) { if (turnOrder.empty()) { bool allDead=true; for (auto&ent:CURRENT_ENCOUNTER.entities) { if (ent->hp>0) { allDead=false; break; } } if (allDead) { IN_BATTLE_ENCOUNTER=false; ENCOUNTERS.erase(ENCOUNTERS.begin()+CURRENT_ENCOUNTER_IND); BATTLE_CARD_SELECTION_IND=0; PLAYER_SELECTED_TARGET=-1; BATTLE_STATE=battle::NONE; PLAYER_COORDS[0]=BATTLE_PLAYER_COORDS.x; PLAYER_COORDS[1]=BATTLE_PLAYER_COORDS.y; clearSeeds(); clearTrees(); performCropUpdate(8); if (FOOD_REGEN_TURNS>0) { FOOD_REGEN_TURNS=0; foodCount++; } } else { if (!GAME_FLAGS[gameflag::ANALYSIS_X_X]&&GAME_FLAGS[gameflag::FIRST_ENCOUNTER_X_X]) { GAME_FLAGS[gameflag::ANALYSIS_X_X]=true; DisplayMessageBox(23); break; } BATTLE_STATE=battle::PLAYER_SELECTION; PLAYER_SELECTED_TARGET=-1; } } else { BATTLE_CURRENT_TURN_ENTITY=turnOrder.front(); turnOrder.pop(); if (BATTLE_CURRENT_TURN_ENTITY==-1) { if (PLAYER_HP<=0) { GAME_STATE=GAME_OVER; break; } } else { if (CURRENT_ENCOUNTER.entities[BATTLE_CURRENT_TURN_ENTITY]->hp<=0) { break; } } BATTLE_STATE=battle::WAIT_TURN_ANIMATION; PIXEL_EFFECT_TRANSPARENCY=0; EFFECT_TIMER=0; for (int i=0;iname.compare("Snack")==0||WEATHER_POWERS[i]->name.compare("Meal")==0) { WEATHER_POWERS[i]->playerOwnCount=foodCount; } } } } }break; } } switch (CURRENT_CUTSCENE) { case cutscene::CUTSCENE_4:{ if (!messageBoxVisible) { if (!CUTSCENE_FLAGS[0]) { CUTSCENE_OBJS[0]=CreateObject(GetMapFileCoords(8,17),PLAYER_DECAL,{64,0},{32,32},true); CUTSCENE_FLAGS[0]=true; DisplayMessageBox(0); } else if (!CUTSCENE_FLAGS[1]) { CUTSCENE_FLAGS[1]=true; DisplayMessageBox(1); } else { PlayCutscene(cutscene::PAN_OVER_TO_CROPS); } } }break; case cutscene::PAN_OVER_TO_CROPS:{ if (CUTSCENE_OBJS[0]->y>4) { CUTSCENE_OBJS[0]->y-=MOVE_SPD; } else if (CUTSCENE_OBJS[0]->x>13) { CUTSCENE_OBJS[0]->spos={32,0}; CUTSCENE_OBJS[0]->flipped=true; CUTSCENE_OBJS[0]->x-=MOVE_SPD; } if (MoveCameraTowardsPoint(GetMapFileCoords(7,11))) { PlayCutscene(cutscene::RAINING_IN_DOME); } }break; case cutscene::RAINING_IN_DOME:{ if (CUTSCENE_TIMER%60==0) { performCropUpdate(3); } if (CUTSCENE_TIMER>=60*6) { PIXEL_EFFECT_TRANSPARENCY=(60-(CUTSCENE_TIMER-60*6))/60; } if (CUTSCENE_TIMER>=60*7) { PlayCutscene(cutscene::AFTER_RAIN); } }break; case cutscene::AFTER_RAIN:{ if (!messageBoxVisible) { if (!CUTSCENE_FLAGS[0]) { DisplayMessageBox(2); CUTSCENE_FLAGS[0]=true; } else if (!CUTSCENE_FLAGS[1]) { DisplayMessageBox(3); CUTSCENE_FLAGS[1]=true; foodMeterVisible=true; } else { PLAYER_COORDS[0]=13; PLAYER_COORDS[1]=4; changeAnimation(playerAnimLeft); EndCutscene(); } } }break; case cutscene::WALK_TO_COMPUTER:{ if (!messageBoxVisible) { if (!CUTSCENE_FLAGS[0]) { DisplayMessageBox(11); CUTSCENE_FLAGS[0]=true; } else if (!CUTSCENE_FLAGS[1]) { DisplayMessageBox(4); CUTSCENE_FLAGS[1]=true; } else { vi2d targetPos = GetMapFileCoords(19,4); if (CUTSCENE_OBJS[0]->x<19) { CUTSCENE_OBJS[0]->x+=MOVE_SPD; if (CUTSCENE_OBJS[0]->x>19) { CUTSCENE_OBJS[0]->x=19; } } if (CUTSCENE_OBJS[0]->y<4) { CUTSCENE_OBJS[0]->y+=MOVE_SPD; if (CUTSCENE_OBJS[0]->y>4) { CUTSCENE_OBJS[0]->y=4; } } if (CUTSCENE_OBJS[0]->y>4) { CUTSCENE_OBJS[0]->y-=MOVE_SPD; if (CUTSCENE_OBJS[0]->y<4) { CUTSCENE_OBJS[0]->y=4; } } if (MoveCameraTowardsPoint({19,4})) { if (!CUTSCENE_FLAGS[2]) { DisplayMessageBox(5); CUTSCENE_FLAGS[2]=true; } else { PlayCutscene(cutscene::INPUT_USERNAME); } } } } }break; case cutscene::GO_OUTSIDE:{ if (!messageBoxVisible) { if (!CUTSCENE_FLAGS[0]) { CUTSCENE_FLAGS[0]=true; DisplayMessageBox(12); } else if (!CUTSCENE_FLAGS[1]) { CUTSCENE_FLAGS[1]=true; DisplayMessageBox(6); } else { PLAYER_COORDS[0]=19; PLAYER_COORDS[1]=4; EndCutscene(); } } }break; case cutscene::WALK_TO_ROVER:{ if (MoveObjectTowardsPoint({33,36},CUTSCENE_OBJS[0],HORZ_FIRST)) { CUTSCENE_OBJS[0]->spos={64,0}; } if (MoveCameraTowardsPoint({33,36})) { if (!CUTSCENE_FLAGS[0]) { CUTSCENE_FLAGS[0]=true; CUTSCENE_TIMER=0; } if (CUTSCENE_TIMER>60) { if (!messageBoxVisible) { if (!CUTSCENE_FLAGS[3]) { CUTSCENE_FLAGS[3]=true; DisplayMessageBox(13); } else if (!CUTSCENE_FLAGS[1]) { CUTSCENE_FLAGS[1]=true; DisplayMessageBox(7); } else if (!CUTSCENE_FLAGS[2]) { CUTSCENE_FLAGS[2]=true; DisplayMessageBox(8); } else { PlayCutscene(cutscene::DISPLAY_VOLCANIC_AREA); fadeOut(); } } } } }break; case cutscene::DISPLAY_VOLCANIC_AREA:{ if (CUTSCENE_FLAGS[0]&&!messageBoxVisible) { if (!CUTSCENE_FLAGS[1]) { CUTSCENE_FLAGS[1]=true; DisplayMessageBox(9); } else { fadeOut(); PlayCutscene(cutscene::END_VOLCANIC_AREA_CUTSCENE); } } }break; case cutscene::REPAIR_ROVER_1:{ if (!messageBoxVisible) { if (!CUTSCENE_FLAGS[0]) { CUTSCENE_FLAGS[0]=true; DisplayMessageBox(16); } else if (!CUTSCENE_FLAGS[1]) { CUTSCENE_FLAGS[1]=true; CUTSCENE_TIMER=0; } else if (!CUTSCENE_FLAGS[4]&&CUTSCENE_TIMER>60) { for (int i=0;ix==33&&OBJECTS[i]->y==35) { OBJECTS[i]->spr=ROVER_DECAL; CUTSCENE_FLAGS[4]=true; break; } } } else if (!CUTSCENE_FLAGS[2]&&CUTSCENE_TIMER>120) { DisplayMessageBox(17); CUTSCENE_FLAGS[2]=true; } else if (!CUTSCENE_FLAGS[3]&&CUTSCENE_TIMER>120) { fadeOut(); CUTSCENE_FLAGS[3]=true; } } }break; case cutscene::GET_SOME_REST:{ if (!messageBoxVisible) { if (!CUTSCENE_FLAGS[0]) { CUTSCENE_FLAGS[0]=true; DisplayMessageBox(19); GAME_FLAGS[gameflag::REST_IN_DOME]=true; } else { EndCutscene(); } } }break; case cutscene::IN_BED:{ if (!CUTSCENE_FLAGS[0]&&MoveCameraTowardsPoint({CUTSCENE_OBJS[0]->x,CUTSCENE_OBJS[0]->y})) { CUTSCENE_FLAGS[0]=true; CUTSCENE_TIMER=0; } else if (CUTSCENE_FLAGS[0]&&!CUTSCENE_FLAGS[1]&&CUTSCENE_TIMER>60*4) { StartCutscene(cutscene::SHAKE); } }break; case cutscene::SHAKE:{ if (CUTSCENE_TIMER<60*4) { if (frameCount%4==0) { PLAYER_COORDS[1]+=0.25; } else if (frameCount%4==1) { PLAYER_COORDS[1]+=0.25; } else if (frameCount%4==2) { PLAYER_COORDS[1]-=0.25; } else if (frameCount%4==3) { PLAYER_COORDS[1]-=0.25; } } else { StartCutscene(cutscene::INVESTIGATE_X_X); } }break; case cutscene::INVESTIGATE_X_X:{ if (!messageBoxVisible) { if (!CUTSCENE_FLAGS[0]) { CUTSCENE_FLAGS[0]=true; DisplayMessageBox(21); } else { PLAYER_COORDS[0]=CUTSCENE_OBJS[1]->x; PLAYER_COORDS[1]=CUTSCENE_OBJS[1]->y; EndCutscene(); ENCOUNTERS.push_back(ENCOUNTER_X_X); } } }break; } if (GAME_STATE==CUTSCENE_3&&!SOUND_IS_PLAYING) { engine.SetOutputVolume(0.6); engine.PlayWaveform(&SONG_MAIN,true); SOUND_IS_PLAYING=true; } switch (GAME_STATE) { case CUTSCENE_1: case CUTSCENE_3: case CUTSCENE_4:{ switch (GAME_STATE) { case CUTSCENE_1:{ CONSOLE_REF_TEXT=STORY_TEXT1; }break; case CUTSCENE_3:{ CONSOLE_REF_TEXT=STORY_TEXT2; }break; case CUTSCENE_4:{ CONSOLE_REF_TEXT=STORY_TEXT3; }break; } if (GAME_STATE==CUTSCENE_3&&frameCount%4!=0) {break;} if (textIndWIDTH-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 (tempIndex120) { 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; case COLLECTED_SILICON:{ if (!messageBoxVisible) { if (!GAME_FLAGS[gameflag::COLLECTED_SILICON_1]) { GAME_FLAGS[gameflag::COLLECTED_SILICON_1]=true; DisplayMessageBox(15); } else { GAME_STATE=GAMEWORLD; } } }break; case LATER_THAT_NIGHTWAIT:{ if (TIMER>180) { fadeOut(); GAME_STATE=LATER_THAT_NIGHTFADEOUT; } }break; } if (PIXEL_EFFECT_TRANSPARENCY>0) { for (int i=0;ipos+=pixels[i]->spd; if (pixels[i]->pos.xpos.x=PIXEL_POS.x+PIXEL_SIZE.x; } if (pixels[i]->pos.x>PIXEL_POS.x+PIXEL_SIZE.x) { pixels[i]->pos.x=PIXEL_POS.x; } if (pixels[i]->pos.ypos.y=PIXEL_POS.y+PIXEL_SIZE.y; } if (pixels[i]->pos.y>PIXEL_POS.y+PIXEL_SIZE.y) { pixels[i]->pos.y=PIXEL_POS.y; } pixels[i]->a=pixels[i]->o_a*PIXEL_EFFECT_TRANSPARENCY; } } } 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 (tempIndex3&&PLAYER_COORDS[0]>12) { GAME_FLAGS[gameflag::TUTORIAL_WALKED_OFF_FARM]=true; PlayCutscene(cutscene::WALK_TO_COMPUTER); CUTSCENE_OBJS[0]=CreateObject({PLAYER_COORDS[0],PLAYER_COORDS[1]},PLAYER_DECAL,{32,0},{32,32},true); } else if (!GAME_FLAGS[gameflag::REPAIRED_ROVER_1]&&GAME_FLAGS[gameflag::COLLECTED_SILICON_1]&&PLAYER_COORDS[0]>=31&&PLAYER_COORDS[0]<=35&&PLAYER_COORDS[1]>=33&&PLAYER_COORDS[1]<=37) { GAME_FLAGS[gameflag::REPAIRED_ROVER_1]=true; PlayCutscene(cutscene::REPAIR_ROVER_1); } } void drawGame(){ switch (GAME_STATE) { case CUTSCENE_1: case CUTSCENE_4:{ DrawStringDecal({16,16},CUTSCENE_CONSOLE_TEXT,GREEN,{1,1}); if (textIndflipped?32:0)),(float)((BATTLE_PLAYER_COORDS.y-PLAYER_COORDS[1])*32+HEIGHT/2-16)},current_playerAnim->spr,current_playerAnim->getCurrentFrame(),{32,32},{(float)(current_playerAnim->flipped?-1:1),1}); } else { DrawPartialDecal({(float)(WIDTH/2-16+(current_playerAnim->flipped?32:0)),(float)(HEIGHT/2-16)},current_playerAnim->spr,current_playerAnim->getCurrentFrame(),{32,32},{(float)(current_playerAnim->flipped?-1:1),1}); } if (IN_BATTLE_ENCOUNTER&&BATTLE_ENTRY_TIMER<45) { DrawStringDecal({(float)((BATTLE_PLAYER_COORDS.x-PLAYER_COORDS[0])*32+WIDTH/2-16+(current_playerAnim->flipped?32:0)),(float)((BATTLE_PLAYER_COORDS.y-PLAYER_COORDS[1])*32+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 (textIndsprite->width/2),(float)(HEIGHT/2-LATER_THAT_NIGHT_DECAL->sprite->height/2)},LATER_THAT_NIGHT_DECAL); }break; } switch (BATTLE_STATE) { case battle::PLAYER_SELECTION:{ SetDrawTarget(nullptr); DrawCard(availablePowers[(BATTLE_CARD_SELECTION_IND+1)%availablePowers.size()],{WIDTH-96,32},{0.7,0.7},0.4); DrawCard(availablePowers[(BATTLE_CARD_SELECTION_IND-1<0)?availablePowers.size()-1:BATTLE_CARD_SELECTION_IND-1],{-96,32},{0.7,0.7},0.4); DrawCard(BATTLE_CARD_SELECTION); }break; case battle::PLAYER_TARGET_SELECTION:{ if (PLAYER_SELECTED_TARGET>=0) { DrawWrappedText({5,5},"Use "+BATTLE_CARD_SELECTION->name+" on "+CURRENT_ENCOUNTER.entities[PLAYER_SELECTED_TARGET]->name+" "+(char)('A'+PLAYER_SELECTED_TARGET),WIDTH-8,BLACK,{2,2}); DrawWrappedText({4,4},"Use "+BATTLE_CARD_SELECTION->name+" on "+CURRENT_ENCOUNTER.entities[PLAYER_SELECTED_TARGET]->name+" "+(char)('A'+PLAYER_SELECTED_TARGET),WIDTH-8,WHITE,{2,2}); DrawStringDecal({(float)(WIDTH-GetTextSize(" Back").x-1),(float)(HEIGHT-GetTextSize(" Back").y-1)}," Back",BLACK,{1,1}); DrawStringDecal({(float)(WIDTH-GetTextSize(" Back").x-2),(float)(HEIGHT-GetTextSize(" Back").y-2)}," Back",GREEN,{1,1}); } }break; case battle::WAIT_TURN_ANIMATION:{ if (BATTLE_CURRENT_TURN_ENTITY==-1) { DrawWrappedText({4,4},"Player uses "+BATTLE_CARD_SELECTION->name,WIDTH-8,WHITE,{2,2}); } else { DrawWrappedText({4,4},CURRENT_ENCOUNTER.entities[BATTLE_CURRENT_TURN_ENTITY]->name+" "+(char)('A'+BATTLE_CURRENT_TURN_ENTITY)+" uses "+CURRENT_ENCOUNTER.entities[BATTLE_CURRENT_TURN_ENTITY]->selectedMove->name,WIDTH-8,WHITE,{2,2}); } }break; case battle::WAIT_TURN_ANIMATION2:{ switch (BATTLE_REASON_CODE) { case reasoncode::SEED_GROWTH:{ DrawWrappedText({5,5},"The seeds grow into lush trees!",WIDTH-8,DARK_GREEN,{2,2}); DrawWrappedText({4,4},"The seeds grow into lush trees!",WIDTH-8,WHITE,{2,2}); }break; case reasoncode::TREE_BURN:{ DrawWrappedText({5,5},"The trees cause rampaging fires!",WIDTH-8,DARK_RED,{2,2}); DrawWrappedText({4,4},"The trees cause rampaging fires!",WIDTH-8,WHITE,{2,2}); }break; } }break; } if (IN_BATTLE_ENCOUNTER||(GAME_STATE==GAMEWORLD&&!CUTSCENE_ACTIVE&&PLAYER_HP!=PLAYER_MAXHP)) { DrawStringDecal({4+1,(float)(HEIGHT-10-GetTextSize("HP:").y+1)},"HP: "+std::to_string(PLAYER_HP),BLACK); DrawStringDecal({4,(float)(HEIGHT-10-GetTextSize("HP:").y)},"HP: "+std::to_string(PLAYER_HP)); DrawHealthbar({2,HEIGHT-10},WIDTH/2,(float)PLAYER_HP/PLAYER_MAXHP,BLACK); for (auto&numb:BATTLE_DISPLAY_NUMBERS) { std::string display=((numb->number>0)?"-"+std::to_string(numb->number):"+"+std::to_string(numb->number*-1)); for (int x=-1;x<=1;x++) { for (int y=-1;y<=1;y++) { if (x!=0&&y!=0) { DrawStringDecal({((numb->x-PLAYER_COORDS[0])*32+WIDTH/2)-GetTextSize(display).x*1.3/2+x-8,((numb->y-PLAYER_COORDS[1])*32+HEIGHT/2)-12-GetTextSize(display).y*1.3/2+y},display,(numb->number>0)?Pixel(255,0,0,numb->alpha):Pixel(0,255,0,numb->alpha),{1.3,1.3}); } } } DrawStringDecal({((numb->x-PLAYER_COORDS[0])*32+WIDTH/2)-GetTextSize(display).x*1.3/2-8,((numb->y-PLAYER_COORDS[1])*32+HEIGHT/2)-12-GetTextSize(display).y*1.3/2},display,Pixel(255,255,255,numb->alpha),{1.3,1.3}); //std::cout<x<<"/"<y<<" "<<(((numb->x-PLAYER_COORDS[0])*32+WIDTH/2)-GetTextSize(display).x/2)<<","<<(((numb->y-PLAYER_COORDS[1])*32+HEIGHT/2)-8-GetTextSize(display).y/2)<<": ("<alpha<<")"<0) { SetDrawTarget(1); for (int i=0;isize.x==1&&pixels[i]->size.y==1) { Draw(pixels[i]->pos,{(uint8_t)(pixels[i]->r),(uint8_t)(pixels[i]->g),(uint8_t)(pixels[i]->b),(uint8_t)(pixels[i]->a)}); } else { FillRectDecal(pixels[i]->pos,pixels[i]->size,{(uint8_t)(pixels[i]->r),(uint8_t)(pixels[i]->g),(uint8_t)(pixels[i]->b),(uint8_t)(pixels[i]->a)}); } } FillRectDecal({0,0},{WIDTH,HEIGHT},Pixel(ORIGINAL_FOREGROUND_EFFECT_COLOR.r,ORIGINAL_FOREGROUND_EFFECT_COLOR.g,ORIGINAL_FOREGROUND_EFFECT_COLOR.b,ORIGINAL_FOREGROUND_EFFECT_COLOR.a*PIXEL_EFFECT_TRANSPARENCY)); SetDrawTarget(2); } if (messageBoxVisible) { SetDrawTarget(nullptr); 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}); } SetDrawTarget(2); } switch (CURRENT_CUTSCENE) { case cutscene::NODE_COLLECT_CUTSCENE:{ FillRectDecal({0,0},{WIDTH,HEIGHT},Pixel(0,0,0,128)); DrawCard(CUTSCENE_DISPLAYED_CARD); }break; case cutscene::INPUT_USERNAME:{ FillRectDecal({0,0},{WIDTH,HEIGHT},Pixel(0,0,0,128)); DrawTerminal(); }break; case cutscene::IN_BED:{ FillRectDecal({0,0},{WIDTH,HEIGHT},Pixel(0,0,0,192)); }break; } 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&&std::rand()%4==0) { tileX++; } while (tileRot<3&&std::rand()%8<5) { tileRot++; } if ((int)(xOffset+x)>=0&&(int)(xOffset+x)=0&&(int)(yOffset+y)spr!=NULL) { if (obj->name.compare("PLANT")==0) { DrawPartialDecal({(float)((obj->x-PLAYER_COORDS[0])*32+WIDTH/2),(float)((obj->y-PLAYER_COORDS[1])*32+HEIGHT/2)},{32,32},obj->spr,{(float)(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({(float)((obj->x-PLAYER_COORDS[0])*32+WIDTH/2-16*(float)sin(frameCount*2/60.0)+16),(float)((obj->y-PLAYER_COORDS[1])*32+HEIGHT/2)},obj->anim->spr,{(float)(obj->anim->getCurrentFrame().x),(float)(obj->anim->getCurrentFrame().y)},{(float)(obj->anim->width),(float)(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?obj->anim->width:0),(obj->y-PLAYER_COORDS[1])*32+HEIGHT/2},obj->anim->spr,{(float)(obj->anim->getCurrentFrame().x),(float)(obj->anim->getCurrentFrame().y)},{(float)(obj->anim->width),(float)(obj->anim->height)},{(float)(obj->anim->flipped?-1:1),1},obj->col); } else if (obj->hascut) { DrawPartialDecal({(obj->x-PLAYER_COORDS[0])*32+WIDTH/2+(obj->flipped?obj->size.x:0),(obj->y-PLAYER_COORDS[1])*32+HEIGHT/2},obj->spr,obj->spos,obj->size,{(float)(obj->flipped?-1:1),1},obj->col); } else { DrawDecal({(obj->x-PLAYER_COORDS[0])*32+WIDTH/2,(obj->y-PLAYER_COORDS[1])*32+HEIGHT/2},obj->spr,{1,1},obj->col); } } } 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)); } } if (IN_BATTLE_ENCOUNTER) { const vi2d CENTER = {(float)((BATTLE_PLAYER_COORDS.x-PLAYER_COORDS[0])*32+WIDTH/2+(current_playerAnim->flipped?32:0)),(float)((BATTLE_PLAYER_COORDS.y-PLAYER_COORDS[1])*32+HEIGHT/2)}; for (int i=0;ipos+CENTER,SEED_DECAL,{0.5,0.5}); } for (int i=0;ipos+CENTER,TREE_DECAL,{1,1}); } } for (auto&enc:ENCOUNTERS) { int targetX=-1,targetY=-1; for (auto&ent:enc.entities) { if (BATTLE_STATE==battle::PLAYER_TARGET_SELECTION&&PLAYER_SELECTED_TARGET>=0&&CURRENT_ENCOUNTER.entities[PLAYER_SELECTED_TARGET]->hp>0&&CURRENT_ENCOUNTER.entities[PLAYER_SELECTED_TARGET]->x==ent->x&&CURRENT_ENCOUNTER.entities[PLAYER_SELECTED_TARGET]->y==ent->y) { DrawDecal({(enc.x+ent->x-PLAYER_COORDS[0])*32+WIDTH/2,(enc.y+ent->y-PLAYER_COORDS[1])*32+HEIGHT/2},TARGETING_CIRCLE,{(float)(ent->spr->sprite->width*ent->sprScale.x/32),(float)(ent->spr->sprite->height*ent->sprScale.y/32)},{255,210,0,255}); DrawDecal({(enc.x+ent->x-PLAYER_COORDS[0])*32+WIDTH/2,(enc.y+ent->y-PLAYER_COORDS[1])*32+HEIGHT/2},ent->spr,ent->sprScale,{(uint8_t)((0.5*(float)sin(frameCount*4/60.0)+0.5)*80+175),(uint8_t)((0.5*(float)sin(frameCount*4/60.0)+0.5)*80+175),(uint8_t)((0.5*(float)sin(frameCount*4/60.0)+0.5)*80+175),255}); targetX=ent->x;targetY=ent->y; } else { if (ent->hp>0) {//Outside battles. DrawDecal({(enc.x+ent->x-PLAYER_COORDS[0])*32+WIDTH/2,(enc.y+ent->y-PLAYER_COORDS[1])*32+HEIGHT/2},ent->spr,ent->sprScale); } } if (ent->hp>0) { DrawHealthbar({(enc.x+ent->x-PLAYER_COORDS[0])*32+WIDTH/2,(enc.y+ent->y-PLAYER_COORDS[1])*32+HEIGHT/2+ent->spr->sprite->height*ent->sprScale.y+2},ent->spr->sprite->width*ent->sprScale.x,(float)ent->hp/ent->maxhp,BLACK); } } if (targetX!=-1&&targetY!=-1) { DrawDecal({(enc.x+targetX-PLAYER_COORDS[0])*32+enc.entities[PLAYER_SELECTED_TARGET]->spr->sprite->width/2*enc.entities[PLAYER_SELECTED_TARGET]->sprScale.x+WIDTH/2-BATTLE_CARD_SELECTION->range,(enc.y+targetY-PLAYER_COORDS[1])*32+enc.entities[PLAYER_SELECTED_TARGET]->spr->sprite->height/2*enc.entities[PLAYER_SELECTED_TARGET]->sprScale.y+HEIGHT/2-BATTLE_CARD_SELECTION->range},TARGETING_RANGE_CIRCLE,{(float)(BATTLE_CARD_SELECTION->range*2/32.0),(float)(BATTLE_CARD_SELECTION->range*2/32.0)},{255,60,0,(uint8_t)((0.5*(float)sin(frameCount*4/60.0)+0.5)*100)}); } } } void DrawHealthbar(vf2d pos,float width,float pct,Pixel col) { GradientFillRectDecal(pos,{width*pct,8},RED,RED,Pixel((1/pct)*255,255*pct,0,255),Pixel((1/pct)*255,255*pct,0,255)); DrawDecal(pos,HEALTHBAR_DECAL,{width/32,1},col); } void DrawTerminal() { const int TERMINAL_WIDTH=7; for (int i=0;i<26;i++) { std::string s(1,(char)('A'+i)); DrawStringDecal({(float)((32*(i%TERMINAL_WIDTH))+16),(float)(16*(i/TERMINAL_WIDTH)+HEIGHT/2)},s); } std::string backspace(1,(char)('<')); DrawStringDecal({(float)((32*(26%TERMINAL_WIDTH))+16),(float)(16*(26/TERMINAL_WIDTH)+HEIGHT/2)},backspace); DrawStringDecal({(float)((32*(27%TERMINAL_WIDTH))+16),(float)(16*(27/TERMINAL_WIDTH)+HEIGHT/2)},"ENTER"); DrawStringDecal({(float)((32*((TERMINAL_SELECTED_CHAR)%TERMINAL_WIDTH))+8),(float)(16*(TERMINAL_SELECTED_CHAR/TERMINAL_WIDTH)+HEIGHT/2)},">"); std::string terminal_name=TERMINAL_INPUT; for (int i=0;i>getPlantId(x+8,y+2)*2&0b11; } //This uses MAP COORDS for determining bit location. The plants are offset by (X+8,Y+2)!! Use getPlantStatusWithAbsoluteCoords() to translate to map coords. int getPlantStatus(int x,int y) { return plantState>>getPlantId(x,y)*2&0b11; } void setPlantStatusWithAbsoluteCoords(int x,int y,char state) { setPlantStatus(x+8,y+2,state); } //This uses MAP COORDS for determining bit location. The plants are offset by (X+8,Y+2)!! Use setPlantStatusWithAbsoluteCoords() to translate to map coords. void setPlantStatus(int x,int y,char state) { int mask=0b11111111111111111111111111111111; mask-=3<>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>x; split2>>y; bool alreadyCollected=false; bool alreadyRepaired=false; for (int i=0;ix=x; obj->y=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) { if (alreadyRepaired) { obj->spr=ROVER_DECAL; } else { obj->spr=BASE_OBJECTS[split3]->spr; } obj->col=BASE_OBJECTS[split3]->col; if (BASE_OBJECTS[split3]->hasanim) { obj->hasAnim=true; obj->anim=BASE_OBJECTS[split3]->anim; } else if (BASE_OBJECTS[split3]->hascut){ obj->hascut=true; obj->spos=BASE_OBJECTS[split3]->spos; obj->size=BASE_OBJECTS[split3]->size; } } 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;yframe=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 DrawWrappedText(vf2d pos,std::string text,int targetWidth,Pixel col,vf2d scale) { std::string wrappedText; int marker=0; while (markertargetWidth) { int tempMarker=marker; while (wrappedText[tempMarker]!=' ') { wrappedText.erase(tempMarker--); } wrappedText.erase(tempMarker++); wrappedText+='\n'; while (tempMarkertargetWidth) { int tempMarker=marker; while (wrappedText[tempMarker]!=' ') { wrappedText.erase(tempMarker--); } wrappedText.erase(tempMarker++); wrappedText+='\n'; while (tempMarkerplayerOwnCount==0?0.4:1; GradientFillRectDecal({(WIDTH/6)*scale.x+offset.x,(HEIGHT/6)*scale.y+offset.y},{WIDTH/3*scale.x,HEIGHT/6*2*scale.y},data->bgcol*darknessFactor*dimColor,data->bgcol*darknessFactor*dimColor,Pixel(72, 160, 212,0),data->bgcol*darknessFactor*dimColor); GradientFillRectDecal({(WIDTH/6*3+1)*scale.x+offset.x,(HEIGHT/6)*scale.y+offset.y},{WIDTH/3*scale.x,HEIGHT/6*2*scale.y},data->bgcol*darknessFactor*dimColor,Pixel(72, 160, 212,0),data->bgcol*darknessFactor*dimColor,data->bgcol*darknessFactor*dimColor); GradientFillRectDecal({(WIDTH/6)*scale.x+offset.x,(HEIGHT/6*3)*scale.y+offset.y},{WIDTH/3*scale.x,HEIGHT/6*2*scale.y},data->bgcol*darknessFactor*dimColor,data->bgcol*darknessFactor*dimColor,data->bgcol*darknessFactor*dimColor,Pixel(72, 160, 212,0)); GradientFillRectDecal({(WIDTH/6*3+1)*scale.x+offset.x,(HEIGHT/6*3)*scale.y+offset.y},{WIDTH/3*scale.x,HEIGHT/6*2*scale.y},Pixel(72, 160, 212,0),data->bgcol*darknessFactor*dimColor,data->bgcol*darknessFactor*dimColor,data->bgcol*darknessFactor*dimColor); DrawPartialDecal({(WIDTH/2-data->anim->width/2*3)*scale.x+offset.x,(HEIGHT/6+16-data->anim->height/2)*scale.y+offset.y},data->anim->spr,data->anim->getCurrentFrame(),{(float)(data->anim->width),(float)(data->anim->height)},{3*scale.x,3*scale.y},WHITE*darknessFactor*dimColor); for (int x=-1;x<=1;x++) { for (int y=-1;y<=1;y++) { if (x!=0&&y!=0) { DrawStringPropDecal({(WIDTH/6+4+x)*scale.x+offset.x,(HEIGHT/2+8+y)*scale.y+offset.y},data->name,BLACK,{2*scale.x,2*scale.y}); } } } DrawStringPropDecal({(WIDTH/6+4)*scale.x+offset.x,(HEIGHT/2+8)*scale.y+offset.y},data->name,data->textcol*darknessFactor*dimColor,{2*scale.x,2*scale.y}); DrawWrappedPropText({(WIDTH/6+4+1)*scale.x+offset.x,(HEIGHT/2+24+1)*scale.y+offset.y},data->description,(WIDTH/3*2-8)*scale.x,BLACK,{scale.x,scale.y}); DrawWrappedPropText({(WIDTH/6+4)*scale.x+offset.x,(HEIGHT/2+24)*scale.y+offset.y},data->description,(WIDTH/3*2-8)*scale.x,Pixel(227, 245, 255,255)*darknessFactor*dimColor,{scale.x,scale.y}); for (int x=-1;x<=1;x++) { for (int y=-1;y<=1;y++) { if (x!=0&&y!=0) { DrawStringPropDecal({(float)((WIDTH/6+4+WIDTH/3*2-8-GetTextSizeProp(std::to_string(data->playerOwnCount)+" uses remaining.").x*1.5+x)*scale.x+offset.x),(float)((HEIGHT/6*3+HEIGHT/6*2-GetTextSizeProp(std::to_string(data->playerOwnCount)+" uses remaining.").y*1.5-4+y))*scale.y+offset.y},std::to_string(data->playerOwnCount)+" uses remaining.",olc::BLACK,{(float)(1.5*scale.x),(float)(1.5*scale.y)}); } } } DrawStringPropDecal({(float)((WIDTH/6+4+WIDTH/3*2-8-GetTextSizeProp(std::to_string(data->playerOwnCount)+" uses remaining.").x*1.5)*scale.x+offset.x),(float)((HEIGHT/6*3+HEIGHT/6*2-GetTextSizeProp(std::to_string(data->playerOwnCount)+" uses remaining.").y*1.5-4)*scale.y+offset.y)},std::to_string(data->playerOwnCount)+" uses remaining.",(data->playerOwnCount==0)?olc::RED:olc::WHITE*darknessFactor,{(float)(1.5*scale.x),(float)(1.5*scale.y)}); } void effectRadius(vi2d coords,WEATHER_POWER*power,bool playerForce) { int finalDamage=power->damage+rand()%power->damageRoll*sign(power->damage); effectRadius(coords,power,finalDamage,playerForce); } void effectRadius(vi2d coords,WEATHER_POWER*power,int finalDamage,bool playerForce) { std::cout<<"Emitting effect radius for "<name<<" for PlayerForce:"<damage==-1002) { //Instead heal for their max health. PLAYER_MAXHP+=5; finalDamage=-PLAYER_MAXHP; foodCount--; } else if (power->damage==-1001) { //Instead heal for their max health. FOOD_REGEN_TURNS=4; finalDamage=-PLAYER_MAXHP*0.33; foodCount--; } PLAYER_HP=std::clamp(PLAYER_HP-finalDamage,0,PLAYER_MAXHP); CreateDisplayNumber(finalDamage,PLAYER_COORDS[0],PLAYER_COORDS[1],frameCount); } else { for (int i=0;idamage+rand()%power->damageRoll*sign(power->damage); Entity*ent=CURRENT_ENCOUNTER.entities[i]; if (distancetoCoords({(float)((ent->x+CURRENT_ENCOUNTER.x)*32),(float)((ent->y+CURRENT_ENCOUNTER.y)*32)},coords*32)<=power->range) { ent->hp=std::clamp(ent->hp-finalDamage,0,ent->maxhp); CreateDisplayNumber(finalDamage,ent->x+CURRENT_ENCOUNTER.x+ent->spr->sprite->width*ent->sprScale.x/2/32,ent->y+CURRENT_ENCOUNTER.y+ent->spr->sprite->height*ent->sprScale.y/2/32,frameCount); ent->damageFrame=frameCount; } } } } else { //Damaging effect. if (playerForce) { for (int i=0;idamage+rand()%power->damageRoll*sign(power->damage); Entity*ent=CURRENT_ENCOUNTER.entities[i]; std::cout<<"Distance was "<x+CURRENT_ENCOUNTER.x)*32),(float)((ent->y+CURRENT_ENCOUNTER.y)*32)},coords*32)<<"\n"; if (ent->hp>0&&distancetoCoords({(float)((ent->x+CURRENT_ENCOUNTER.x)*32),(float)((ent->y+CURRENT_ENCOUNTER.y)*32)},coords*32)<=power->range) { ent->hp=std::clamp(ent->hp-finalDamage,0,ent->maxhp); CreateDisplayNumber(finalDamage,ent->x+CURRENT_ENCOUNTER.x+ent->spr->sprite->width*ent->sprScale.x/2/32,ent->y+CURRENT_ENCOUNTER.y+ent->spr->sprite->height*ent->sprScale.y/2/32,frameCount); ent->damageFrame=frameCount; } } } else { PLAYER_HP=std::clamp(PLAYER_HP-finalDamage,0,PLAYER_MAXHP); CreateDisplayNumber(finalDamage,PLAYER_COORDS[0],PLAYER_COORDS[1],frameCount); } } } double distancetoCoords(vf2d c1,vf2d c2) { return sqrt(pow(c1.x-c2.x,2)+pow(c2.y-c1.y,2)); } int sign(int x) { return (x > 0) - (x < 0); } int rand() { srand(time(NULL)+RAND_CALLS); int randNumb = std::rand(); RAND_CALLS=randNumb; return randNumb; } void performCropUpdate(int chanceToRegrow) { for (int x=0;x<4;x++) { for (int y=0;y<4;y++) { if (rand()%chanceToRegrow==0) { setPlantStatusWithAbsoluteCoords(x,y,std::clamp(getPlantStatusWithAbsoluteCoords(x,y)+1,0,2)); } } } } void setupBattleTurns() { //Remove the card from inventory. BATTLE_CARD_SELECTION->playerOwnCount--; BATTLE_STATE=battle::ENEMY_SELECTION; for (int i=0;ihp>0) { if (CURRENT_ENCOUNTER.entities[i]->fixedTurnOrder) { CURRENT_ENCOUNTER.entities[i]->selectedMove=CURRENT_ENCOUNTER.entities[i]->moveSet[CURRENT_ENCOUNTER.entities[i]->fixedTurnOrderInd++]; if (CURRENT_ENCOUNTER.entities[i]->fixedTurnOrderInd>=CURRENT_ENCOUNTER.entities[i]->moveSet.size()) { CURRENT_ENCOUNTER.entities[i]->fixedTurnOrderInd=0; } } else { CURRENT_ENCOUNTER.entities[i]->selectedMove=CURRENT_ENCOUNTER.entities[i]->moveSet[rand()%CURRENT_ENCOUNTER.entities[i]->moveSet.size()]; } CURRENT_ENCOUNTER.entities[i]->turnComplete=false; } } PLAYER_TURN_COMPLETE=false; BATTLE_STATE=battle::MOVE_RESOLUTION; //Seed Storm has prio. if (!PLAYER_TURN_COMPLETE&&isPriorityMove(BATTLE_CARD_SELECTION)) { turnOrder.push(-1); PLAYER_TURN_COMPLETE=true; } for (int i=0;ihp>0&&!CURRENT_ENCOUNTER.entities[i]->turnComplete&& isPriorityMove(CURRENT_ENCOUNTER.entities[i]->selectedMove)) { turnOrder.push(i); CURRENT_ENCOUNTER.entities[i]->turnComplete=true; std::cout<<" Entity "<hp>0&&!ent->turnComplete&& !ent->slowed&&rand()%2==0) { turnOrder.push(i); ent->turnComplete=true; } } if (!PLAYER_TURN_COMPLETE) { turnOrder.push(-1); PLAYER_TURN_COMPLETE=true; } //Finally, any enemies that haven't gone will now go. for (int i=0;ihp>0&&!ent->turnComplete) { turnOrder.push(i); ent->turnComplete=true; } } BATTLE_STATE=battle::PERFORM_TURN; BATTLE_CURRENT_TURN_ENTITY=turnOrder.front(); turnOrder.pop(); BATTLE_STATE=battle::WAIT_TURN_ANIMATION; EFFECT_TIMER=0; } void displayPowerInfo(WEATHER_POWER*POWER){ PlayCutscene(cutscene::NODE_COLLECT_CUTSCENE); CUTSCENE_DISPLAYED_CARD=POWER; } void applyPixelEffect(ParticleEffect*effect,vf2d pos,float startingTransparency) { applyPixelEffect( {(pos.x-PLAYER_COORDS[0])*32+WIDTH/2-effect->effectSize.x/2,(pos.y-PLAYER_COORDS[1])*32+HEIGHT/2-effect->effectSize.y/2}, effect->effectSize, effect->pos_low, effect->pos_high, effect->size_low, effect->size_high, effect->spd_low, effect->spd_high, effect->col_low, effect->col_high, effect->amt, effect->foregroundColor,startingTransparency ); } void applyPixelEffect(WEATHER_POWER*power,vf2d pos,float startingTransparency) { applyPixelEffect( {(pos.x-PLAYER_COORDS[0])*32+WIDTH/2-power->effect->effectSize.x/2,(pos.y-PLAYER_COORDS[1])*32+HEIGHT/2-power->effect->effectSize.y/2}, power->effect->effectSize, power->effect->pos_low, power->effect->pos_high, power->effect->size_low, power->effect->size_high, power->effect->spd_low, power->effect->spd_high, power->effect->col_low, power->effect->col_high, power->effect->amt, power->effect->foregroundColor,startingTransparency ); } void applyPixelEffect(vf2d effectPos,vf2d effectSize,vf2d pos_low,vf2d pos_high,vf2d size_low,vf2d size_high,vf2d spd_low,vf2d spd_high,olc::Pixel col_low,olc::Pixel col_high,int amt,olc::Pixel foregroundColor,float startingTransparency) { for (int i=0;ipos={range(pos_low.x,pos_high.x),range(pos_low.y,pos_high.y)}; pixels[i]->size={range(size_low.x,size_high.x),range(size_low.y,size_high.y)}; std::cout<size.x)<<","<size.y)<<"\n"; pixels[i]->spd={range(spd_low.x,spd_high.x),range(spd_low.y,spd_high.y)}; pixels[i]->r=range(col_low.r,col_high.r); pixels[i]->g=range(col_low.g,col_high.g); pixels[i]->b=range(col_low.b,col_high.b); pixels[i]->a=range(col_low.a,col_high.a); pixels[i]->o_a=range(col_low.a,col_high.a); } ORIGINAL_FOREGROUND_EFFECT_COLOR=FOREGROUND_EFFECT_COLOR=foregroundColor; PIXEL_POS=effectPos; PIXEL_SIZE=effectSize; PIXEL_LIMIT=amt; PIXEL_EFFECT_TRANSPARENCY=startingTransparency; } void clearPixelEffect() { PIXEL_LIMIT=0; PIXEL_EFFECT_TRANSPARENCY=0; } //Returns a number between 0.0 and X. float random(float X) { return (float)rand()/RAND_MAX * X; } float range(float val1,float val2) { return random(val2-val1)+val1; } vf2d GetMapFileCoords(int ln,int col) { return {(float)col-1,(float)ln-3}; } //Basically, click on a spot in the text editor and this function translates it into the proper teleport coords so you don't have to. void TeleportToMapFileCoords(int ln,int col) { vi2d teleLoc = GetMapFileCoords(ln,col); PLAYER_COORDS[0]=teleLoc.x+0.5; PLAYER_COORDS[1]=teleLoc.y+0.5; } Object*CreateObject(vf2d pos,Decal*spr,int ,bool temporary=false) { Object*newobj; OBJECTS.push_back(newobj=new Object(spr)); newobj->x=pos.x; newobj->y=pos.y; newobj->tempObj=temporary; return newobj; } Object*CreateObject(vf2d pos,Decal*spr,Animation*anim,bool temporary=false) { Object*newobj; OBJECTS.push_back(newobj=new Object(spr,anim)); newobj->x=pos.x; newobj->y=pos.y; newobj->tempObj=temporary; return newobj; } Object*CreateObject(vf2d pos,Decal*spr,vi2d spos,vi2d size,bool temporary=false) { Object*newobj; OBJECTS.push_back(newobj=new Object(spr,spos,size)); newobj->x=pos.x; newobj->y=pos.y; newobj->tempObj=temporary; return newobj; } void ClearAllTemporaryObjects() { for (int i=0;i<8;i++) { for (int j=0;jtempObj) { OBJECTS.erase(OBJECTS.begin()+j); std::cout<<"Erased at position "<pos.x) { PLAYER_COORDS[0]=pos.x; } } else { PLAYER_COORDS[0]-=spd; if (PLAYER_COORDS[0]pos.y) { PLAYER_COORDS[1]=pos.y; } } else { PLAYER_COORDS[1]-=spd; if (PLAYER_COORDS[1]x!=pos.x) { if (obj->xx+=spd; if (obj->x>pos.x) { obj->x=pos.x; } } else { obj->x-=spd; if (obj->xx=pos.x; } } reachedPosition=false; } else if (!secondRun&&movementStyle!=BOTH) { MoveObjectTowardsPoint(pos,obj,VERT_FIRST,spd,true); } } if (movementStyle==VERT_FIRST||movementStyle==BOTH) { if (obj->y!=pos.y) { if (obj->yy+=spd; if (obj->y>pos.y) { obj->y=pos.y; } } else { obj->y-=spd; if (obj->yy=pos.y; } } reachedPosition=false; } else if (!secondRun&&movementStyle!=BOTH) { MoveObjectTowardsPoint(pos,obj,HORZ_FIRST,spd,true); } } return reachedPosition; } void ResetTerminal(std::string text){ CUTSCENE_CONSOLE_TEXT.clear(); textInd=0; CONSOLE_REF_TEXT=text; } bool isPriorityMove(WEATHER_POWER*power) { return power->name.compare("Seed Storm")==0|| power->name.compare("Seed of Life")==0|| power->name.compare("Petal Storm")==0; } bool isFoodMove(WEATHER_POWER*power) { return power->name.compare("Meal")==0|| power->name.compare("Snack")==0; } void addSeeds(int seedCount) { for (int i=0;i