Browse Source

Updates to working version

Caleb Fangmeier 4 years ago
parent
commit
4403421cdd

+ 5 - 0
.gitignore

@@ -1,2 +1,7 @@
 cocos/
 build/
+
+__pycache__/
+
+*.so
+*.cpp

BIN
app/__pycache__/__init__.cpython-38.pyc


BIN
app/__pycache__/app.cpython-38.pyc


BIN
app/__pycache__/camera.cpython-38.pyc


BIN
app/__pycache__/economy.cpython-38.pyc


BIN
app/__pycache__/verkolst.cpython-38.pyc


+ 11 - 8
app/app.py

@@ -33,12 +33,16 @@ class CocostratUI(cocos.layer.Layer):
                                                       position=(100, 100))
         self.hl_province_sprite.visible = False
 
+        from app.ui.overlay_layer import HexMapLayerWithOutlines
+        self.overlay_layer = HexMapLayerWithOutlines('overlay', verkolst['overlay'])
+        camera.add(self.overlay_layer)
+
         self.overlays = [
-            overlays.FoodOverlay(self, verkolst['overlay']),
-            overlays.PopsOverlay(self, verkolst['overlay'], 'lc'),
-            overlays.PopsOverlay(self, verkolst['overlay'], 'mc'),
-            overlays.PopsOverlay(self, verkolst['overlay'], 'uc'),
-            overlays.TradeDistanceOverlay(self, verkolst['overlay']),
+            overlays.FoodOverlay(self, self.overlay_layer),
+            overlays.PopsOverlay(self, self.overlay_layer, 'lc'),
+            overlays.PopsOverlay(self, self.overlay_layer, 'mc'),
+            overlays.PopsOverlay(self, self.overlay_layer, 'uc'),
+            overlays.TradeDistanceOverlay(self, self.overlay_layer),
         ]
 
         self.click_sound = pyg.media.load('assets/sound_effects/tap1.wav', streaming=False)
@@ -90,7 +94,7 @@ class CocostratUI(cocos.layer.Layer):
                 overlay.toggle()
             else:
                 overlay.disable()
-        verkolst['overlay'].visible = any(overlay.enabled for overlay in self.overlays)
+        self.overlay_layer.visible = any(overlay.enabled for overlay in self.overlays)
 
     def on_key_press(self, symbol, modifiers):
         if symbol == key.F1:
@@ -137,8 +141,7 @@ def main():
     camera.add(verkolst['terrain'])
     camera.add(verkolst['rivers'])
     camera.add(verkolst['buildings'])
-    camera.add(verkolst['nations'])
-    camera.add(verkolst['overlay'])
+    # camera.add(verkolst['nations'])
 
     ui = CocostratUI()
     camera.overlay_layer.add(ui.hl_province_sprite)

+ 6 - 0
app/colormap/regions.pyx

@@ -0,0 +1,6 @@
+import numpy as np
+
+
+
+def find_region_outline(src_grid: np.ndarray, value):
+    pass

+ 101 - 59
app/economy.py

@@ -6,11 +6,15 @@ import numpy as np
 
 
 class Resources:
+
+    base_trade_range = 2
+
     def __init__(self, rows=10, cols=10):
         self.shape = shape = (rows, cols)
-        self.lc_pops = np.zeros(shape, dtype=np.float32)
-        self.mc_pops = np.zeros(shape, dtype=np.float32)
-        self.uc_pops = np.zeros(shape, dtype=np.float32)
+        self.lc_pops = np.zeros(shape, dtype=np.int32)
+        self.mc_pops = np.zeros(shape, dtype=np.int32)
+        self.uc_pops = np.zeros(shape, dtype=np.int32)
+        self.pops_cap = np.zeros(shape, dtype=np.int32)
 
         self.lc_starvation = np.zeros(shape, dtype=np.bool)
         self.mc_starvation = np.zeros(shape, dtype=np.bool)
@@ -18,54 +22,83 @@ class Resources:
         self.any_starvation = np.zeros(shape, dtype=np.bool)
 
         self.food_rate = np.zeros(shape, dtype=np.float32)
-        self.food_production_capacity = np.zeros(shape, dtype=np.float32)
+        self.food_production_cap = np.zeros(shape, dtype=np.float32)
         self.food_production = np.zeros(shape, dtype=np.float32)
+        self.food_imports = np.zeros(shape, dtype=np.float32)
         self.food_consumption = np.zeros(shape, dtype=np.float32)
         self.food_stored = np.zeros(shape, dtype=np.float32)
         self.food_stored_capacity = np.zeros(shape, dtype=np.float32)
 
-        self.trade_distance = np.zeros(shape, dtype=np.float32)
-        self.trade_range = np.full(shape, 5)
+        self.trade_impedance = np.zeros(shape, dtype=np.float32)
+        self.trade_range = np.full(shape, self.base_trade_range, dtype=np.float32)
         self.trade_value = np.zeros(shape, dtype=np.float32)
+        self.trade_modifier = np.zeros(shape, dtype=np.float32)
+
+        self.export_partner = np.full((*shape, 2), 0, dtype=np.int32)
 
-        self.export_partner = np.full((*shape, 2), 0)
+        self.goods_production = {
+            'stone': np.full(shape, 0, dtype=np.float32),
+            'wood': np.full(shape, 0, dtype=np.float32),
+        }
 
     def init(self, verkolst):
         self.shape = (verkolst.width, verkolst.height)
-        self.lc_pops = np.full(self.shape, 25, dtype=np.float32)
-        self.mc_pops = np.full(self.shape, 0, dtype=np.float32)
-        self.uc_pops = np.full(self.shape, 0, dtype=np.float32)
+        self.lc_pops = np.full(self.shape, 25, dtype=np.int32)
+        self.mc_pops = np.full(self.shape, 0, dtype=np.int32)
+        self.uc_pops = np.full(self.shape, 0, dtype=np.int32)
 
         self.lc_starvation = np.full_like(self.lc_pops, False, dtype=np.bool)
         self.mc_starvation = np.full_like(self.lc_pops, False, dtype=np.bool)
         self.uc_starvation = np.full_like(self.lc_pops, False, dtype=np.bool)
         self.any_starvation = np.full_like(self.lc_pops, False, dtype=np.bool)
 
-        # Lets calculate the base food production
         terrain = verkolst["terrain"]
+        buildings = verkolst["buildings"]
 
         food_rate = np.full(self.shape, 0, dtype=np.float32)
-        food_capacity = np.full(self.shape, 0, dtype=np.float32)
-        trade_distance = np.full(self.shape, 0, dtype=np.float32)
+        food_production_cap = np.full(self.shape, 0, dtype=np.float32)
+        trade_impedance = np.full(self.shape, 0, dtype=np.float32)
+        stone_production = np.full(self.shape, 0, dtype=np.float32)
+        wood_production = np.full(self.shape, 0, dtype=np.float32)
+
+        trade_modifier = np.full(self.shape, 0, dtype=np.float32)
+        pops_cap = np.full(self.shape, 0, dtype=np.float32)
+
         for i, j in product(range(self.shape[0]), range(self.shape[1])):
             food_rate[i][j] = terrain.cells[i][j].tile.properties["food_rate"]
-            food_capacity[i][j] = terrain.cells[i][j].tile.properties["food_capacity"]
-            trade_distance[i][j] = terrain.cells[i][j].tile.properties["trade_distance"]
+            food_production_cap[i][j] = terrain.cells[i][j].tile.properties["food_production_cap"]
+            trade_impedance[i][j] = terrain.cells[i][j].tile.properties["trade_impedance"]
+            trade_modifier[i][j] = buildings.cells[i][j].tile.properties["trade_modifier"]
+            pops_cap[i][j] = terrain.cells[i][j].tile.properties["pops_cap"]
+
+            stone_production[i][j] = terrain.cells[i][j].tile.properties["stone_production"]
+            wood_production[i][j] = terrain.cells[i][j].tile.properties["wood_production"]
+
+        self.goods_production = {
+            'stone': stone_production,
+            'wood': wood_production,
+        }
 
         self.food_rate = food_rate
-        self.food_production_capacity = food_capacity
+        self.food_production_cap = food_production_cap
         self.food_production = np.full_like(self.lc_pops, 0)
+        self.food_imports = np.full_like(self.lc_pops, 0)
         self.update_food_production()
         self.food_consumption = 5 * self.uc_pops + 2 * self.mc_pops + 1 * self.lc_pops
         self.food_stored = 2 * self.food_production
         self.food_stored_capacity = np.full_like(self.lc_pops, 5000)
 
-        self.trade_distance = trade_distance
-        self.trade_range = np.full_like(self.lc_pops, 5)
-        self.update_trade_value()
+        self.trade_impedance = trade_impedance
+        self.trade_range = np.full_like(self.lc_pops, self.base_trade_range, dtype=np.float32)
+        self.trade_modifier = trade_modifier
 
         self.export_partner = np.full((*self.shape, 2), 0)
-        self.update_export_partners()
+        # self.update_export_partners()
+
+        self.pops_cap = pops_cap
+
+        # Now process a single turn to sync up everything
+        self.process_turn()
 
     def load(self, save_dir):
         with open(join(save_dir, "pops.json"), "r") as f:
@@ -86,34 +119,35 @@ class Resources:
             )
 
     def update_food_production(self):
-        (self.food_rate * np.floor(self.lc_pops)).clip(
-            min=0, max=self.food_production_capacity, out=self.food_production
+        (self.food_rate * self.lc_pops).clip(
+            min=0, max=self.food_production_cap, out=self.food_production
         )
 
     def update_trade_value(self):
-        self.trade_value = self.lc_pops*1 + self.mc_pops*5 + self.uc_pops*20
+        self.trade_value = (self.lc_pops*1 + self.mc_pops*5 + self.uc_pops*20).astype(np.float32) * self.trade_modifier
 
     def update_export_partners(self):
         from app.trade.trade_utils import update_export_partner
-        update_export_partner(self.trade_range, self.trade_distance, self.trade_value, self.export_partner)
+        update_export_partner(self.trade_range, self.trade_impedance, self.trade_value, self.export_partner)
 
     def eat_food(self):
+        # from app.trade.trade_utils import share_food
         # First, add any produced food to the stockpile
         self.food_stored += self.food_production
+        # share_food(self.food_production, self.food_consumption, self.food_stored, self.food_stored_capacity,
+        #            self.export_partner, 0.1)
 
         # Next eat the food from uc->mc->lc marking starvation as it occurs
-        self.food_stored -= np.floor(self.uc_pops) * 5
+        self.food_stored -= self.uc_pops * 5
         self.uc_starvation = self.food_stored <= 0
 
-        self.food_stored -= np.floor(self.mc_pops) * 2
+        self.food_stored -= self.mc_pops * 2
         self.mc_starvation = self.food_stored <= 0
 
-        self.food_stored -= np.floor(self.lc_pops) * 1
+        self.food_stored -= self.lc_pops * 1
         self.lc_starvation = self.food_stored <= 0
 
-        self.any_starvation = np.logical_or(
-            self.lc_starvation, np.logical_or(self.mc_starvation, self.uc_starvation)
-        )
+        self.any_starvation = np.any([self.lc_starvation, self.mc_starvation, self.uc_starvation], axis=0)
 
         # Finally, clip the amount of food stored to between 0 and the food storage capacity
         self.food_stored.clip(
@@ -122,47 +156,55 @@ class Resources:
 
     def redistribute_classes(self):
         total_pops = self.lc_pops + self.mc_pops + self.uc_pops
-        current_proportions = np.stack([self.lc_pops, self.mc_pops, self.uc_pops]) / (
-            total_pops
-        )
+        current_proportions = np.divide(np.stack([self.lc_pops, self.mc_pops, self.uc_pops]), total_pops)
+        np.nan_to_num(current_proportions, copy=False, nan=0, posinf=0)
+
         target_proportions = np.stack([
-            np.full_like(self.lc_pops, 0.8),
-            np.full_like(self.lc_pops, 0.15),
-            np.full_like(self.lc_pops, 0.05),
+            np.full_like(self.lc_pops, 0.8, dtype=np.float32),
+            np.full_like(self.lc_pops, 0.15, dtype=np.float32),
+            np.full_like(self.lc_pops, 0.05, dtype=np.float32),
         ])
+
         target_proportions[0, self.any_starvation] = 1
         target_proportions[1, self.any_starvation] = 0
         target_proportions[2, self.any_starvation] = 0
 
         new_proportions = current_proportions + (target_proportions - current_proportions) * 0.1
-        self.lc_pops = total_pops * new_proportions[0]
-        self.mc_pops = total_pops * new_proportions[1]
-        self.uc_pops = total_pops * new_proportions[2]
+        self.lc_pops = np.ceil(np.multiply(total_pops, new_proportions[0])).astype(np.int32)
+        self.mc_pops = np.ceil(np.multiply(total_pops, new_proportions[1])).astype(np.int32)
+        self.uc_pops = np.ceil(np.multiply(total_pops, new_proportions[2])).astype(np.int32)
 
     def make_babies(self):
 
         food_stored_proportion = self.food_stored / self.food_stored_capacity
 
-        repro_rate = 1 + 0.10 * food_stored_proportion
-        repro_rate[self.any_starvation] = 1.0
-        repro_rate[self.lc_starvation] = 0.95
-        np.multiply(self.lc_pops, repro_rate, out=self.lc_pops, casting="unsafe")
-
-        repro_rate = 1 + 0.08 * food_stored_proportion
-        repro_rate[self.any_starvation] = 1.0
-        repro_rate[self.mc_starvation] = 0.95
-        np.multiply(self.mc_pops, repro_rate, out=self.mc_pops, casting="unsafe")
-
-        repro_rate = 1 + 0.06 * food_stored_proportion
-        repro_rate[self.any_starvation] = 1.0
-        repro_rate[self.uc_starvation] = 0.95
-        np.multiply(self.uc_pops, repro_rate, out=self.uc_pops, casting="unsafe")
-
-        self.food_consumption = (
-            5 * np.floor(self.uc_pops)
-            + 2 * np.floor(self.mc_pops)
-            + 1 * np.floor(self.lc_pops)
-        )
+        repro_rate = 0.05 * food_stored_proportion
+        repro_rate[self.any_starvation] = 0.0
+        repro_rate[self.lc_starvation] = -0.05
+        np.add(self.lc_pops, np.sign(repro_rate) * np.random.binomial(self.lc_pops,  np.abs(repro_rate)),
+               out=self.lc_pops, casting='unsafe')
+
+        repro_rate = 0.02 * food_stored_proportion
+        repro_rate[self.any_starvation] = 0.0
+        repro_rate[self.mc_starvation] = -0.05
+        np.add(self.mc_pops, np.sign(repro_rate) * np.random.binomial(self.mc_pops,  np.abs(repro_rate)),
+               out=self.mc_pops, casting='unsafe')
+
+        repro_rate = 0.01 * food_stored_proportion
+        repro_rate[self.any_starvation] = 0.0
+        repro_rate[self.uc_starvation] = -0.05
+        np.add(self.uc_pops, np.sign(repro_rate) * np.random.binomial(self.uc_pops,  np.abs(repro_rate)),
+               out=self.uc_pops, casting='unsafe')
+
+        overpop_fraction = np.divide(self.pops_cap, self.lc_pops+self.mc_pops+self.uc_pops)
+        np.nan_to_num(overpop_fraction, copy=False, nan=1.0, posinf=1.0, neginf=1.0)
+        overpop_fraction.clip(max=1.0, out=overpop_fraction)
+
+        self.lc_pops = np.multiply(self.lc_pops, overpop_fraction).astype(np.int32)
+        self.mc_pops = np.multiply(self.mc_pops, overpop_fraction).astype(np.int32)
+        self.uc_pops = np.multiply(self.uc_pops, overpop_fraction).astype(np.int32)
+
+        self.food_consumption = 5 * self.uc_pops + 2 * self.mc_pops + 1 * self.lc_pops
 
     def process_turn(self):
         self.eat_food()

File diff suppressed because it is too large
+ 0 - 25705
app/trade/trade_utils.cpp


BIN
app/trade/trade_utils.cpython-38-x86_64-linux-gnu.so


+ 66 - 15
app/trade/trade_utils.pyx

@@ -30,18 +30,11 @@ cdef hex_neighbors(const int i, const int j, int[:,:] out):
 @cython.boundscheck(True)
 @cython.wraparound(False)
 @cython.cdivision(True)
-cdef _trade_distance(int init_i, int init_j, float trade_range, const float[:, :] trade_traversal_cost,
+cdef _trade_distance(int init_i, int init_j, float trade_range, const float[:, :] trade_impedance,
                      const float[:, :] trade_value, float[:, :] distance):
-    """
-    Function needs following properties:
-      1. Returns an array for the map where
-        a) Shows trade distance where distance < trade_range
-        b) Otherwise, filled with -1
-      2. Returns the province that is the export partner (if one exists)
-    """
 
-    cdef int width = trade_traversal_cost.shape[0]
-    cdef int height = trade_traversal_cost.shape[1]
+    cdef int width = trade_impedance.shape[0]
+    cdef int height = trade_impedance.shape[1]
     cdef pp_t pp
     cdef step top
     cdef int i, j, ii, jj
@@ -50,7 +43,7 @@ cdef _trade_distance(int init_i, int init_j, float trade_range, const float[:, :
     cdef float dist, dist_tmp
     cdef int[:, :] neighbors = np.zeros((6,2), dtype=np.int32)
 
-    cdef char[:, :] visited = np.full((trade_traversal_cost.shape[0], trade_traversal_cost.shape[1]),
+    cdef char[:, :] visited = np.full((trade_impedance.shape[0], trade_impedance.shape[1]),
                                       False, dtype=np.int8)
     distance[init_i][init_j] = 0.0
     pp.push(step(0.0, init_j*width+init_i))
@@ -72,7 +65,7 @@ cdef _trade_distance(int init_i, int init_j, float trade_range, const float[:, :
             jj = neighbors[idx][1]
             if 0 <= ii < width and 0 <= jj < height and not visited[ii][jj]:
                 visited[ii][jj] = True
-                dist_tmp = dist + trade_traversal_cost[ii][jj]
+                dist_tmp = dist + trade_impedance[ii][jj]
 
                 if dist_tmp <= trade_range:
                     distance[ii][jj] = dist_tmp
@@ -80,14 +73,21 @@ cdef _trade_distance(int init_i, int init_j, float trade_range, const float[:, :
     return exp_i, exp_j
 
 
-def trade_distance(int i, int j, float trade_range, trade_traversal_cost: np.ndarray, trade_value: np.ndarray):
-    distance = np.full_like(trade_traversal_cost, -1)
-    exp = _trade_distance(i, j, trade_range, trade_traversal_cost, trade_value, distance)
+
+def trade_distance(int i, int j, float trade_range, trade_impedance: np.ndarray, trade_value: np.ndarray):
+    distance = np.full_like(trade_impedance, -1)
+    exp = _trade_distance(i, j, trade_range, trade_impedance, trade_value, distance)
     return exp, distance
 
+
+@cython.boundscheck(False)
+@cython.wraparound(False)
+@cython.cdivision(True)
 cpdef update_export_partner(trade_range: np.ndarray, trade_distance: np.ndarray, trade_value: np.ndarray, export_partner: np.ndarray):
     cdef int width = trade_range.shape[0]
     cdef int height = trade_range.shape[1]
+    cdef int exp_i, exp_j
+    print(trade_range)
 
     cdef float[:, :] distance
     for i in range(width):
@@ -97,3 +97,54 @@ cpdef update_export_partner(trade_range: np.ndarray, trade_distance: np.ndarray,
             export_partner[i, j] = [exp_i, exp_j]
 
 
+@cython.boundscheck(True)
+@cython.wraparound(False)
+@cython.cdivision(True)
+cpdef share_food(food_produced: np.ndarray, food_consumed: np.ndarray, food_stored: np.ndarray,
+                 food_stored_capacity: np.ndarray, export_partner: np.ndarray,
+                 spread_factor_neighbor: float):
+    """
+    If a province produces more food that it consumes *and* it's food storage is full, a portion of it's excess
+    can be transferred to neighboring hex's provided that they don't also have excess production. Any leftover excess
+    will get shipped to the export partner. 
+    """
+    cdef int width = food_produced.shape[0]
+    cdef int height = food_produced.shape[1]
+    cdef float[:, :] food_excess = food_produced - food_consumed
+    cdef int ii, jj
+
+    cdef int[:, :] neighbors = np.zeros((6,2), dtype=np.int32)
+
+    food_stored_new = np.copy(food_stored)
+    cdef float[:, :] food_stored_new_ = food_stored_new
+
+    cdef float spread_amount
+    cdef int spread_count
+
+    for i in range(width):
+        for j in range(height):
+            if food_excess[i][j] <= 0 or food_stored[i][j] < food_stored_capacity[i][j]:
+                continue
+            hex_neighbors(i, j, neighbors)
+            spread_amount_neighbor = spread_factor_neighbor * food_excess[i][j]
+            spread_count = 0
+
+            for idx in range(6):
+                ii = neighbors[idx][0]
+                jj = neighbors[idx][1]
+                if not (0 <= ii < width and 0 <= jj < height):
+                    continue
+                if food_excess[ii][jj] < food_excess[i][j] and food_stored[ii][jj] < food_stored_capacity[ii][jj]:
+                    food_stored_new_[ii][jj] += spread_amount_neighbor
+                    food_stored_new_[i][j] -= spread_amount_neighbor
+                    spread_count += 1
+            spread_amount = food_excess[i][j] * (1 - spread_amount_neighbor*spread_count)
+            try:
+                food_stored_new_[export_partner[i][j][0], export_partner[i][j][1]] += spread_amount
+            except IndexError:
+                print(export_partner[i][j])
+            food_stored_new_[i][j] -= spread_amount
+
+
+    np.copyto(food_stored, food_stored_new)
+

BIN
app/ui/__pycache__/__init__.cpython-38.pyc


BIN
app/ui/__pycache__/map_overlay.cpython-38.pyc


BIN
app/ui/__pycache__/province_info.cpython-38.pyc


BIN
app/ui/__pycache__/status_bar.cpython-38.pyc


+ 13 - 10
app/ui/map_overlay.py

@@ -51,18 +51,19 @@ class Overlay:
 class FoodOverlay(Overlay):
 
     def __init__(self, ui, hexmap_layer):
-        super().__init__(ui, hexmap_layer)
+        super().__init__(ui, hexmap_layer, opacity=200)
+        self._colors = None
+
+    def _recalculate(self):
+        self._colors = apply_colormap(verkolst.resources.food_stored/verkolst.resources.food_stored_capacity,
+                                      'magma', min_=0)
 
     def get_cell_color(self, i, j):
-        res = verkolst.resources
-        if res.any_starvation[i, j]:
+        # res = verkolst.resources
+        if verkolst.resources.any_starvation[i, j]:
             return 255, 0, 0  # Red
-        elif res.food_stored[i, j]/res.food_stored_capacity[i, j] < 0.25:
-            return 255, 153, 51  # Orange
-        elif res.food_stored[i, j] < res.food_stored_capacity[i, j]:
-            return 51, 204, 51  # Green
         else:
-            return 0, 0, 255  # Blue
+            return self._colors[i, j]
 
 
 class PopsOverlay(Overlay):
@@ -94,8 +95,10 @@ class TradeDistanceOverlay(Overlay):
 
     def _recalculate(self):
         if self._ui.hl_province is not None:
-            self.exp_partner, self.trade_distance = trade_distance(self._ui.hl_province.i, self._ui.hl_province.j, 10,
-                                                                   verkolst.resources.trade_distance,
+            i, j = self._ui.hl_province.i, self._ui.hl_province.j
+            self.exp_partner, self.trade_distance = trade_distance(i, j,
+                                                                   verkolst.resources.trade_range[i, j],
+                                                                   verkolst.resources.trade_impedance,
                                                                    verkolst.resources.trade_value)
         else:
             self.trade_distance[:, :] = 0.0

+ 17 - 0
app/ui/overlay_layer.py

@@ -0,0 +1,17 @@
+from cocos.tiles import HexMapLayer
+
+import cocos.draw
+
+
+class HexMapLayerWithOutlines(HexMapLayer):
+
+    def __init__(self, id_, source_layer):
+        super().__init__(id_, False, source_layer.th, source_layer.cells,
+                         properties=source_layer.properties)
+        self.visible = False
+
+        # Looks like we want to add a cocos.draw.Canvas with a bunch of lines.
+
+        for i in range(10):
+
+            pass

+ 11 - 8
app/ui/province_info.py

@@ -65,15 +65,18 @@ class ProvinceInfo(cocos.layer.Layer):
             pops_tot = resources.lc_pops[i][j] + resources.mc_pops[i][j] + resources.uc_pops[i][j]
 
             def _fmt(label, number, starving):
-                if starving[i][j]:
-                    hl_color = "#B22222"  # Red
-                elif resources.any_starvation[i][j]:
-                    hl_color = "#DAA520"  # Yellow
+                if pops_tot > 0:
+                    if starving[i][j]:
+                        hl_color = "#B22222"  # Red
+                    elif resources.any_starvation[i][j]:
+                        hl_color = "#DAA520"  # Yellow
+                    else:
+                        hl_color = "#FFFFF0"  # Off White
+                    return (f'<font color="#FFFFF0">{label}: </font><font color="{hl_color}">{int(number[i][j]):d}</font>'
+                            f'<font color="#FFFFF0"> - {100*number[i][j]/pops_tot:.1f}%</font>'
+                            )
                 else:
-                    hl_color = "#FFFFF0"  # Off White
-                return (f'<font color="#FFFFF0">{label}: </font><font color="{hl_color}">{int(number[i][j]):d}</font>'
-                        f'<font color="#FFFFF0"> - {100*number[i][j]/pops_tot:.1f}%</font>'
-                        )
+                    return f'<font color="#FFFFF0">{label}: - </font>'
 
             self.lc_pops_label.element.text = _fmt('LC', resources.lc_pops, resources.lc_starvation)
             self.mc_pops_label.element.text = _fmt('MC', resources.mc_pops, resources.mc_starvation)

+ 61 - 61
assets/map/Verkolst.tmx

@@ -74,70 +74,70 @@
  </layer>
  <layer id="3" name="buildings" width="50" height="30">
   <data encoding="csv">
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,0,0,52,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,52,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,53,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,52,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,52,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51
 </data>
  </layer>
- <layer id="5" name="nations" width="50" height="30" visible="0" opacity="0.41">
+ <layer id="5" name="nations" width="50" height="30" visible="0">
   <data encoding="csv">
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,76,0,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,76,76,76,76,76,0,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,76,76,76,76,76,0,0,0,0,0,0,0,0,0,0,0,76,76,76,76,76,76,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,76,76,76,76,76,76,76,76,76,76,0,0,0,0,0,0,0,0,76,76,76,76,76,76,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,76,0,76,76,76,76,76,76,76,76,0,0,0,0,0,0,0,0,76,76,76,76,76,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,76,76,76,76,76,76,76,76,76,0,76,76,0,76,76,76,76,0,76,0,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,76,76,76,76,76,76,76,76,76,76,76,76,76,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,76,76,76,76,76,76,76,76,76,76,76,76,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,76,76,76,76,76,76,76,76,76,76,76,76,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,76,76,76,0,76,76,76,76,76,76,76,76,76,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,76,76,76,76,76,76,76,76,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,76,76,76,76,76,0,0,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,0,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76
 </data>
  </layer>
  <layer id="6" name="overlay" width="50" height="30" visible="0">

BIN
assets/map/buildings.png


+ 126 - 1
assets/map/buildings.tsx

@@ -1,4 +1,129 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<tileset version="1.2" tiledversion="1.3.1" name="buildings" tilewidth="115" tileheight="100" spacing="4" tilecount="25" columns="5">
+<tileset version="1.2" tiledversion="1.3.2" name="buildings" tilewidth="115" tileheight="100" spacing="4" tilecount="25" columns="5">
  <image source="buildings.png" width="591" height="516"/>
+ <tile id="0">
+  <properties>
+   <property name="trade_modifier" type="float" value="1"/>
+  </properties>
+ </tile>
+ <tile id="1">
+  <properties>
+   <property name="trade_modifier" type="float" value="2"/>
+  </properties>
+ </tile>
+ <tile id="2">
+  <properties>
+   <property name="trade_modifier" type="float" value="10"/>
+  </properties>
+ </tile>
+ <tile id="3">
+  <properties>
+   <property name="trade_modifier" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="4">
+  <properties>
+   <property name="trade_modifier" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="5">
+  <properties>
+   <property name="trade_modifier" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="6">
+  <properties>
+   <property name="trade_modifier" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="7">
+  <properties>
+   <property name="trade_modifier" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="8">
+  <properties>
+   <property name="trade_modifier" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="9">
+  <properties>
+   <property name="trade_modifier" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="10">
+  <properties>
+   <property name="trade_modifier" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="11">
+  <properties>
+   <property name="trade_modifier" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="12">
+  <properties>
+   <property name="trade_modifier" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="13">
+  <properties>
+   <property name="trade_modifier" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="14">
+  <properties>
+   <property name="trade_modifier" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="15">
+  <properties>
+   <property name="trade_modifier" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="16">
+  <properties>
+   <property name="trade_modifier" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="17">
+  <properties>
+   <property name="trade_modifier" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="18">
+  <properties>
+   <property name="trade_modifier" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="19">
+  <properties>
+   <property name="trade_modifier" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="20">
+  <properties>
+   <property name="trade_modifier" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="21">
+  <properties>
+   <property name="trade_modifier" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="22">
+  <properties>
+   <property name="trade_modifier" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="23">
+  <properties>
+   <property name="trade_modifier" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="24">
+  <properties>
+   <property name="trade_modifier" type="float" value="0"/>
+  </properties>
+ </tile>
 </tileset>

BIN
assets/map/buildings.xcf


+ 169 - 19
assets/map/terrain.tsx

@@ -1,76 +1,226 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<tileset version="1.2" tiledversion="1.3.2" name="terrain" tilewidth="115" tileheight="100" spacing="4" tilecount="25" columns="5">
+<tileset version="1.2" tiledversion="1.3.3" name="terrain" tilewidth="115" tileheight="100" spacing="4" tilecount="25" columns="5">
  <image source="terrain.png" width="591" height="516"/>
  <tile id="0">
   <properties>
-   <property name="food_capacity" type="float" value="0"/>
+   <property name="food_production_cap" type="float" value="0"/>
    <property name="food_rate" type="float" value="0"/>
    <property name="name" value="null"/>
-   <property name="trade_distance" type="float" value="0"/>
+   <property name="pops_cap" type="float" value="0"/>
+   <property name="stone_production" type="float" value="0"/>
+   <property name="trade_impedance" type="float" value="0"/>
+   <property name="wood_production" type="float" value="0"/>
   </properties>
  </tile>
  <tile id="1">
   <properties>
-   <property name="food_capacity" type="float" value="0"/>
+   <property name="food_production_cap" type="float" value="0"/>
    <property name="food_rate" type="float" value="0"/>
    <property name="name" value="water_deep"/>
-   <property name="trade_distance" type="float" value="2"/>
+   <property name="pops_cap" type="float" value="0"/>
+   <property name="stone_production" type="float" value="0"/>
+   <property name="trade_impedance" type="float" value="2"/>
+   <property name="wood_production" type="float" value="0"/>
   </properties>
  </tile>
  <tile id="2">
   <properties>
-   <property name="food_capacity" type="float" value="1000"/>
+   <property name="food_production_cap" type="float" value="1000"/>
    <property name="food_rate" type="float" value="1.5"/>
    <property name="name" value="grassland"/>
-   <property name="trade_distance" type="float" value="1"/>
+   <property name="pops_cap" type="float" value="1000"/>
+   <property name="stone_production" type="float" value="0"/>
+   <property name="trade_impedance" type="float" value="1"/>
+   <property name="wood_production" type="float" value="0"/>
   </properties>
  </tile>
  <tile id="3">
   <properties>
-   <property name="food_capacity" type="float" value="2000"/>
+   <property name="food_production_cap" type="float" value="2000"/>
    <property name="food_rate" type="float" value="2"/>
    <property name="name" value="fertile_grassland"/>
-   <property name="trade_distance" type="float" value="1"/>
+   <property name="pops_cap" type="float" value="1000"/>
+   <property name="stone_production" type="float" value="0"/>
+   <property name="trade_impedance" type="float" value="1"/>
+   <property name="wood_production" type="float" value="0"/>
   </properties>
  </tile>
  <tile id="4">
   <properties>
-   <property name="food_capacity" type="float" value="500"/>
+   <property name="food_production_cap" type="float" value="500"/>
    <property name="food_rate" type="float" value="1.1"/>
    <property name="name" value="mountains"/>
-   <property name="trade_distance" type="float" value="10"/>
+   <property name="pops_cap" type="float" value="100"/>
+   <property name="stone_production" type="float" value="2"/>
+   <property name="trade_impedance" type="float" value="10"/>
+   <property name="wood_production" type="float" value="0"/>
   </properties>
  </tile>
  <tile id="5">
   <properties>
-   <property name="food_capacity" type="float" value="500"/>
+   <property name="food_production_cap" type="float" value="500"/>
    <property name="food_rate" type="float" value="1.1"/>
    <property name="name" value="forest_coniferous"/>
-   <property name="trade_distance" type="float" value="5"/>
+   <property name="pops_cap" type="float" value="200"/>
+   <property name="stone_production" type="float" value="0"/>
+   <property name="trade_impedance" type="float" value="5"/>
+   <property name="wood_production" type="float" value="1"/>
   </properties>
  </tile>
  <tile id="6">
   <properties>
-   <property name="food_capacity" type="float" value="1000"/>
+   <property name="food_production_cap" type="float" value="1000"/>
    <property name="food_rate" type="float" value="1.5"/>
    <property name="name" value="water_shallow"/>
-   <property name="trade_distance" type="float" value="0.5"/>
+   <property name="pops_cap" type="float" value="0"/>
+   <property name="stone_production" type="float" value="0"/>
+   <property name="trade_impedance" type="float" value="0.5"/>
+   <property name="wood_production" type="float" value="0"/>
   </properties>
  </tile>
  <tile id="7">
   <properties>
-   <property name="food_capacity" type="float" value="5000"/>
+   <property name="food_production_cap" type="float" value="5000"/>
    <property name="food_rate" type="float" value="5"/>
    <property name="name" value="fields"/>
-   <property name="trade_distance" type="float" value="1"/>
+   <property name="pops_cap" type="float" value="1000"/>
+   <property name="stone_production" type="float" value="0"/>
+   <property name="trade_impedance" type="float" value="1"/>
+   <property name="wood_production" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="8">
+  <properties>
+   <property name="pops_cap" type="float" value="0"/>
+   <property name="stone_production" type="float" value="0"/>
+   <property name="trade_impedance" type="float" value="0"/>
+   <property name="wood_production" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="9">
+  <properties>
+   <property name="pops_cap" type="float" value="0"/>
+   <property name="stone_production" type="float" value="0"/>
+   <property name="trade_impedance" type="float" value="0"/>
+   <property name="wood_production" type="float" value="0"/>
   </properties>
  </tile>
  <tile id="10">
   <properties>
-   <property name="food_capacity" type="float" value="500"/>
+   <property name="food_production_cap" type="float" value="500"/>
    <property name="food_rate" type="float" value="1.1"/>
    <property name="name" value="forest_deciduous"/>
-   <property name="trade_distance" type="float" value="5"/>
+   <property name="pops_cap" type="float" value="200"/>
+   <property name="stone_production" type="float" value="0"/>
+   <property name="trade_impedance" type="float" value="5"/>
+   <property name="wood_production" type="float" value="1.5"/>
+  </properties>
+ </tile>
+ <tile id="11">
+  <properties>
+   <property name="pops_cap" type="float" value="0"/>
+   <property name="stone_production" type="float" value="0"/>
+   <property name="trade_impedance" type="float" value="0"/>
+   <property name="wood_production" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="12">
+  <properties>
+   <property name="pops_cap" type="float" value="0"/>
+   <property name="stone_production" type="float" value="0"/>
+   <property name="trade_impedance" type="float" value="0"/>
+   <property name="wood_production" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="13">
+  <properties>
+   <property name="pops_cap" type="float" value="0"/>
+   <property name="stone_production" type="float" value="0"/>
+   <property name="trade_impedance" type="float" value="0"/>
+   <property name="wood_production" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="14">
+  <properties>
+   <property name="pops_cap" type="float" value="0"/>
+   <property name="stone_production" type="float" value="0"/>
+   <property name="trade_impedance" type="float" value="0"/>
+   <property name="wood_production" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="15">
+  <properties>
+   <property name="pops_cap" type="float" value="0"/>
+   <property name="stone_production" type="float" value="0"/>
+   <property name="trade_impedance" type="float" value="0"/>
+   <property name="wood_production" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="16">
+  <properties>
+   <property name="pops_cap" type="float" value="0"/>
+   <property name="stone_production" type="float" value="0"/>
+   <property name="trade_impedance" type="float" value="0"/>
+   <property name="wood_production" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="17">
+  <properties>
+   <property name="pops_cap" type="float" value="0"/>
+   <property name="stone_production" type="float" value="0"/>
+   <property name="trade_impedance" type="float" value="0"/>
+   <property name="wood_production" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="18">
+  <properties>
+   <property name="pops_cap" type="float" value="0"/>
+   <property name="stone_production" type="float" value="0"/>
+   <property name="trade_impedance" type="float" value="0"/>
+   <property name="wood_production" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="19">
+  <properties>
+   <property name="pops_cap" type="float" value="0"/>
+   <property name="stone_production" type="float" value="0"/>
+   <property name="trade_impedance" type="float" value="0"/>
+   <property name="wood_production" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="20">
+  <properties>
+   <property name="pops_cap" type="float" value="0"/>
+   <property name="stone_production" type="float" value="0"/>
+   <property name="wood_production" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="21">
+  <properties>
+   <property name="pops_cap" type="float" value="0"/>
+   <property name="stone_production" type="float" value="0"/>
+   <property name="wood_production" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="22">
+  <properties>
+   <property name="pops_cap" type="float" value="0"/>
+   <property name="stone_production" type="float" value="0"/>
+   <property name="wood_production" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="23">
+  <properties>
+   <property name="pops_cap" type="float" value="0"/>
+   <property name="stone_production" type="float" value="0"/>
+   <property name="wood_production" type="float" value="0"/>
+  </properties>
+ </tile>
+ <tile id="24">
+  <properties>
+   <property name="pops_cap" type="float" value="0"/>
+   <property name="stone_production" type="float" value="0"/>
+   <property name="wood_production" type="float" value="0"/>
   </properties>
  </tile>
 </tileset>