home · contact · privacy
Server: Don't proliferate things on map cells inhabited by same type.
authorChristian Heller <c.heller@plomlompom.de>
Thu, 23 Oct 2014 21:54:39 +0000 (23:54 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Thu, 23 Oct 2014 21:54:39 +0000 (23:54 +0200)
SERVER_COMMANDS
src/server/things.c

index 0a85cd381588c6379ded56b8a324be45ddfb467a..a39cf7242d15fae0df3e79e6d1f1f021652bf474 100644 (file)
@@ -201,5 +201,5 @@ transform into when their state changes from animate to inanimate.
 TT_PROLIFERATE [0-255]
 If non-zero, there is a chance of 1 divided by the given value each turn for any
 thing of the selected type to emit an offspring to a random neighbor cell if one
-passable is available (and, if the thing is of an animate type, not inhabited by
-another animate thing).
+is available that is passable and not inhabited by a thing of the same same type
+or, if the proliferating thing is animate, any other animate thing.
index 30563220a26d4830fded78b757a278aab0e5dc8a..d4db1938836fac6f6bd31d6e535f5343ff31bc00 100644 (file)
@@ -43,6 +43,11 @@ static struct NextAndId * add_to_struct_list(size_t n_size, uint8_t start_id,
                                              int16_t id, uint8_t struct_id,
                                              struct NextAndId ** start);
 
+/* Return 1 if cell at "test_pos" is proliferable by "t", i.e. it is passable,
+ * it is not inhabited by another thing of "t"'s type, and, if "t" is animate,
+ * neither by any other animate thing; else return 0.
+ */
+static uint8_t cell_is_proliferable(struct yx_uint8 test_pos, struct Thing * t);
 
 
 static struct NextAndId * add_to_struct_list(size_t n_size, uint8_t start_id,
@@ -79,6 +84,32 @@ static struct NextAndId * add_to_struct_list(size_t n_size, uint8_t start_id,
 
 
 
+static uint8_t cell_is_proliferable(struct yx_uint8 test_pos, struct Thing * t)
+{
+    if ('.' == world.map.cells[test_pos.y * world.map.length + test_pos.x])
+    {
+        struct Thing * t_test;
+        for (t_test = world.things; t_test; t_test = t_test->next)
+        {
+            if (t_test->pos.y == test_pos.y && t_test->pos.x == test_pos.x)
+            {
+                if (t_test->type == t->type)
+                {
+                    return 0;
+                }
+                if (t_test->lifepoints && t->lifepoints)
+                {
+                    return 0;
+                }
+            }
+        }
+        return 1;
+    }
+    return 0;
+}
+
+
+
 extern struct ThingAction * add_thing_action(uint8_t id)
 {
     struct ThingAction * ta;
@@ -278,31 +309,15 @@ extern void try_thing_proliferation(struct Thing * t)
             struct yx_uint8 candidates[6];
             uint8_t n_candidates = 0;
             char dirs[7] = "dxswed";
-            struct yx_uint8 start = t->pos;
+            struct yx_uint8 test = t->pos;
             uint8_t i;
             for (i = 0; i < strlen(dirs); i++)
             {
-                if (   mv_yx_in_dir_legal(dirs[i], &start)
-                    && '.' == world.map.cells[start.y*world.map.length+start.x])
+                if (   mv_yx_in_dir_legal(dirs[i], &test)
+                    && cell_is_proliferable(test, t))
                 {
-                    uint8_t drop = 0;
-                    if (tt->lifepoints)
-                    {
-                        for (t = world.things; t; t = t->next)
-                        {
-                            if (   t->lifepoints
-                                && start.y == t->pos.y && start.x == t->pos.x)
-                            {
-                                drop = 1;
-                                break;
-                            }
-                        }
-                    }
-                    if (!drop)
-                    {
-                        candidates[n_candidates] = start;
+                        candidates[n_candidates] = test;
                         n_candidates++;
-                    }
                 }
             }
             if (!n_candidates)