DEADSOFTWARE

Добавлена стрельба
[netwar.git] / game.c
diff --git a/game.c b/game.c
index cbc8e156ce5ff24ec6ef70e1a9150f34052f8a3d..219141884dd23ba9a59b2643135c78fcd83568e5 100644 (file)
--- a/game.c
+++ b/game.c
@@ -8,35 +8,77 @@
 
 #define SPEED  0.00006
 #define ROTATE 0.00004
+#define BULL_SPEED 0.008
 
 Player g_player[MAX_PLAYERS];
+Bullet g_bullet[MAX_BULLETS];
+
+void g_player_set(unsigned int id, bool live, float x, float y, float r, float vx, float vy, float vr) {
+       assert(id < MAX_PLAYERS);
+       g_player[id] = (Player) {
+               .updated = true,
+               .live    = live,
+               .x       = x,
+               .y       = y,
+               .r       = r,
+               .vx      = vx,
+               .vy      = vy,
+               .vr      = vr,
+       };
+}
+
+void g_bullet_set(unsigned int id, unsigned int owner, bool live, float x, float y, float vx, float vy, int tick) {
+       assert(id < MAX_BULLETS);
+       assert(owner < MAX_PLAYERS);
+       g_bullet[id] = (Bullet) {
+               .live  = live,
+               .owner = owner,
+               .x     = x,
+               .y     = y,
+               .vx    = vx,
+               .vy    = vy,
+               .tick  = tick,
+       };
+}
+
+static int freebullet() {
+       for(int i = 0; i < MAX_BULLETS; i++)
+               if(!g_bullet[i].live)
+                       return i;
+       return -1;
+}
 
 static void moveplayer(int id, float speed) {
        g_player[id].vx += speed * cos(g_player[id].r * 2 * M_PI);
        g_player[id].vy += speed * sin(g_player[id].r * 2 * M_PI);
 }
 
+static void roteplayer(int id, float speed) {
+       g_player[id].vr += speed;
+}
+
+static void fireplayer(int id) {
+       int j = freebullet();
+       if(j < 0)
+               return;
+
+       float vx = BULL_SPEED * cos(g_player[id].r * 2 * M_PI);
+       float vy = BULL_SPEED * sin(g_player[id].r * 2 * M_PI);
+       g_bullet_set(j, id, true, g_player[id].x, g_player[id].y, vx, vy, 0);
+}
+
 static void checkspacebound(float * a) {
        float x = *a;
        if(x < -1)
-               x = abs(x);
+               x = fabs(x);
        else if(x > 1)
                x = -x;
        *a = x;
 }
 
-void g_player_set(unsigned int id, bool live, float x, float y, float r, float vx, float vy, float vr) {
-       assert(id < MAX_PLAYERS);
-       g_player[id] = (Player) {
-               .updated = true,
-               .live    = live,
-               .x       = x,
-               .y       = y,
-               .r       = r,
-               .vx      = vx,
-               .vy      = vy,
-               .vr      = vr,
-       };
+static bool collide(float x1, float y1, float r1, float x2, float y2, float r2) {
+       float l = sqrtf(powf(x1 - x2, 2) + powf(y1 - y2, 2));
+       return ((l - r1 - r2) <= 0);
 }
 
 void g_player_does(unsigned int id, DoesCode code) {
@@ -45,9 +87,9 @@ void g_player_does(unsigned int id, DoesCode code) {
        switch(code) {
        case DOES_UP:    moveplayer(id, SPEED); break;
        case DOES_DOWN:  moveplayer(id, -SPEED); break;
-       case DOES_LEFT:  g_player[id].vr -= ROTATE; break;
-       case DOES_RIGHT: g_player[id].vr += ROTATE; break;
-       case DOES_FIRE:  break;
+       case DOES_LEFT:  roteplayer(id, -ROTATE); break;
+       case DOES_RIGHT: roteplayer(id, ROTATE); break;
+       case DOES_FIRE:  fireplayer(id); break;
        }
 }
 
@@ -62,4 +104,25 @@ void g_update() {
                        checkspacebound(&g_player[i].y);
                }
        }
+
+       for(int i = 0; i < MAX_BULLETS; i++) {
+               if(g_bullet[i].live) {
+                       g_bullet[i].updated = true;
+                       g_bullet[i].tick += 1;
+                       g_bullet[i].x += g_bullet[i].vx;
+                       g_bullet[i].y += g_bullet[i].vy;
+
+                       checkspacebound(&g_bullet[i].x);
+                       checkspacebound(&g_bullet[i].y);
+
+                       for(int j = 0; j < MAX_PLAYERS; j++)
+                               if(g_player[j].live)
+                                       if(collide(g_bullet[i].x, g_bullet[i].y, 0.0001, g_player[j].x, g_player[j].y, PLAYER_SIZE))
+                                               if(j != g_bullet[i].owner)
+                                                       g_player[j].live = false;
+
+                       if(g_bullet[i].tick > BULLET_TIME)
+                               g_bullet[i].live = false;
+               }
+       }
 }