Stores cargo movement on transport, keeping a running total for the
month. At the end of the month, an average velocity and direction is
calculated which can be displayed to help players see where what's
actually *moving* on transport (as opposed to what is simply being
stored there), as well as which direction it is moving.

Signed-off-by: Daniel Santos <[email protected]>
---
 src/lincity/init_game.cpp |  1 +
 src/lincity/stats.cpp     |  2 ++
 src/lincity/transport.cpp | 70 +++++++++++++++++++++++++++++++++++++++++++----
 src/lincity/transport.h   | 18 ++++++++++++
 4 files changed, 85 insertions(+), 6 deletions(-)

diff --git a/src/lincity/init_game.cpp b/src/lincity/init_game.cpp
index b1e3052..5a97994 100644
--- a/src/lincity/init_game.cpp
+++ b/src/lincity/init_game.cpp
@@ -83,6 +83,7 @@ void clear_game(void)
     highest_tech_level = 0;
     rockets_launched = 0;
     rockets_launched_success = 0;
+    transport_clear_monthly();
     init_inventory();
     update_avail_modules(0);
 
diff --git a/src/lincity/stats.cpp b/src/lincity/stats.cpp
index 385e89e..482bde5 100644
--- a/src/lincity/stats.cpp
+++ b/src/lincity/stats.cpp
@@ -12,6 +12,7 @@
 #include "engglobs.h"
 #include "gui_interface/pbar_interface.h"
 #include "stats.h"
+#include "transport.h"
 
 /* ---------------------------------------------------------------------- *
  * Public Global Variables
@@ -114,6 +115,7 @@ void init_monthly(void)
     twaste_in_markets = 0;
     tunemployed_population = 0;
     unnat_deaths = 0;
+    transport_init_monthly();
 }
 
 void init_yearly(void)
diff --git a/src/lincity/transport.cpp b/src/lincity/transport.cpp
index 115a2c8..c1c5e67 100644
--- a/src/lincity/transport.cpp
+++ b/src/lincity/transport.cpp
@@ -6,12 +6,19 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <assert.h>
+#include <string.h>
+#include <math.h>
 #include "lin-city.h"
 #include "lctypes.h"
 #include "transport.h"
 #include "power.h"
 #include "stats.h"              /* for transport_cost */
 
+// struct vec2 {float x, y;};
+
+struct vec2 goods_movement[WORLD_SIDE_LEN * WORLD_SIDE_LEN * 7];
+struct vec2 goods_moved_last_month[WORLD_SIDE_LEN * WORLD_SIDE_LEN * 7];
+
 static int max_load(int x, int y, int i)
 {
     int group=MP_GROUP(x,y);
@@ -64,8 +71,8 @@ static int max_load(int x, int y, int i)
 }
 
 /* ---------------------------------------------------------------------
-   For track, road and rail: 
-  
+   For track, road and rail:
+
    MP_INFO(x,y).int_1 contains the amount of food
                 int_2 contains the amount of jobs
                 int_3 contains the amount of coal
@@ -118,6 +125,7 @@ void general_transport(int x, int y, int max_waste)
 
     int *pol = &MP_POL(x, y);
     Map_Point_Info *minfo = &MP_INFO(x, y);
+    struct vec2 *totals = &goods_movement[(x * WORLD_SIDE_LEN + y) * 7];
 
     int tot, max, ratio, *base, xm1, xp1, ym1, yp1;
     int i;
@@ -176,7 +184,11 @@ void general_transport(int x, int y, int max_waste)
         tot = CC + LC + RC + UC + DC;
         max = CM + LM + RM + UM + DM;
         ratio = (tot * 100) / max;
-        
+
+        totals->x += (RC - LC);
+        totals->y += (DC - UC);
+        ++totals;
+
         /* left */
         if (XY_IS_TRANSPORT(x - 1, y)) {
             LC = base[xm1] = (ratio * LM) / 100;
@@ -194,8 +206,8 @@ void general_transport(int x, int y, int max_waste)
             DC = base[yp1] = (ratio * DM) / 100;
         }
 
-        *base = tot - (LC + RC + UC + DC);
-        *base++; // loop on address of int_"i"
+        *base++ = tot - (LC + RC + UC + DC);
+        // loop on address of int_"i"
     }
 
     /*
@@ -340,7 +352,7 @@ void general_transport(int x, int y, int max_waste)
     }
     */
 
-    //  *--base = &minfo->int_7 = current waste on this tile of transport 
+    //  *--base = &minfo->int_7 = current waste on this tile of transport
     if (*--base >= max_waste) {
         *base -= WASTE_BURN_ON_TRANSPORT;
         ++*pol;
@@ -813,3 +825,49 @@ void connect_transport(int originx, int originy, int w, 
int h)
         }                       /* end for */
     }                           /* end for */
 }
+
+void transport_clear_monthly() {
+    memset(goods_movement, 0, sizeof(goods_movement));
+}
+
+void transport_init_monthly(void) {
+    const struct vec2 *totals_end = &goods_movement[WORLD_SIDE_LEN * 
WORLD_SIDE_LEN * 7];
+    struct vec2 *totals;
+    struct vec2 *stats;
+
+    for (totals = goods_movement, stats = goods_moved_last_month;
+         totals < totals_end; ++totals, ++stats) {
+        // TODO: skip non-transport cells?
+
+        // magnitude as a percentage of cargo that can be stored on the 
transport
+        stats->x = sqrtf(totals->x * totals->x + totals->y * totals->y)
+                        / (float)(NUMOF_DAYS_IN_MONTH);
+        // direction in degrees with 0/360 being east
+        stats->y = atan2f(totals->y, totals->x) / (float)M_PI * 180.f + 180.f;
+
+    }
+    transport_clear_monthly();
+}
+
+const char *transport_format_cargo(int store, const struct vec2 *vec, int max) 
{
+    static char buf[0x40];
+    float fstore = store * 100.f / max;
+    float vel = vec->x * 100.f / max;
+
+    /* int truncation rounding to a number between zero and 16 (a bit of 
"east" resides at each end) */
+    int approximate_dir = (vec->y + 11.25f) / 22.5f;
+    static const char* dirstr[] = {"E", "ESE", "SE", "SSE", "S", "SSW", "SW", 
"WSW", "W", "WNW", "NW", "WWN", "N", "NNE", "NE", "ENE", "E"};
+    const char *dir = "";
+
+    if (approximate_dir >= 0 && approximate_dir <= 17) {
+        dir = dirstr[approximate_dir];
+    }
+
+    if (vel > 0.01f) {
+        snprintf(buf, sizeof(buf), "%0.1f%%    %s @ %0.2f", fstore, dir, vel);
+    } else
+        snprintf(buf, sizeof(buf), "%0.1f%%", fstore);
+
+    return buf;
+}
+
diff --git a/src/lincity/transport.h b/src/lincity/transport.h
index 3e5c48e..6f2bb8d 100644
--- a/src/lincity/transport.h
+++ b/src/lincity/transport.h
@@ -8,6 +8,7 @@
 #define __TRANSPORT_H__
 
 #include "engglobs.h"
+#include "lintypes.h"
 
 #define XY_IS_TRANSPORT(x,y) \
 ((MP_GROUP(x,y) == GROUP_TRACK) || \
@@ -18,5 +19,22 @@
  (MP_GROUP(x,y) == GROUP_RAIL_BRIDGE))
 #endif
 
+struct vec2 {
+       float x, y;
+};
+
+/** X & Y deltas, updated daily & cleared at the start of each month. */
+extern struct vec2 goods_movement[WORLD_SIDE_LEN * WORLD_SIDE_LEN * 7];
+
+/** Last month's goods velocity, stored as direction and magnitude */
+extern struct vec2 goods_moved_last_month[WORLD_SIDE_LEN * WORLD_SIDE_LEN * 7];
+
 void general_transport(int x, int y, int max_waste);
 void connect_transport(int originx, int originy, int w, int h);
+void transport_clear_monthly(void);
+void transport_init_monthly(void);
+const char *transport_format_cargo(int store, const struct vec2 *vec, int max);
+
+static inline struct vec2 *transport_get_stats(int x, int y) {
+       return &goods_moved_last_month[(x * WORLD_SIDE_LEN + y) * 7];
+}
-- 
1.8.1.5

_______________________________________________
Lincity-ng-devel mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/lincity-ng-devel

Reply via email to