DEADSOFTWARE

Изменены физические константы
[netwar.git] / game.c
diff --git a/game.c b/game.c
index 9b7f2391ddc78d4aa3fdb7ef0777ba46c9001e61..2370692abdad4904825a910b65828b03821394a3 100644 (file)
--- a/game.c
+++ b/game.c
@@ -6,14 +6,24 @@
 
 #include "game.h"
 
-#define SPEED  0.00006
-#define ROTATE 0.00004
-#define BULL_SPEED 0.008
+#define SPEED      (0.0005 / TICK)
+#define ROTATE     (0.03 / TICK)
+#define BULL_SPEED (0.4  / TICK)
+
+#define MAX_SPEED  (0.1 / TICK)
+#define MAX_ROTATE (0.3 / TICK)
+
+// Цифры взяты с потолка, но вроде неплохо подобраны
+#define G      6.6719199e-11
+#define M_STAR 3e8
+#define M_SHIP 0.001
 
 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) {
+static bool svmode;
+
+void g_player_set(unsigned int id, bool live, float x, float y, float r, float vx, float vy, float vr, int shoot) {
        assert(id < MAX_PLAYERS);
        g_player[id] = (Player) {
                .updated = true,
@@ -49,12 +59,16 @@ static int freebullet() {
 }
 
 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);
+       if(fabs(g_player[id].vx) < MAX_SPEED)
+               g_player[id].vx += speed * cos(g_player[id].r * 2 * M_PI);
+       if(fabs(g_player[id].vy) < MAX_SPEED)
+               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;
+       if(fabs(g_player[id].vr) > MAX_ROTATE)
+               g_player[id].vr = copysignf(MAX_ROTATE, g_player[id].vr);
 }
 
 static void fireplayer(int id) {
@@ -62,23 +76,36 @@ static void fireplayer(int id) {
        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);
+       if(g_player[id].shoot < PLAYER_SHOOT)
+               return;
+
+       g_player[id].shoot = 0;
+
+       if(svmode) {
+               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 = fabs(x);
-       else if(x > 1)
-               x = -x;
+       if(x < -1 || x > 1)
+               x = copysign(fmodf(x, 1) + 1, -1 * x);
        *a = x;
 }
 
+static float length(float x1, float y1, float x2, float y2) {
+       return sqrtf(powf(x1 - x2, 2) + powf(y1 - y2, 2));
+}
+
 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);
+       return ((length(x1, y1, x2, y2) - r1 - r2) <= 0);
+}
+
+static void gravity(float * vx, float * vy, float x, float y) {
+       *vx += copysign(G * M_STAR * M_SHIP / length(0, 0, x, y), x * -1);
+       *vy += copysign(G * M_STAR * M_SHIP / length(0, 0, x, y), y * -1);
 }
 
 void g_player_does(unsigned int id, DoesBits code) {
@@ -103,8 +130,18 @@ void g_update() {
                        g_player[i].x += g_player[i].vx;
                        g_player[i].y += g_player[i].vy;
                        g_player[i].r += g_player[i].vr;
+
+                       gravity(&g_player[i].vx, &g_player[i].vy, g_player[i].x, g_player[i].y);
+
                        checkspacebound(&g_player[i].x);
                        checkspacebound(&g_player[i].y);
+
+                       ++g_player[i].shoot;
+                       if(g_player[i].shoot > PLAYER_SHOOT)
+                               g_player[i].shoot = PLAYER_SHOOT;
+
+                       if(collide(g_player[i].x, g_player[i].y, PLAYER_SIZE, 0, 0, STAR_SIZE))
+                               g_player[i].live = false;
                }
        }
 
@@ -118,6 +155,8 @@ void g_update() {
                        checkspacebound(&g_bullet[i].x);
                        checkspacebound(&g_bullet[i].y);
 
+                       gravity(&g_bullet[i].vx, &g_bullet[i].vy, g_bullet[i].x, 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))
@@ -129,3 +168,8 @@ void g_update() {
                }
        }
 }
+
+void g_init(bool server_mode) {
+       svmode = server_mode;
+       // TODO memset & co
+}