summaryrefslogtreecommitdiff
path: root/game
diff options
context:
space:
mode:
Diffstat (limited to 'game')
-rw-r--r--game/CMakeLists.txt13
-rw-r--r--game/bounding.hpp21
-rw-r--r--game/graphics.hpp93
-rw-r--r--game/story.hpp176
4 files changed, 303 insertions, 0 deletions
diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt
new file mode 100644
index 0000000..ac6fc76
--- /dev/null
+++ b/game/CMakeLists.txt
@@ -0,0 +1,13 @@
+file(GLOB_RECURSE GAME_SOURCES CONFIGURE_DEPENDS
+ "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp"
+ "${CMAKE_CURRENT_SOURCE_DIR}/*.cc"
+ "${CMAKE_CURRENT_SOURCE_DIR}/*.cxx"
+)
+
+file(GLOB_RECURSE GAME_HEADERS CONFIGURE_DEPENDS
+ "${CMAKE_CURRENT_SOURCE_DIR}/*.hpp"
+ "${CMAKE_CURRENT_SOURCE_DIR}/*.h"
+ "${CMAKE_CURRENT_SOURCE_DIR}/*.hh"
+)
+
+target_sources(cirno_day PRIVATE ${GAME_SOURCES} ${GAME_HEADERS})
diff --git a/game/bounding.hpp b/game/bounding.hpp
new file mode 100644
index 0000000..012729a
--- /dev/null
+++ b/game/bounding.hpp
@@ -0,0 +1,21 @@
+#include <raylib.h>
+#include "../lib/gameState.hpp"
+#define UI_PADDING_BOTTOM 10
+#define UI_BUTTON_SIZE 32
+
+inline Rectangle Calendar = {170, 65, 40, 45};
+inline Rectangle Forehead = {80, 190, 58, 50};
+inline Rectangle Chest = {75, 130, 70, 50};
+inline Rectangle Futton = {145, 190, 80, 110};
+
+inline Rectangle YokaiMountain = {0, 0, 225, 128};
+inline Rectangle Igloo = {130, 160, 100, 90};
+inline Rectangle MistyLake = {0, 128, 225, 32};
+inline Rectangle Flower = {25, 350, 47, 47};
+
+inline Rectangle Frog = {32, 270, 55, 45};
+inline Rectangle RiceCake = {160, 180, 64, 100};
+
+// UI components
+inline Rectangle UI_arrowBtn = {(int)(VIRTUAL_SCREEN_W/3)*2 + UI_BUTTON_SIZE/2.0f ,VIRTUAL_SCREEN_H - UI_BUTTON_SIZE - UI_PADDING_BOTTOM, 32, 32};
+inline Rectangle UI_talkBtn = {(int)(VIRTUAL_SCREEN_W/2) - 88.0f/2,VIRTUAL_SCREEN_H - UI_BUTTON_SIZE - UI_PADDING_BOTTOM,88, 32};
diff --git a/game/graphics.hpp b/game/graphics.hpp
new file mode 100644
index 0000000..b4ff3b0
--- /dev/null
+++ b/game/graphics.hpp
@@ -0,0 +1,93 @@
+#include <raylib.h>
+#include <cmath>
+#include <raymath.h>
+
+#include "lib/gameState.hpp"
+
+#define CIRNO_SPRITE_POSITION {-26, 156}
+
+constexpr float TRANSITION_TIME = 1.5f; // in seconds
+
+inline void drawCirno(GameState &gs) {
+ switch (gs.curExp) {
+ case NEUTRAL:
+ DrawTextureV(gs.AssetManager.load("cirno-neutral"), CIRNO_SPRITE_POSITION, WHITE);
+ break;
+ case PISSED:
+ DrawTextureV(gs.AssetManager.load("cirno-pissed"), CIRNO_SPRITE_POSITION, WHITE);
+ break;
+ case HURT:
+ DrawTextureV(gs.AssetManager.load("cirno-hurt"), CIRNO_SPRITE_POSITION, WHITE);
+ break;
+ case JOY:
+ DrawTextureV(gs.AssetManager.load("cirno-joy"), CIRNO_SPRITE_POSITION, WHITE);
+ break;
+ case WOW:
+ DrawTextureV(gs.AssetManager.load("cirno-wow"), CIRNO_SPRITE_POSITION, WHITE);
+ break;
+ case TIERED:
+ DrawTextureV(gs.AssetManager.load("cirno-tiered"), CIRNO_SPRITE_POSITION, WHITE);
+ break;
+ case LAUGH:
+ DrawTextureV(gs.AssetManager.load("cirno-laugh"), CIRNO_SPRITE_POSITION, WHITE);
+ break;
+ case RELAXED:
+ DrawTextureV(gs.AssetManager.load("cirno-relaxed"), CIRNO_SPRITE_POSITION, WHITE);
+ break;
+ }
+}
+
+inline Texture2D getCurrentScene(GameState &gs) {
+ switch (gs.curPos) {
+ case INSIDE:
+ return gs.AssetManager.load("inside");
+ break;
+ case OUTSIDE:
+ return gs.AssetManager.load(gs.flowerOnHead ? "outside2" : "outside");
+ break;
+ case FOREST:
+ return gs.AssetManager.load(gs.riceCakeEaten ? "forest2" : "forest");
+ break;
+ case MENU:
+ return gs.AssetManager.load("menu");
+ }
+};
+
+inline Texture2D getCurrentScene(GameState &gs, POSITION scene) {
+ switch (scene) {
+ case INSIDE:
+ return gs.AssetManager.load("inside");
+ break;
+ case OUTSIDE:
+ return gs.AssetManager.load(gs.flowerOnHead ? "outside2" : "outside");
+ break;
+ case FOREST:
+ return gs.AssetManager.load(gs.riceCakeEaten ? "forest2" : "forest");
+ break;
+ case MENU:
+ return gs.AssetManager.load("menu");
+ }
+};
+
+inline void DrawSceneChange(GameState &gs) {
+ if (gs.timeSinceSceneChange < TRANSITION_TIME) {
+ float t = Clamp(gs.timeSinceSceneChange / TRANSITION_TIME, 0.0f, 1.0f);
+ float a = 0.5f - 0.5f * cosf(t * PI);
+ DrawTextureV(getCurrentScene(gs, gs.prevPos),
+ ZERO_VEC,
+ ColorAlpha(WHITE, 1.0f - a));
+
+ DrawTextureV(getCurrentScene(gs, gs.curPos),
+ ZERO_VEC,
+ ColorAlpha(WHITE, a));
+ gs.timeSinceSceneChange = gs.timeSinceSceneChange + GetFrameTime();
+ } else {
+ gs.timeSinceSceneChange = -1.0f;
+ }
+}
+
+inline void changeSceneTo(GameState &gs, POSITION scene) {
+ gs.timeSinceSceneChange = 0;
+ gs.prevPos = gs.curPos;
+ gs.curPos = scene;
+}
diff --git a/game/story.hpp b/game/story.hpp
new file mode 100644
index 0000000..ef06d13
--- /dev/null
+++ b/game/story.hpp
@@ -0,0 +1,176 @@
+#include "lib/gameState.hpp"
+#include "lib/dialogue.hpp"
+
+#include "bounding.hpp"
+#include "graphics.hpp"
+#include "raylib.h"
+
+#define CIRNO_DIALOG "Cirno",
+
+inline void ProcessClick(GameState &gs) {
+ if (CheckCollisionPointRec(gs.currentMousePos, Forehead)) {
+ if (gs.flickCount == 0) {
+ SayDialog(gs, std::vector<Dialogues>{
+ {CIRNO_DIALOG HURT, "owww"},
+ {CIRNO_DIALOG PISSED, "it hurts. You are mean!"},
+ {CIRNO_DIALOG PISSED, "Why did you do that?"}
+ });
+ } else if (gs.flickCount == 1) {
+ SayDialog(gs, std::vector<Dialogues> {
+ {CIRNO_DIALOG HURT, "You did it again!"},
+ {CIRNO_DIALOG PISSED, "Owww, it hurts.\nStop it!"},
+ });
+ } else if (gs.flickCount == 2) {
+ SayDialog(gs, std::vector<Dialogues> {
+ {CIRNO_DIALOG PISSED, "No, I won't let you\ndo it again"},
+ {CIRNO_DIALOG PISSED, "You meanie!!"},
+ });
+ gs.explored.insert(1);
+ }
+ gs.flickCount++;
+ }
+ else if (CheckCollisionPointRec(gs.currentMousePos, UI_arrowBtn)) {
+ if (gs.curPos == INSIDE) {
+ changeSceneTo(gs, OUTSIDE);
+ SayDialog(gs, std::vector<Dialogues> {
+ {CIRNO_DIALOG WOW, "This is where I live"},
+ });
+ gs.explored.insert(2);
+ } else if (gs.curPos == OUTSIDE) {
+ changeSceneTo(gs, FOREST);
+ SayDialog(gs, std::vector<Dialogues> {
+ {CIRNO_DIALOG LAUGH, "Let's freeze some\nfrogs!"},
+ });
+ gs.explored.insert(3);
+ } else if (gs.curPos == FOREST) {
+ changeSceneTo(gs, INSIDE);
+ SayDialog(gs, std::vector<Dialogues> {
+ {CIRNO_DIALOG RELAXED, "Back in sweet cozy\nhome!"}
+ });
+ gs.explored.insert(4);
+ }
+ } else if (CheckCollisionPointRec(gs.currentMousePos, UI_talkBtn)) {
+ if (!gs.usedTalkButton) {
+ SayDialog(gs, std::vector<Dialogues> {
+ {CIRNO_DIALOG RELAXED, "Good Morning"},
+ });
+ gs.usedTalkButton = true;
+ } else {
+ SayDialog(gs, std::vector<Dialogues> {
+ {CIRNO_DIALOG JOY, "Having lots of fun is\nwhat matters."},
+ {CIRNO_DIALOG RELAXED, "Imagine having no fun\nand being grumpy\nall the time."},
+ {CIRNO_DIALOG JOY, "Next time, when you come,\nwe can play together."},
+ {CIRNO_DIALOG JOY, "With Daiyousei and\nthe other fairies."},
+ {CIRNO_DIALOG RELAXED, "It would be nice if\nwinter comes soon."},
+ {CIRNO_DIALOG JOY, "I want to skate on the\nmisty lake with Letty."},
+ {CIRNO_DIALOG WOW, "I am the smartest\nin Gensokyo."},
+ {CIRNO_DIALOG WOW, "I can add and multiply\nfractions!"},
+ {CIRNO_DIALOG LAUGH, "Only a few could rival\nan intellect such\nas mine."}
+ });
+ gs.explored.insert(7);
+ }
+ }
+ else if (gs.curPos == INSIDE) {
+ if (CheckCollisionPointRec(gs.currentMousePos, Calendar)) {
+ SayDialog(gs, std::vector<Dialogues> {
+ {CIRNO_DIALOG WOW, "its cirno day, todeh"},
+ {CIRNO_DIALOG JOY, "billions must celebrate"}
+ });
+ gs.explored.insert(5);
+ }
+ else if (CheckCollisionPointRec(gs.currentMousePos, Chest)) {
+ if (gs.chestCount == 0) {
+ SayDialog(gs, std::vector<Dialogues> {
+ {CIRNO_DIALOG WOW, "Hey!! Don't snoop around\nthe chest"},
+ {CIRNO_DIALOG TIERED, "It's where I store all my\ntreasures"}
+ });
+ gs.chestCount++;
+ } else if (gs.chestCount == 1) {
+ SayDialog(gs, std::vector<Dialogues> {
+ {CIRNO_DIALOG PISSED, "No, I won't let you\nsee what's inside!!!"},
+ });
+ gs.explored.insert(6);
+ }
+ }
+ else if (CheckCollisionPointRec(gs.currentMousePos, Futton)) {
+ if (gs.explored.size() == 13) {
+ SayDialog(gs, std::vector<Dialogues> {
+ {CIRNO_DIALOG WOW, "I am feeling sleepy\nI had lots of fun with you"},
+ {CIRNO_DIALOG TIERED, " I am gonna take a nap\nLet's see tommorow!!"}
+ });
+ } else {
+ SayDialog(gs, std::vector<Dialogues> {
+ {CIRNO_DIALOG WOW, "I just woke up before\nyou came"},
+ {CIRNO_DIALOG TIERED, "So, I am not sleepy now\nI want to play"}
+ });
+ }
+ }
+ } else if (gs.curPos == OUTSIDE){
+ if (CheckCollisionPointRec(gs.currentMousePos, YokaiMountain)) {
+ SayDialog(gs, std::vector<Dialogues> {
+ {CIRNO_DIALOG WOW, "That's the Youkai Mountain\nThat's where Aya lives"},
+ {CIRNO_DIALOG JOY, "She is nosy and snitches\nme to people whenever\nI am up to no good"},
+ {CIRNO_DIALOG PISSED, "Bah!! She is annoying!"},
+ {CIRNO_DIALOG JOY, "The Moriya shrine is at\nthe very top of the\nYoukai Mountain"},
+ {CIRNO_DIALOG WOW, "The deities there,\nare very strong."},
+ {CIRNO_DIALOG LAUGH, "Not as strong as me,\nof course!"},
+ {CIRNO_DIALOG WOW, "But I like the Hakurei\nshrine more"},
+ {CIRNO_DIALOG RELAXED, "Reimu sometimes gives\nme some snacks\nwhen I go there"},
+ });
+ gs.explored.insert(8);
+ } else if (CheckCollisionPointRec(gs.currentMousePos, MistyLake)) {
+ SayDialog(gs, std::vector<Dialogues> {
+ {CIRNO_DIALOG WOW, "Do you know? There is a\ngiant frog that lives"},
+ {CIRNO_DIALOG TIERED, "at the bottom of the lake.\nIt's very very big."},
+ {CIRNO_DIALOG PISSED, "It ate me one time!!"}
+ });
+ gs.explored.insert(9);
+ } else if (CheckCollisionPointRec(gs.currentMousePos, Igloo)) {
+ SayDialog(gs, std::vector<Dialogues> {
+ {CIRNO_DIALOG WOW, "My house looks very cool,\nright?"},
+ {CIRNO_DIALOG JOY, "It was a lot of work,\nbullying the other fairies\ninto building my house"},
+ {CIRNO_DIALOG TIERED, "Though, sometimes they\nbarge into my home to\nplay"}
+ });
+ gs.explored.insert(10);
+ } else if (CheckCollisionPointRec(gs.currentMousePos, Flower) && !gs.flowerOnHead) {
+ SayDialog(gs, std::vector<Dialogues> {
+ {CIRNO_DIALOG JOY, "A flower!"},
+ });
+ gs.flowerOnHead = true;
+ SayDialog(gs, std::vector<Dialogues> {
+ {CIRNO_DIALOG WOW, "Do I look cute with\nthis flower on me?"},
+ {CIRNO_DIALOG LAUGH, "I like it a lot"}
+ });
+ gs.explored.insert(11);
+ }
+ } else if (gs.curPos == FOREST) {
+ if (CheckCollisionPointRec(gs.currentMousePos, Frog)) {
+ if (!gs.frogDialogDone) {
+ SayDialog(gs, std::vector<Dialogues> {
+ {CIRNO_DIALOG WOW, "Suwako somehow always\ncatches me henever I bully\nfrogs here"},
+ {CIRNO_DIALOG JOY, "Let's leave it alone for now\nShe will beat me up"},
+ {CIRNO_DIALOG TIERED, "if I get caught red handed"}
+ });
+ gs.frogDialogDone = true;
+ gs.explored.insert(12);
+ } else {
+ SayDialog(gs, std::vector<Dialogues> {
+ {CIRNO_DIALOG LAUGH, "Ribbit ribbit\nThe frogs make\nfunny noises."},
+ });
+ }
+ } else if (CheckCollisionPointRec(gs.currentMousePos, RiceCake) && !gs.riceCakeEaten) {
+ SayDialog(gs, std::vector<Dialogues> {
+ {CIRNO_DIALOG RELAXED, "It's a small shrine for the\nMoriya gods built by the Kappas"},
+ {CIRNO_DIALOG WOW, "The Miko called Sanae comes\nhere from time to time\nand takes care of it. "},
+ {CIRNO_DIALOG JOY, "Look! There is a rice cake here\nleft as an offering."}
+ });
+ gs.explored.insert(13);
+ gs.riceCakeEaten = true;
+ SayDialog(gs, std::vector<Dialogues> {
+ {CIRNO_DIALOG JOY, "The rice cake magically disappeared!"},
+ {CIRNO_DIALOG RELAXED, ". . .", 0.4f},
+ {CIRNO_DIALOG JOY, "*Burp*"},
+ });
+ }
+ }
+}