Undertale

Dependencies:   mbed wave_player 4DGL-uLCD-SE MMA8452

main.cpp

Committer:
cdong49
Date:
2019-04-14
Revision:
4:3883ea0930ec
Parent:
3:ab8f2b4b44b0

File content as of revision 4:3883ea0930ec:

// Project includes
#include "globals.h"
#include "hardware.h"
#include "map.h"
#include "graphics.h"
#include "speech.h"

#include <stdlib.h>
int menu = 0;
int health = 3;
int omni_pressed = 0;
int run = 0;
int quest = 0; // 0 is before quest, 1 is during quest no key, 2 is with key, 3 is back talking 
int door = 0; // 1 if door unlocked, 0 if door locked
int chest = 0;
int game_over = 0;
char* task[5] = {"talk to the dog to start quest", "go to Snowdin", "go into the room to start the puzzle", "come back to the castle", "go to the castle"};
char* hint[5] = {"Just talk to him", "talk to the riverman", "read the sign", "talk to the riverman", "walk down south"};

char* flowey_wink[4] = {"Howdy!", "I'm FLOWEY", "FLOWEY THE", "FLOWER"};
char* flowey_creepy[4] = {"In this","world...","It's KILL","or BE killed!"};
char* flowey_friendly1[4] = {"That shirt...", "it seems familiar", "reminds me of", "someone"};
char* flowey_friendly2[4] = {"are you sure", "it's yours?", "ugh I hate", "that dog"};
char** flowey_friendly[2] = {flowey_friendly1, flowey_friendly2};

char* sign1[4] = {"Welcome to","Snowdin!", "here you have to","solve a puzzle"};
char* sign2[4] = {"Choose the right", "button. One will", "take you to", "the next level"};
char* sign3[4] = {"Two will kick you","out of the room", "Three strikes", "and you're out"};
char** sign[3] = {sign1, sign2, sign3};

char* toby_pre1[4] = {"ruff ruff", "yo!", "I'm just a dog"};
char* toby_pre2[4] = {"how are ya", "you must be", "new here!", "This is the"};
char* toby_pre3[4] = {"the ruins! We", "have monsters and", "all kind of"};
char* toby_pre4[4] = {"stuff down here", "...", "There is not", "much to do tho"};
char* toby_pre5[4] = {"... oh wait", "there is!! I'm", "hungry.. can you", "get me some bone?"};
char* toby_pre6[4] = {"Where? Snowdin!","it's quite a", "distance from here", "so i suggest"};
char* toby_pre7[4] = {"you get going!", "Bring me a bone", "asap, and ill" };
char* toby_pre8[4] = {"give you something","in return!","good luck!!","..."};
char** toby_pre[8] = {toby_pre1, toby_pre2, toby_pre3,toby_pre4,toby_pre5,toby_pre6,toby_pre7,toby_pre8};
char* toby_bone1[4] = {"Om nom nom", "nom..", "oh hey!", "look at ya"};
char* toby_bone2[4] = {"How did you get", "here so fast?", ".. nom nom", "nom"};
char* toby_bone3[4] = {"what's with the", "look? Didnt", "I tell you I", "could teleport?"};
char* toby_bone4[4] = {"Yea!Like the dude", "on the boat", "pretty nice,","isnt it?"};
char* toby_bone5[4] = {"You just came", "here for nothing!", "bamboozled!","..."};
char* toby_bone6[4] = {"Lol don't be mad", "I'll give ya", "this pretty dope", "shirt!"};
char* toby_bone7[4] = {"The old prince", "threw it away", "you can", "basically go"};
char* toby_bone8[4] = {"anywhere with it", "...", "It's", "pretty nice!"};
char* toby_bone9[4] = {"imma go!", "baiiii", "i'll see ya at", "the starting point"};
char** toby_bone[9] = {toby_bone1, toby_bone2,toby_bone3,toby_bone4,toby_bone5,toby_bone6,toby_bone7,toby_bone8,toby_bone9};

char* river_man_line1[4] = {"Tra la la", "The waters are", "wild today.", "That is bad luck"};
char* river_man_line2[4] = {"Tra la la", "The waters are", "wild today.", "That is good luck"};
char* river_man_line3[4] = {"Tra la la", "What's inside an", "acorn? It's" ,"just a mystery."};
char* river_man_line4[4] = {"Tra la la", "Dancing on a boat","is danger.", "But good exercise"};
char* river_man_line5[4] = {"Tra la la", "Why don't you", "sing with me.", "Tra la la."};
char* river_man_line6[4] = {"Tra la la", "Uh oh.", "Suddenly, feeling" ,"tropical..."};
char* river_man_line7[4] = {"Tra la la", "The water is", "very dry", "today"};
char* river_man_line8[4] = {"Tra la la", "The water is", "very wet", "today"};
char* river_man_line9[4] = {"Tra la la", "Tri li li.", "Tre le le.", "..."};
char* river_man_line10[4] = {"Tra la la", "What's my name?" ,"It doesn't", "really matter..."};
char* river_man_line11[4] = {"Tra la la." "I heard dogs" "have a favorite" "food. It's bone!"};
char* river_man_line12[4] = {"Tra la la. You", "can never have", "too many hot dogs", "This is not true"};
char* river_man_line13[4] = {"Tra la la.", "Beware of", "the man who", "speaks in hands"};
char* river_man_line14[4] = {"Tra la la.", "Beware of the", "man who came from", "the other world"};
char* river_man_line15[4] = {"Tra la la.", "Humans, monsters", "...", "flowers"};
char** river_man_line[15] = {river_man_line13, river_man_line3,river_man_line14, river_man_line1, river_man_line15, river_man_line6, river_man_line11, river_man_line8, river_man_line9, river_man_line10,river_man_line7,river_man_line12,river_man_line2,river_man_line4,river_man_line5};
// Functions in this file
int get_action (GameInputs inputs);
int update_game (int action);
void draw_game (int init);
void init_main_map ();
void intit_start();
void init_menu(char* task, char* hint, int health, int key, int chest, int run);
int go_up(int x, int y);
int go_down(int x, int y);
int go_left(int x, int y);
int go_right(int x, int y);
int main ();
int interact(int x, int y);
void check_health();
/**
 * The main game state. Must include Player locations and previous locations for
 * drawing to work properly. Other items can be added as needed.
 */
struct {
    int x,y;    // Current locations
    int px, py; // Previous locations
    int has_key;
} Player;

/**
 * Given the game inputs, determine what kind of update needs to happen.
 * Possbile return values are defined below.
 */
#define NO_ACTION 0
#define ACTION_BUTTON 1
#define MENU_BUTTON 2
#define GO_LEFT 3
#define GO_RIGHT 4
#define GO_UP 5
#define GO_DOWN 6
#define RUN 7
int get_action(GameInputs inputs)
{
    if(!inputs.b1) {
        return ACTION_BUTTON;   
    }
    if(!inputs.b2) {
        return MENU_BUTTON;   
    }
    if(inputs.ax < -0.49) {
        return GO_LEFT;   
    }
    if(inputs.ax >= 0.49) {
        return GO_RIGHT;
    }
    if(inputs.ay >=0.45) {
        return GO_UP;   
    }
    if(inputs.ay <= -0.45) {
        return GO_DOWN;   
    }
    if (!inputs.b3) {
        omni_pressed = !omni_pressed;
    }
    return NO_ACTION;
}

/**
 * Update the game state based on the user action. For example, if the user
 * requests GO_UP, then this function should determine if that is possible by
 * consulting the map, and update the Player position accordingly.
 * 
 * Return values are defined below. FULL_DRAW indicates that for this frame,
 * draw_game should not optimize drawing and should draw every tile, even if
 * the player has not moved.
 */
#define NO_RESULT 0
#define GAME_OVER 1
#define FULL_DRAW 2
int update_game(int action)
{
    // Save player previous location before updating
    Player.px = Player.x;
    Player.py = Player.y;
    
    // Do different things based on the each action.
    // You can define functions like "go_up()" that get called for each case.
    switch(action)
    {
        case GO_UP:
            if(go_up(Player.px, Player.py)) {
                return FULL_DRAW;   
            } else {
                break;
            }
        case GO_LEFT:
            if(go_left(Player.px, Player.py)) {
                return FULL_DRAW;   
            } else {
                break;
            }          
        case GO_DOWN:
            if(go_down(Player.px, Player.py)) {
                return FULL_DRAW;   
            } else {
                break;
            }
        case GO_RIGHT:
            if(go_right(Player.px, Player.py)) {
                return FULL_DRAW;   
            } else {
                break;
            }
        case ACTION_BUTTON:
            if(interact(Player.x,Player.y)) {
                return FULL_DRAW;
            } else {
                break;   
            }
        case MENU_BUTTON: 
            uLCD.cls();
            init_menu(task[menu], hint[menu], health, Player.has_key, chest, run);
            wait_ms(300);
            draw_game(true);
            return FULL_DRAW;
        default:        break;
    }
    return NO_RESULT;
}

int interact(int x, int y) {
    MapItem *item = get_south(x, y);

    if(item->type == CHEST) {
        speech("you found a", "chest!!!");
        draw_game(true);
        wait_ms(150);
        map_erase(x,y+1);
        draw_game(true);
        wait_ms(150);
        chest = 1;
        map_erase(x,y-2);
        draw_game(true);
        quest = 99;
        wait_ms(150);
        
        add_leaf(11, 10);
        add_wood(11, 11);
        add_wood(11, 12);
        return 1;  
    }
    
    if(item->type == WOOD) {
        if(run == 0) {
            speech("Hi kid!,","Im a tree");
            draw_game(true);
            wait_ms(150);
            speech("...","uhm so...");
            draw_game(true);
            wait_ms(150);
            speech("some kid left", "their running");
            draw_game(true);
            wait_ms(150);
            speech("shoes here, imma", "give it to you");
            draw_game(true);
            wait_ms(150);
            run = 1;
        } else {
            speech("oh you dont", "want the shoes");  
            draw_game(true);
            wait_ms(150);
            speech("no mo? Ill", "take it back then");
            draw_game(true);
            wait_ms(150);
            run = 0;
        }       
    }
    if(item->type == TOBY) {
        if(quest == 0) {
            for(int i =0; i<8;i++) {
                for(int j = 0; j < 4;j+=2) {
                    speech(toby_pre[i][j], toby_pre[i][j+1]);
                    draw_game(true);   
                }   
            }
            wait_ms(150);  
            quest=1;
            menu = 1;
            menu++;
        } else if(quest == 1) {
            speech("well..","what are you waiting for!");
            draw_game(true);
            wait_ms(300);
            menu = 1;
        } else if(quest == 3) {
            speech("ruff ruff,","looking good!!");
            draw_game(true);
            wait_ms(300); 
            speech("you can go to", "the castle");
            draw_game(true);
            wait_ms(300);
            speech("down south now!", "Have fun");
            draw_game(true);
            wait_ms(300);
            menu = 4;  
        } else if(quest == 99) {
            speech("congrats! you","finish the game");
            draw_game(true);
            wait_ms(300);
            game_over = 1;
        }
        
        return 1;  
    }
    if(item->type == FLOWWINK) {
    // generate a 500Hz tone using PWM hardware output
        speaker.period(1.0/500.0); // 500hz period
        speaker =0.5; //50% duty cycle - max volume
        wait(1);
        speaker=0.0; // turn off audio
        wait(1);
        if(quest == 2) {
            add_flowey_friendly(x, y+1);
            draw_game(true);
            wait_ms(100);
            for(int i = 0; i <2;i++) {
                for(int j = 0; j < 4;j+=2) {
                    speech(flowey_friendly[i][j], flowey_friendly[i][j+1]);
                    draw_game(true);
                }
            }
            draw_nothing(x,y+1);
            draw_game(true);
            wait_ms(100); 
        } else {
            for(int i = 0; i < 4;i+=2) {
                speech(flowey_wink[i], flowey_wink[i+1]);
                draw_game(true);   
            }
            add_flowey_creepy(x, y+1);
            draw_game(true);
            return 1;
        }
        return 1;
    }
    if(item->type == FLOWCREEPY) {
    // generate a 500Hz tone using PWM hardware output
        speaker.period(1.0/500.0); // 500hz period
        speaker =0.5; //50% duty cycle - max volume
        wait(1);
        speaker=0.0; // turn off audio
        wait(1);
 
        if(quest != 2) {
            for(int i = 0; i < 4;i+=2) {
                speech(flowey_creepy[i], flowey_creepy[i+1]);
                draw_game(true);   
            }  
            add_flowey_wink(x, y+1);
            draw_game(true);
            return 1;
        } else {
            add_flowey_friendly(x, y+1);
            draw_game(true);
            wait_ms(100);
            for(int i = 0; i <2;i++) {
                for(int j = 0; j < 4;j+=2) {
                    speech(flowey_friendly[i][j], flowey_friendly[i][j+1]);
                    draw_game(true);
                }
            }  
            draw_nothing(x,y+1);
            draw_game(true);
            wait_ms(100);
        }
        return 1;
    }
    if(item->type == FLOWFRIEND) {
    // generate a 500Hz tone using PWM hardware output
        speaker.period(1.0/500.0); // 500hz period
        speaker =0.5; //50% duty cycle - max volume
        wait(1);
        speaker=0.0; // turn off audio
        wait(1);
        for(int i = 0; i <2;i++) {
            for(int j = 0; j < 4;j+=2) {
                speech(flowey_friendly[i][j], flowey_friendly[i][j+1]);
                draw_game(true);
            }
        }
        wait_ms(100);
        draw_nothing(x,y+1);
        draw_game(true);
        wait_ms(100);
        return 1;
    }
    if(item->type == SIGN) {
        door = 1;
        for(int i = 0; i < 3;i++) {
            for(int j = 0; j < 4;j+=2) {
                speech(sign[i][j], sign[i][j+1]);
                draw_game(true);   
                wait_ms(200);
            }   
        }
        return 1;
    }
    
    if(item->type == DOORLOCKED) {
        if(x == 2) {
            speech("Door locked", "Not a royalty");
            draw_game(true);
            wait_ms(150);
        } else if(x== map_width()-3) {
            speech("You use the","key you just found");
            draw_game(true);
            wait_ms(150);
            add_door_unlocked(x,y+1);
            draw_game(true);
            menu = 2;
        } else {
            if(door == 0) {
                speech("door locked", "read the sign");
                draw_game(true);
                wait_ms(300);
                speech("first to unlock", "this door!"); 
                draw_game(true);
                wait_ms(300);
            } else if(door == 1) {
                speech("You hear the", "door opens");
                draw_game(true);
                wait_ms(150);
                add_door_unlocked(x, y+1);
                draw_game(true);   
            }  
        }
        return 1;
    }
    
    if(item->type == DOORUNLOCKED){
        wait_ms(150); 
        Player.y += 2;
        draw_game(true);
        return 1;
    }
    
    if(item->type == REDBUTTON) {
        if(y+1 == map_height()-38) {
            waver.dac_out();
            speech("uh oh", "wrong one");
            draw_game(true);
            wait_ms(150);
            Player.x = map_width()-35;
            Player.y = map_height()-43;
            draw_game(true);
            health--;
            return 1;
        } else if(y+1 == map_height()-34) {
            speech("uh oh", "wrong one");
            draw_game(true);
            wait_ms(150);
            Player.x = map_width()-35;
            Player.y = map_height()-43;
            draw_game(true);
            health--;
            return 1;
        } else if(y+1 == map_height()-31) {
            speech("You hear", "a click!");
            draw_game(true);
            wait_ms(150);
            Player.y += 3;
            draw_game(true);
        } else if(y+1 == map_height()-27) {
            speech("You hear", "a click!");
            draw_game(true);
            wait_ms(150);
            Player.y += 3;
            draw_game(true);
            wait_ms(300);
    
        }
        return 1;
    }
    if(item->type == GREENBUTTON) {
        if(y+1 == map_height()-38) {
            speech("You hear", "a click!");
            draw_game(true);
            wait_ms(150);
            Player.y += 3;
            draw_game(true);
        } else if(y+1 == map_height()-34) {
            speech("uh oh", "wrong one");
            draw_game(true);
            wait_ms(150);
            Player.x = map_width()-35;
            Player.y = map_height()-43;
            draw_game(true);
            health--;
        } else if(y+1 == map_height()-31) {
            speech("uh oh", "wrong one");
            draw_game(true);
            wait_ms(150);
            Player.x = map_width()-35;
            Player.y = map_height()-43;
            draw_game(true);
            health--;
        } else if(y+1 == map_height()-27) {
            speech("uh oh", "wrong one");
            draw_game(true);
            wait_ms(150);
            Player.x = map_width()-35;
            Player.y = map_height()-43;
            draw_game(true);
            health--;
        }
        return 1;
    }
    if(item->type == BLUEBUTTON) {
        if(y+1 == map_height()-38) {
            speech("uh oh", "wrong one");
            draw_game(true);
            wait_ms(150);
            Player.x = map_width()-35;
            Player.y = map_height()-43;
            draw_game(true);
            health--;
        } else if(y+1 == map_height()-34) {
            speech("You hear", "a click!");
            draw_game(true);
            wait_ms(150);
            Player.y += 3;
            draw_game(true);
        } else if(y+1 == map_height()-31) {
            speech("uh oh", "wrong one");
            draw_game(true);
            wait_ms(150);
            Player.x = map_width()-35;
            Player.y = map_height()-43;
            draw_game(true);
            health--;
        } else if(y+1 == map_height()-27) {
            speech("uh oh", "wrong one");
            draw_game(true);
            wait_ms(150);
            Player.x = map_width()-35;
            Player.y = map_height()-43;
            draw_game(true);
            health--;
        }
        return 1;
    }
    if(item->type == TOBYBONE) {
        for(int i = 0; i < 9; i++) {
            for(int j = 0; j < 4;j+=2) {
                speech(toby_bone[i][j], toby_bone[i][j+1]);
                draw_game(true);
                wait_ms(150);   
            }   
        }
        map_erase(x,y+1);
        draw_game(true);
        wait_ms(300);
        Player.has_key = 1;
        quest=2;
        
        draw_game(true); 
        wait_ms(300);
        map_erase(x-3, y+2);
        menu = 3;
        return 1;   
    }
    
    if(item->type == RIVERMAN) {
        if(quest == 1) { // head to snowdin
            speech("Tra la la", "Everything is");
            draw_game(true);
            wait_ms(150);
            speech("not how they", "seem to be");
            draw_game(true);
            wait_ms(150);
            menu = 2;
            Player.x = map_width()-36;
            Player.y = map_height()-45;
            draw_game(true);
            wait_ms(150);
        } else if(quest==2) { // got the keys
            speech("Tra la la", "Did I");
            draw_game(true);
            wait_ms(150);
            speech("not warn", "ya...");
            draw_game(true);
            wait_ms(150);
            uLCD.cls();
            Player.x = 5;
            Player.y = 5;
            draw_game(true);
            wait_ms(300);
            quest++;
        } else {
            int index = rand()%15;
            for(int i = 0; i <4;i+=2 ) {
                speech(river_man_line[index][i], river_man_line[index][i+1]);
                draw_game(true);
                wait_ms(150);   
            }
        }   
    }
    return 0;
}

void init_start() {
    GameInputs in = read_inputs();
    draw_start();
    while(in.b1) {
        Timer t; t.start();
        in = read_inputs();
        t.stop();
        int dt = t.read_ms();
        if(dt < 100) wait_ms(100-dt);   
    }
    uLCD.cls();
}

void init_menu(char *a, char *b, int health_count, int key, int chest, int run) {
        GameInputs in = read_inputs();
        draw_menu(a, b, health_count, key, chest, run);  
        uLCD.cls(); 
}

void init_game_over() {
    GameInputs in = read_inputs();
    draw_game_over();
    uLCD.cls();   
}
/**
 * Entry point for frame drawing. This should be called once per iteration of
 * the game loop. This draws all tiles on the screen, followed by the status 
 * bars. Unless init is nonzero, this function will optimize drawing by only 
 * drawing tiles that have changed from the previous frame.
 */
void draw_game(int init)
{
    // Draw game border first
    if(init) draw_border();
    
    // Iterate over all visible map tiles
    for (int i = -5; i <= 5; i++) // Iterate over columns of tiles
    {
        for (int j = -4; j <= 4; j++) // Iterate over one column of tiles
        {
            // Here, we have a given (i,j)
            
            // Compute the current map (x,y) of this tile
            int x = i + Player.x;
            int y = j + Player.y;
            
            // Compute the previous map (px, py) of this tile
            int px = i + Player.px;
            int py = j + Player.py;
                        
            // Compute u,v coordinates for drawing
            int u = (i+5)*11 + 3;
            int v = (j+4)*11 + 15;
            
            // Figure out what to draw
            DrawFunc draw = NULL;
            if (init && i == 0 && j == 0) // Only draw the player on init
            {
                draw_player(u, v, Player.has_key);
                continue;
            }
            else if (x >= 0 && y >= 0 && x < map_width() && y < map_height()) // Current (i,j) in the map
            {
                MapItem* curr_item = get_here(x, y);
                MapItem* prev_item = get_here(px, py);
                if (init || curr_item != prev_item) // Only draw if they're different
                {
                    if (curr_item) // There's something here! Draw it
                    {
                        draw = curr_item->draw;
                    }
                    else // There used to be something, but now there isn't
                    {
                        draw = draw_nothing;
                    }
                }
            }
            else if (init) // If doing a full draw, but we're out of bounds, draw the walls.
            {
                draw = draw_wall;
            }

            // Actually draw the tile
            if (draw) draw(u, v);
        }
    }

    // Draw status bars    
    draw_upper_status(Player.x, Player.y);
    draw_lower_status();
}


/**
 * Initialize the main world map. Add walls around the edges, interior chambers,
 * and plants in the background so you can see motion.
 */
void init_main_map()
{
    // "Random" plants
    Map* map = set_active_map(0);
    
    for(int i = map_width() + 3; i < map_area(); i += 40)
    {
        if((i%map_width() > (map_width()-40)) && (i%map_width() < (map_width()-20))) {
            if((i/map_height() > (map_height()-40)) && (i/map_width() < (map_height()-20))) {
                
            } else {
                add_plant(i % map_width(), i / map_width());
            }   
        } else {
            add_plant(i % map_width(), i / map_width());   
        }
        
        
    }
    pc.printf("plants\r\n");
    
    pc.printf("Adding walls!\r\n");
    add_wall(0,              0,              HORIZONTAL, map_width());
    add_wall(0,              map_height()-1, HORIZONTAL, map_width());
    add_wall(0,              0,              VERTICAL,   map_height());
    add_wall(map_width()-1,  0,              VERTICAL,   map_height());
    pc.printf("Walls done!\r\n"); 

    add_river_man(1, 3);
    
    add_toby(4, 8);
    add_river_man(map_width()-36,map_height()-44);

    add_wall(map_width()-40, map_height()-40, HORIZONTAL, 20); //add puzzle room
    add_wall(map_width()-40, map_height()-40, VERTICAL, 20);
    add_wall(map_width()-40, map_height()-20, HORIZONTAL, 20);
    add_wall(map_width()-20, map_height()-40, VERTICAL, 20);
    
    add_wall(map_width()-40, map_height()-37, HORIZONTAL,20); // add floor
    add_wall(map_width()-40, map_height()-33, HORIZONTAL,20);
    add_wall(map_width()-40, map_height()-30, HORIZONTAL,20);
    add_wall(map_width()-40, map_height()-26, HORIZONTAL,20);
    
 
    add_red_button(map_width()-37, map_height()-38); // first floor button
    add_green_button(map_width()-31, map_height()-38);
    add_blue_button(map_width()-23, map_height()-38);
    
    add_red_button(map_width()-37, map_height()-34); // second floor button
    add_green_button(map_width()-31, map_height()-34);
    add_blue_button(map_width()-23, map_height()-34);
    
    add_red_button(map_width()-37, map_height()-31); // third floor button
    add_green_button(map_width()-31, map_height()-31);
    add_blue_button(map_width()-23, map_height()-31);
    
    add_red_button(map_width()-37, map_height()-27); // fourth floor button
    add_green_button(map_width()-31, map_height()-27);
    add_blue_button(map_width()-23, map_height()-27);
    
    add_toby_bone(map_width()-23, map_height()-21);
    add_door_locked(map_width()-35, map_height()-40);
    add_sign(map_width()-36, map_height()-41);
    
    add_wall(0, map_height()-5, HORIZONTAL, 5);
    add_wall(5, map_height()-5, VERTICAL, 5);
    
    add_door_locked(3, map_height()-5);
    add_chest(2, map_height()-2);

    print_map();
}

/**
 * Program entry point! This is where it all begins.
 * This function orchestrates all the parts of the game. Most of your
 * implementation should be elsewhere - this holds the game loop, and should
 * read like a road map for the rest of the code.
 */
int main()
{
    // First things first: initialize hardware
    ASSERT_P(hardware_init() == ERROR_NONE, "Hardware init failed!");
    init_start();
    // Initialize the maps
    maps_init();
    
    init_main_map();
    
    // Initialize game state
    set_active_map(0);
    Player.x = 5;
    Player.y = 5;

    // Initial drawing
    draw_game(true);

    
    GameInputs in;
    int action;
    int update;
    // Main game loop
    while(!game_over)
    {
        // Timer to measure game update speed
        Timer t; t.start();
        
        // Actuall do the game update:
        // 1. Read inputs    
        in = read_inputs();
        // 2. Determine action (get_action) 
        action = get_action(in);  
        // 3. Update game (update_game)
        update = update_game(action);
        check_health();
        // 3b. Check for game over
        // 4. Draw frame (draw_game)
        draw_game(update);
        // 5. Frame delay
        t.stop();
        int dt = t.read_ms();
        if (dt < 100) wait_ms(100 - dt);
    }
    init_game_over();
}

void check_health() {
    if(health == 0) {
        uLCD.cls();
        init_main_map();
        Player.x = 5;
        Player.y = 5;
        menu = 0; 
        health = 3;
        quest = 0;
        door = 0;
        draw_game(true);
    }
}
int go_up(int x, int y) {
    MapItem *item = get_north(x,y);
    if(item->walkable || omni_pressed) {
        if(run) {
            Player.y -= 2;   
        } else {
            Player.y--;
        }
        return 1;   
    }  else {
        return 0;   
    }
}

int go_down(int x, int y) {
    MapItem *item = get_south(x,y);
    if(item->walkable || omni_pressed) {
        if(run) {
            Player.y += 2;   
        } else {
            Player.y++;
        }
        return 1;   
    } else {
        return 0;   
    }
}

int go_left(int x, int y) {
    MapItem *item = get_west(x,y);
    if(item->walkable || omni_pressed) {
        if(run==1) {
            Player.x -= 2;   
        } else {
            Player.x--;
        }
        return 1;   
    } else {
        return 0;   
    }  
}

int go_right(int x, int y) {
    MapItem *item = get_east(x,y);
    if(item->walkable || omni_pressed) {
        if(run == 1) {
            Player.x += 2;   
        } else {
            Player.x++;
        }
        return 1;   
    } else {
        return 0;   
    }   
}