Index: proj/include/ent.h
===================================================================
--- proj/include/ent.h	(revision 300)
+++ proj/include/ent.h	(revision 301)
@@ -11,9 +11,15 @@
 double (ent_get_XLength)(void);
 double (ent_get_YLength)(void);
 
+typedef enum {
+    gunner_meelee,
+    gunner_ranged,
+    gunner_player
+} gunner_type;
+
 struct gunner;
 typedef struct gunner gunner_t;
-gunner_t* (gunner_ctor)(basic_sprite_t *dude, basic_sprite_t *weapon);
+gunner_t* (gunner_ctor)(basic_sprite_t *dude, basic_sprite_t *weapon, gunner_type tp);
 void      (gunner_dtor)(gunner_t *p);
 void (gunner_set_pos)               (gunner_t *p, double x, double y);
 void (gunner_set_spawn)             (gunner_t *p, double x, double y);
@@ -29,6 +35,7 @@
 double  (gunner_get_curr_health)    (const gunner_t *p);
 int16_t (gunner_get_x_screen)       (const gunner_t *p);
 int16_t (gunner_get_y_screen)       (const gunner_t *p);
+gunner_type (gunner_get_type)       (const gunner_t *p);
 void (gunner_draw)(gunner_t *p);
 void (gunner_draw_health)(const gunner_t *p);
 
Index: proj/libs/classes/include/list.h
===================================================================
--- proj/libs/classes/include/list.h	(revision 300)
+++ proj/libs/classes/include/list.h	(revision 301)
@@ -24,5 +24,6 @@
 void         (list_push_back)(list_t *l, void *val);
 void**       (list_front)(list_t *l);
 void         (list_pop_front)(list_t *l);
+list_node_t* (list_find)(list_t *l, void *val);
 
 #endif //LIST_H_INCLUDED
Index: proj/libs/classes/src/list.c
===================================================================
--- proj/libs/classes/src/list.c	(revision 300)
+++ proj/libs/classes/src/list.c	(revision 301)
@@ -77,3 +77,10 @@
 void         (list_pop_front)(list_t *l){
     list_erase(l, list_begin(l));
 }
+list_node_t* (list_find)(list_t *l, void *val){
+    list_node_t *it = list_begin(l);
+    while(it != list_end(l) && *list_node_val(it) != val){
+        it = list_node_next(it);
+    }
+    return it;
+}
Index: proj/src/ent.c
===================================================================
--- proj/src/ent.c	(revision 300)
+++ proj/src/ent.c	(revision 301)
@@ -23,8 +23,9 @@
     sprite_t *dude;
     sprite_t *weapon;
     double health, current_health;
+    gunner_type type;
 };
-gunner_t* (gunner_ctor)(basic_sprite_t *dude, basic_sprite_t *weapon){
+gunner_t* (gunner_ctor)(basic_sprite_t *dude, basic_sprite_t *weapon, gunner_type tp){
     gunner_t *ret = malloc(sizeof(gunner_t));
     if(ret == NULL) return NULL;
     ret->spawn_x = 0.0;
@@ -33,6 +34,7 @@
     ret->y = 0.0;
     ret->health = 100;
     ret->current_health = ret->health;
+    ret->type = tp;
     ret->dude   = sprite_ctor(dude  );
     ret->weapon = sprite_ctor(weapon);
     if(ret->dude == NULL || ret->weapon == NULL){
@@ -69,6 +71,7 @@
 double  (gunner_get_curr_health)    (const gunner_t *p){ return p->current_health; }
 int16_t (gunner_get_x_screen)       (const gunner_t *p){ return (p->x-x_origin)*scale; }
 int16_t (gunner_get_y_screen)       (const gunner_t *p){ return (p->y-y_origin)*scale; }
+gunner_type (gunner_get_type)       (const gunner_t *p){ return p->type; }
 void (gunner_draw)(gunner_t *p){
     const int16_t x_screen = gunner_get_x_screen(p);
     const int16_t y_screen = gunner_get_y_screen(p);
Index: proj/src/proj.c
===================================================================
--- proj/src/proj.c	(revision 300)
+++ proj/src/proj.c	(revision 301)
@@ -51,6 +51,7 @@
 font_t               *consolas      = NULL;
 basic_sprite_t       *bsp_crosshair = NULL;
 basic_sprite_t       *bsp_shooter   = NULL;
+basic_sprite_t       *bsp_zombie    = NULL;
 basic_sprite_t       *bsp_pistol    = NULL;
 basic_sprite_t       *bsp_nothing   = NULL;
 basic_sprite_t       *bsp_bullet    = NULL;
@@ -86,6 +87,7 @@
 
         bsp_crosshair = get_crosshair(); if(bsp_crosshair == NULL) printf("Failed to get crosshair\n");
         bsp_shooter   = get_shooter  (); if(bsp_shooter   == NULL) printf("Failed to get shooter\n");
+        bsp_zombie    = bsp_shooter;     if(bsp_zombie    == NULL) printf("Failed to get zombie\n");
         bsp_pistol    = get_pistol   (); if(bsp_pistol    == NULL) printf("Failed to get pistol\n");
         bsp_nothing   = get_nothing  (); if(bsp_nothing   == NULL) printf("Failed to get nothing\n");
         bsp_bullet    = get_bullet   (); if(bsp_bullet    == NULL) printf("Failed to get bullet\n");
@@ -172,6 +174,7 @@
 
     basic_sprite_dtor      (bsp_crosshair); bsp_crosshair = NULL;
     basic_sprite_dtor      (bsp_shooter  ); bsp_shooter   = NULL;
+    /*basic_sprite_dtor      (bsp_zombie   );*/ bsp_zombie    = NULL;
     sprite_dtor            (sp_crosshair ); sp_crosshair  = NULL;
     basic_sprite_dtor      (bsp_pistol   ); bsp_pistol    = NULL;
     basic_sprite_dtor      (bsp_nothing  ); bsp_nothing   = NULL;
@@ -194,7 +197,7 @@
 }
 
 static int (campaign)(void);
-
+static int (zombies)(void);
 static int (singleplayer)(void) {
 
     int r;
@@ -236,7 +239,7 @@
                                 switch(menu_update_state(main_menu, click)){
                                     case -1: break;
                                     case  0: campaign(); break;
-                                    case  1: break;
+                                    case  1: zombies(); break;
                                     case  2: good = false; break;
                                 }
                                 menu_draw(main_menu);
@@ -285,11 +288,11 @@
 
     list_t *shooter_list = list_ctor();
 
-    gunner_t *shooter1 = gunner_ctor(bsp_shooter, bsp_pistol); if(shooter1 == NULL) printf("Failed to get shooter1\n");
+    gunner_t *shooter1 = gunner_ctor(bsp_shooter, bsp_pistol, gunner_player); if(shooter1 == NULL) printf("Failed to get shooter1\n");
     gunner_set_spawn(shooter1, 75, 75);
     gunner_set_pos(shooter1, 75, 75);
 
-    gunner_t *shooter2 = gunner_ctor(bsp_shooter, bsp_nothing);
+    gunner_t *shooter2 = gunner_ctor(bsp_shooter, bsp_nothing, gunner_player);
     gunner_set_spawn(shooter2, 975, 75);
     gunner_set_pos(shooter2, 775, 75);
 
@@ -398,6 +401,152 @@
     }
     if(list_dtor(shooter_list)) printf("COULD NOT DESTRUCT SHOOTER LIST\n");
 
+    while(list_size(bullet_list) > 0){
+        bullet_t *p = (bullet_t*)list_erase(bullet_list, list_begin(bullet_list));
+        bullet_dtor(p);
+    }
+    if(list_dtor(bullet_list)) printf("COULD NOT DESTRUCT BULLET LIST\n");
+
+    timer_dtor(in_game_timer); in_game_timer = NULL;
+
+    return SUCCESS;
+}
+
+#define ZOMBIES_NUM             5
+#define ZOMBIE_HEALTH_FACTOR    1.1
+
+static int (zombies)(void){
+
+    int r;
+
+    ent_set_scale(DEFAULT_SCALE);
+    text_timer_t *in_game_timer = timer_ctor(consolas);
+
+    list_t *shooter_list = list_ctor();
+
+    gunner_t *shooter1 = gunner_ctor(bsp_shooter, bsp_pistol, gunner_player); if(shooter1 == NULL) printf("Failed to get shooter1\n");
+    gunner_set_spawn(shooter1, 75, 75);
+    gunner_set_pos(shooter1, 75, 75);
+
+    list_insert(shooter_list, list_end(shooter_list), shooter1);
+
+    list_t *bullet_list  = list_ctor();
+
+    ent_set_origin(gunner_get_x(shooter1)-ent_get_XLength()/2.0,
+                   gunner_get_y(shooter1)-ent_get_YLength()/2.0);
+
+   //uint32_t refresh_count_value = sys_hz() / REFRESH_RATE;
+   uint8_t last_lb = 0;
+   struct packet pp;
+   keys_t *keys = get_key_presses();
+
+    /// loop stuff
+    int ipc_status;
+    message msg;
+    int good = true;
+
+    int health = 50;
+
+    while (good) {
+       /* Get a request message. */
+       if ((r = driver_receive(ANY, &msg, &ipc_status)) != 0) {
+           printf("driver_receive failed with %d", r);
+           continue;
+       }
+       if (is_ipc_notify(ipc_status)) { /* received notification */
+           switch (_ENDPOINT_P(msg.m_source)) {
+               case HARDWARE: /* hardware interrupt notification */
+                   for (uint32_t i = 0, n = 1; i < 32; i++, n <<= 1) {
+                       if (msg.m_notify.interrupts & n) {
+                           interrupt_handler(i);
+                           switch (i) {
+                           case TIMER0_IRQ: //printf("L463\n");
+
+                               if (no_interrupts % 60 == 0) timer_update(in_game_timer);//printf("L465\n");
+                               update_movement(map1, shooter1, keys, shooter_list);//printf("L466\n");
+
+                               update_game_state(map1, shooter_list, bullet_list);//printf("L468\n");
+
+                               //update_scale();
+                               double angle = get_mouse_angle(shooter1);//printf("L471\n");
+                               gunner_set_angle(shooter1, angle - M_PI_2); //printf("L472\n");
+
+                               ent_set_origin(gunner_get_x(shooter1)-ent_get_XLength()/2.0,
+                                              gunner_get_y(shooter1)-ent_get_YLength()/2.0);
+
+                               while(list_size(shooter_list) < ZOMBIES_NUM){
+                                   gunner_t *zombie = gunner_ctor(bsp_zombie, bsp_nothing, gunner_meelee);
+                                   gunner_set_health(zombie, health);
+                                   gunner_set_curr_health(zombie, health);
+                                   health *= ZOMBIE_HEALTH_FACTOR;
+                                   get_random_spawn(map1, zombie);
+                                   list_push_back(shooter_list, zombie);
+                               } //printf("L484\n");
+
+                               if(list_find(shooter_list, shooter1) == list_end(shooter_list)){
+                                   good = false;
+                                   break;
+                               } //printf("L489\n");
+                               graph_clear_screen();
+                               map_draw   (map1);
+                               gunner_draw_list(shooter_list);
+                               bullet_draw_list(bullet_list); //printf("L502\n");
+
+                               text_draw(in_game_timer->text);
+
+                               sprite_set_pos(sp_crosshair, *get_mouse_X(), *get_mouse_Y());
+                               sprite_draw(sp_crosshair);
+                               graph_draw(); //printf("L508\n");
+
+                               break;
+                           case KBC_IRQ:
+                               if ((scancode[0]) == ESC_BREAK_CODE) {
+                                   good = false;
+                                   // reset game
+                                   while(list_size(bullet_list) > 0){
+                                       bullet_t *p = (bullet_t*)list_erase(bullet_list, list_begin(bullet_list));
+                                       bullet_dtor(p);
+                                   }
+                                   list_node_t *it = list_begin(shooter_list);
+                                   while (it != list_end(shooter_list)) {
+                                       gunner_t *p = *(gunner_t**)list_node_val(it);
+                                       get_random_spawn(map1, p);
+                                       gunner_set_curr_health(p, gunner_get_health(p));
+                                       it = list_node_next(it);
+                                   }
+                                   timer_reset(in_game_timer);
+                               }
+                               break;
+                           case MOUSE_IRQ:
+                               if (counter_mouse_ih >= 3) {
+                                   mouse_parse_packet(packet_mouse_ih, &pp);
+                                   update_mouse(&pp);
+                                   if (last_lb ^ keys->lb_pressed && keys->lb_pressed)
+                                       shoot_bullet(shooter1, bullet_list, bsp_bullet);
+                                   last_lb = keys->lb_pressed;
+                                   counter_mouse_ih = 0;
+
+                               }
+                               break;
+                           case COM1_IRQ: nctp_ih(); break;
+                           }
+                       }
+                   }
+                   break;
+               default:
+                   break; /* no other notifications expected: do nothing */
+           }
+       } else { /* received standart message, not a notification */
+           /* no standart message expected: do nothing */
+       }
+    }
+
+    while(list_size(shooter_list) > 0){
+        gunner_t *p = list_erase(shooter_list, list_begin(shooter_list));
+        gunner_dtor(p);
+    }
+    if(list_dtor(shooter_list)) printf("COULD NOT DESTRUCT SHOOTER LIST\n");
+
     while(list_size(bullet_list) > 0){
         bullet_t *p = (bullet_t*)list_erase(bullet_list, list_begin(bullet_list));
         bullet_dtor(p);
Index: proj/src/proj_func.c
===================================================================
--- proj/src/proj_func.c	(revision 300)
+++ proj/src/proj_func.c	(revision 301)
@@ -117,8 +117,7 @@
                 /// Change health
                 gunner_set_curr_health(shooter, gunner_get_curr_health(shooter) - bullet_get_damage(bullet));
                 if (gunner_get_curr_health(shooter) <= 0) {
-                    gunner_set_curr_health(shooter, gunner_get_health(shooter));
-                    get_random_spawn(map, shooter);
+                    gunner_dtor(list_erase(shooter_list, shooter_it));
                 }
                 /// Delete bullet
                 bullet_dtor(list_erase(bullet_list, bullet_it)); deleted_bullet = true;
