Randall Kliman / Mbed 2 deprecated NEOPUNK

Dependencies:   mbed wave_player 4DGL-uLCD-SE MMA8452

Revision:
2:06c63d567719
Parent:
0:35660d7952f7
Child:
3:664c79e2ceb5
--- a/main.cpp	Wed Apr 04 21:11:07 2018 +0000
+++ b/main.cpp	Fri Nov 30 02:53:05 2018 +0000
@@ -4,6 +4,24 @@
 #include "map.h"
 #include "graphics.h"
 #include "speech.h"
+#include "hash_table.h"
+
+GameInputs in;
+int actions;
+int update;
+bool god;
+bool puzzle = false;
+bool mapact = 0;
+int story = 0;
+unsigned int m_z=12434,m_w=33254;
+unsigned int rnd() {
+    m_z = 36969 * (m_z & 65535) + (m_z >>16);
+    m_w = 18000 * (m_w & 65535) + (m_w >>16);
+    return ((m_z <<16) + m_w);
+}
+
+unsigned int n[4];
+
 
 // Functions in this file
 int get_action (GameInputs inputs);
@@ -20,8 +38,17 @@
     int x,y;    // Current locations
     int px, py; // Previous locations
     int has_key;
+    int speed;
+    bool can_teleport;
 } Player;
 
+struct {
+    bool has_boots;
+    bool has_teleport;
+    bool has_gun;
+    bool has_printer;
+} Inventory;
+
 /**
  * Given the game inputs, determine what kind of update needs to happen.
  * Possbile return values are defined below.
@@ -33,11 +60,176 @@
 #define GO_RIGHT 4
 #define GO_UP 5
 #define GO_DOWN 6
+#define THRESH 0.3
+#define GOD_MODE 7
+#define BUTTON_3 8
+#define BUTTON_4 9
+int walkk;
 int get_action(GameInputs inputs)
 {
+    //pc.printf("%d,%d\r\n",inputs.ax,inputs.ay);
+    if(inputs.ax <  -THRESH) return GO_UP;
+    if(inputs.ax >= THRESH) return GO_DOWN;
+    if(inputs.ay >= THRESH) return GO_RIGHT;
+    if(inputs.ay <  -THRESH) return GO_LEFT;
+    if(!inputs.b1) return ACTION_BUTTON;
+    if(!inputs.b2) return MENU_BUTTON;
+    if(!inputs.b3 && !puzzle){
+        pc.printf("Button 3 pressed");
+        god = !god;
+        if(god) uLCD.filled_rectangle(128,0,119,7,WHITE);
+        else if(!god) uLCD.filled_rectangle(128,0,119,7,BLACK);
+    }
+    else if(!inputs.b3) return BUTTON_3;
+    if(!inputs.b4) return BUTTON_4;
     return NO_ACTION;
 }
 
+int go_up()
+{
+    if(get_north(Player.x,Player.y)->walkable || god)
+    {
+        for(walkk = 1;walkk < Player.speed;walkk++){
+            if(!get_north(Player.x,Player.y-walkk)->walkable) break;
+        }
+        Player.y-=walkk;
+        return 1;
+    }else return 0;
+}
+
+int go_down()
+{
+    if(get_south(Player.x,Player.y)->walkable || god)
+    {
+        for(walkk = 1;walkk < Player.speed;walkk++){
+            if(!get_south(Player.x,Player.y+walkk)->walkable) break;
+        }
+        Player.y+=walkk;
+        return 1;
+    }else return 0;
+}
+
+int go_left()
+{
+    if(get_west(Player.x,Player.y)->walkable || god)
+    {
+        for(walkk = 1;walkk < Player.speed;walkk++){
+            if(!get_west(Player.x-walkk,Player.y)->walkable) break;
+        }
+        Player.x-=walkk;
+        return 1;
+    }else return 0;
+}
+
+int go_right()
+{
+    if(get_east(Player.x,Player.y)->walkable || god)
+    {
+        for(walkk = 1;walkk < Player.speed;walkk++){
+            if(!get_east(Player.x+walkk,Player.y)->walkable) break;
+        }
+        Player.x+=walkk;
+        return 1;
+    }else return 0;
+}
+
+//Looks at if there's a block of the desired type next to the player
+int checkType(int t)
+{
+    MapItem* n = get_north(Player.x,Player.y);
+    MapItem* s = get_south(Player.x,Player.y);
+    MapItem* e = get_east(Player.x,Player.y);
+    MapItem* w = get_west(Player.x,Player.y);
+    //pc.printf("%d\r\n",n->type);
+//    pc.printf("%d\r\n",s->type);
+//    pc.printf("%d\r\n",e->type);
+//    pc.printf("%d\r\n",w->type);
+    if(n->type == t || s->type == t || e->type == t || w->type == t)
+    {
+        return 1;
+    }else return 0;
+}
+
+MapItem* find_type(int t)
+{
+    MapItem* n = get_north(Player.x,Player.y);
+    MapItem* s = get_south(Player.x,Player.y);
+    MapItem* e = get_east(Player.x,Player.y);
+    MapItem* w = get_west(Player.x,Player.y);
+    //pc.printf("%d\r\n",n->type);
+//    pc.printf("%d\r\n",s->type);
+//    pc.printf("%d\r\n",e->type);
+//    pc.printf("%d\r\n",w->type);
+    if(n->type == t) return n;
+    else if(s->type == t) return s;
+    else if(e->type == t) return e;
+    else if(w->type == t) return w;
+    else return NULL;
+}
+
+int convert(int num)
+{
+    if(num == 1) return ACTION_BUTTON;
+    else if(num == 2) return MENU_BUTTON;
+    else if(num == 3) return BUTTON_3;
+    else if(num == 4) return BUTTON_4;
+    return 5;
+}
+
+#define mx 4
+#define my 3
+void run_minigame(){
+    char buffer[100];
+    n[0] = rnd()%4+1;
+    n[1] = rnd()%4+1;
+    n[2] = rnd()%4+1;
+    n[3] = rnd()%4+1;
+    sprintf(buffer,"of numbers: %d%d%d%d",n[0],n[1],n[2],n[3]);
+    speech(buffer,"");
+    int solved = 0;
+    while(solved < 4)
+    {
+        in = read_inputs();   
+        actions = get_action(in); 
+        if(solved == 0){
+            if(actions == convert(n[0])){
+                uLCD.locate(mx,my);
+                sprintf(buffer," %d - - - ",n[0]);
+                uLCD.printf(buffer);
+                solved++;
+                wait(0.5);
+            }
+        }
+       else if(solved == 1){
+            if(actions == convert(n[1])){
+                uLCD.locate(mx,my);
+                sprintf(buffer," %d %d - - ",n[0],n[1]);
+                uLCD.printf(buffer);
+                solved++;
+                wait(0.5);
+            }
+        }
+        else if(solved == 2){
+            if(actions == convert(n[2])){
+                uLCD.locate(mx,my);
+                sprintf(buffer," %d %d %d - ",n[0],n[1],n[2]);
+                uLCD.printf(buffer);
+                solved++;
+                wait(0.5);
+            }
+        }
+        else if(solved == 3){
+            if(actions == convert(n[3])){
+                uLCD.locate(mx,my);
+                sprintf(buffer," %d %d %d %d ",n[0],n[1],n[2],n[3]);
+                uLCD.printf(buffer);
+                solved++;
+                wait(0.5);
+            }
+        }
+    }
+}
+
 /**
  * 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
@@ -50,6 +242,7 @@
 #define NO_RESULT 0
 #define GAME_OVER 1
 #define FULL_DRAW 2
+MapItem* boi;
 int update_game(int action)
 {
     // Save player previous location before updating
@@ -60,12 +253,164 @@
     // You can define functions like "go_up()" that get called for each case.
     switch(action)
     {
-        case GO_UP:     break;
-        case GO_LEFT:   break;            
-        case GO_DOWN:   break;
-        case GO_RIGHT:  break;
-        case ACTION_BUTTON: break;
-        case MENU_BUTTON: break;
+        case GO_UP:
+            go_up();
+            break;
+        case GO_LEFT:
+            go_left();
+            break;         
+        case GO_DOWN:
+            go_down();
+            break;
+        case GO_RIGHT:
+            go_right();
+            break;
+        case ACTION_BUTTON:
+            pc.printf("Action Button Pressed\r\n");
+            if(checkType(NPORTAL))
+            {
+                if(story == 2 || story == 3 || story == 4){
+                    speech("Don't leave! The","hack is almost");
+                    speech("finished!","");
+                    return FULL_DRAW;
+                }
+                pc.printf("Entering Portal");
+                if(!mapact){
+                    set_active_map(1);
+                    mapact = 1;
+                    Player.x = 2;
+                    Player.y = 5;
+                }
+                else if(mapact){
+                    set_active_map(0);
+                    mapact = 0;
+                    Player.x = 37;
+                    Player.y = 44;
+                }
+                uLCD.filled_rectangle(0,0,127,9, 0x0);
+                return FULL_DRAW;
+            }
+            else if(checkType(NPC))
+            {
+                if(story == 0){
+                    speech("Hey, want to make","some quick cash?");
+                    speech("Head over to the","netPortal next");
+                    speech("door. Hack","BULLETCORPs server");
+                    speech("so we can steal","some of their");
+                    speech("advanced tech.","That is, if");
+                    speech("you're up for","the job");
+                    story++;
+                }
+                else if(story == 1)
+                {
+                    speech("C'mon! What are","you waiting for?");                    
+                }
+                else if(story == 6)
+                {
+                    speech("Thanks for the","codes. here's a ");
+                    speech("chip that will","let you into");
+                    speech("BULLETCORP's","secret tech room");
+                    Player.has_key = true;
+                }
+                return FULL_DRAW;               
+            }
+            else if(checkType(TERMINAL))
+            {
+                if(story == 1){  
+                    speech("Pondsmith:","~ksshhk~");
+                    speech("Nice, you're in.","Use the terminals");
+                    speech("to decypher the","BULLETCORP access");
+                    speech("codes. There are","4 codes. Each");
+                    speech("terminal will","give one of the");
+                    speech("access codes.","");
+                    uLCD.cls();
+                    puzzle = true;
+                    uLCD.locate(mx,my);
+                    uLCD.printf(" - - - - ");
+                    speech("Ok, here is","the first string");
+                    run_minigame();
+                    story++;
+                    if((boi = find_type(TERMINAL))){
+                        boi->type = HACKED_TERMINAL;
+                        boi->draw = draw_hacked_terminal;
+                    }
+                    puzzle = false;   
+                    return FULL_DRAW;
+                }
+                else if(story == 2){
+                    uLCD.cls();
+                    puzzle = true;
+                    uLCD.locate(mx,my);
+                    uLCD.printf(" - - - - ");
+                    speech("Ok, here is","the second string");
+                    run_minigame();
+                    story++;
+                    if((boi = find_type(TERMINAL))){
+                        boi->type = HACKED_TERMINAL;
+                        boi->draw = draw_hacked_terminal;
+                    }   
+                    puzzle = false; 
+                    return FULL_DRAW;
+                }
+                else if(story == 3){
+                    uLCD.cls();
+                    puzzle = true;
+                    uLCD.locate(mx,my);
+                    uLCD.printf(" - - - - ");
+                    speech("Ok, here is","the third string");
+                    run_minigame();
+                    story++;
+                    if((boi = find_type(TERMINAL))){
+                        boi->type = HACKED_TERMINAL;
+                        boi->draw = draw_hacked_terminal;
+                    }   
+                    puzzle = false; 
+                    return FULL_DRAW;
+                }
+                else if(story == 4){
+                    uLCD.cls();
+                    puzzle = true;
+                    uLCD.locate(mx,my);
+                    uLCD.printf(" - - - - ");
+                    speech("Ok, here is","the fourth string");
+                    run_minigame();
+                    story++;
+                    if((boi = find_type(TERMINAL))){
+                        boi->type = HACKED_TERMINAL;
+                        boi->draw = draw_hacked_terminal;
+                    }   
+                    puzzle = false; 
+                    return FULL_DRAW;
+                }
+            }
+            else if(checkType(DOOR) && Player.has_key == true){
+                if(boi = find_type(DOOR)) boi->walkable = true;
+            }
+            else if(checkType(TELEPORT)){
+                Inventory.has_teleport = true;
+                if(boi = find_type(TELEPORT)) deleteItem(get_active_map()->items, XY_KEY(boi->x, boi->y));
+            }
+            else if(checkType(KILL)){
+                Inventory.has_gun = true;
+                if(boi = find_type(KILL)) deleteItem(get_active_map()->items, XY_KEY(boi->x, boi->y));
+            }
+            else if(checkType(BOOTS)){
+                Inventory.has_boots = true;
+                Player.speed = 2;
+                if(boi = find_type(BOOTS)) deleteItem(get_active_map()->items, XY_KEY(boi->x, boi->y));
+            }
+            else if(checkType(PRINTER)){
+                Inventory.has_printer = true;
+                if(boi = find_type(PRINTER)) deleteItem(get_active_map()->items, XY_KEY(boi->x, boi->y));
+            }
+            break;
+        case MENU_BUTTON:
+            pc.printf("Menu Button Pressed\r\n");
+            break;
+        case BUTTON_4:
+            pc.printf("Button 4 Pressed\r\n");
+            //NVIC_SystemReset();
+            break;
         default:        break;
     }
     return NO_RESULT;
@@ -103,7 +448,7 @@
             
             // Figure out what to draw
             DrawFunc draw = NULL;
-            if (init && i == 0 && j == 0) // Only draw the player on init
+            if (i == 0 && j == 0) // Only draw the player on init
             {
                 draw_player(u, v, Player.has_key);
                 continue;
@@ -134,8 +479,8 @@
         }
     }
 
-    // Draw status bars    
-    draw_upper_status();
+    // Draw status bars
+    draw_upper_status(Player.x,Player.y);
     draw_lower_status();
 }
 
@@ -146,22 +491,59 @@
  */
 void init_main_map()
 {
-    // "Random" plants
     Map* map = set_active_map(0);
-    for(int i = map_width() + 3; i < map_area(); i += 39)
-    {
-        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());
+    
+    
+    add_wall(0,38,HORIZONTAL,4);
+    add_wall(6,38,HORIZONTAL,15);
+    add_wall(0,29,HORIZONTAL,2);
+    add_wall(4,29,HORIZONTAL,26);
+    add_door(2,29,false);
+    add_door(3,29,false);
+    add_boots(3,22);
+    add_teleport(5,24);
+    add_orgprint(8,21);
+    add_kill(15,19);
+    add_wall(0,17,HORIZONTAL,40);
+    add_wall(0,13,HORIZONTAL,2);
+    add_door(2,13,false);
+    add_door(3,13,false);
+    add_wall(4,13,HORIZONTAL,36);
+    add_wall(39,0,VERTICAL,13);
+    add_wall(11,0,VERTICAL,13);
+    add_wall(39,17,VERTICAL,13);
+    add_wall(39,38,VERTICAL,12);
+    add_wall(26,38,VERTICAL,10);
+    add_wall(21,38,VERTICAL,4);
+    add_wall(21,44,VERTICAL,5);
+    add_wall(31,38,HORIZONTAL,9);
+    add_wall(27,38,HORIZONTAL,2);
+    add_netPortal(38,44);
+    add_NPC(5,42);
     pc.printf("Walls done!\r\n");
 
-    print_map();
+    //print_map();
+}
+
+void init_sub_map()
+{
+    set_active_map(1);
+    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());
+    add_terminal(3,3);
+    add_terminal(7,3);  
+    add_terminal(3,7);  
+    add_terminal(7,7);
+    add_netPortal(1,5);   
 }
 
 /**
@@ -170,38 +552,102 @@
  * 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!");
-
+    //hardware_init();
+    pc.printf("Initializing Game\r\n");
+    in = read_inputs();
+    actions = get_action(in);
+    uLCD.text_width(2); //4X size text
+    uLCD.text_height(2);
+    uLCD.color(0x00ffd8);
+    uLCD.set_font(FONT_5X7);
+    uLCD.text_bold(true);
+    uLCD.printf("\n\n  N E O\n");
+    uLCD.color(0xff00e4);
+    uLCD.printf("\n P U N K\n");
+    uLCD.text_width(1); //4X size text
+    uLCD.text_height(1);
+    uLCD.color(RED);
+    bool swap = 0;
+    int flash = 0;
+    while(actions != ACTION_BUTTON)
+    {
+        if(flash >= 600){
+            swap = !swap;
+            flash = 0;
+            if(swap) draw_menu_2();
+            else if(!swap) draw_menu_1();
+        }
+        if(swap) flash+=3;
+        else if(!swap) flash++;
+            
+        
+        in = read_inputs();
+        actions = get_action(in);
+    }
+    uLCD.cls();
+    uLCD.text_width(1); //4X size text
+    uLCD.text_height(1);
+    uLCD.color(GREEN);
+    uLCD.set_font(FONT_7X8);
     // Initialize the maps
     maps_init();
     init_main_map();
+    init_sub_map();
+    set_active_map(0);
+    print_map();
+    pc.printf("Map initialized\r\n");
     
     // Initialize game state
-    set_active_map(0);
-    Player.x = Player.y = 5;
-
+    Player.x = 3;
+    Player.y = 33;
+    Player.speed = 1;
     // Initial drawing
     draw_game(true);
 
     // Main game loop
     while(1)
     {
+        //pc.printf("Game Running\r\n");
         // Timer to measure game update speed
         Timer t; t.start();
         
-        // Actuall do the game update:
-        // 1. Read inputs        
-        // 2. Determine action (get_action)        
+        // Actually do the game update:
+        // 1. Read inputs
+        in = read_inputs(); 
+        //pc.printf("Gathering Sensor Data\r\n");
+        // 2. Determine action (get_action)    
+        actions = get_action(in);   
+        //pc.printf("Determining Action\r\n"); 
         // 3. Update game (update_game)
+        update = update_game(actions);
+        //pc.printf("Updating Game State\r\n");
+        //pc.printf("Game State: %d\r\n", gameState);
         // 3b. Check for game over
+        //if(update == 0) break;
         // 4. Draw frame (draw_game)
+        //pc.printf("Drawing Game\r\n");
+        draw_game(update);
         
         // 5. Frame delay
         t.stop();
         int dt = t.read_ms();
         if (dt < 100) wait_ms(100 - dt);
+        
+        if(story == 5){
+            speech("Nice! You got","the codes.");
+            speech("Come back to me","and i'll");
+            speech("compile them into","a security chip");
+            speech("you can use to","break into");
+            speech("BULLETCORP","");
+            story++;
+            draw_game(FULL_DRAW);
+        }
     }
 }