home · contact · privacy
Re-insert map existence check in command_worldactive().
[plomrogue] / roguelike-server
index 77c53d44025e821c0b6ad4a5949960f8132bb01f..e723339a46bdad1e0c121cdb1b41e69537c9f77d 100755 (executable)
@@ -139,7 +139,8 @@ def obey(command, prefix, replay=False, do_record=False):
                 if time.time() > io_db["save_wait"] + 15:
                     atomic_write(io_db["path_record"], io_db["record_chunk"],
                                  do_append=True)
-                    save_world()
+                    if world_db["WORLD_ACTIVE"]:
+                        save_world()
                     io_db["record_chunk"] = ""
                     io_db["save_wait"] = time.time()
             io_db["worldstate_updateable"] = world_db["WORLD_ACTIVE"]
@@ -500,10 +501,9 @@ def update_map_memory(t, age_map=True):
             t["T_MEMMAP"][pos] = world_db["MAP"][pos]
     if age_map:
         age_some_memdepthmap_on_nonfov_cells()
-    for mt in [mt for mt in t["T_MEMTHING"]
-               if ord_v == t["fovmap"][(mt[1] * world_db["MAP_LENGTH"])
-                                       + mt[2]]]:
-        t["T_MEMTHING"].remove(mt)
+    t["T_MEMTHING"] = [mt for mt in t["T_MEMTHING"]
+                       if ord_v != t["fovmap"][(mt[1] * world_db["MAP_LENGTH"])
+                                               + mt[2]]]
     for id in [id for id in world_db["Things"]
                if not world_db["Things"][id]["carried"]]:
         type = world_db["Things"][id]["T_TYPE"]
@@ -713,31 +713,21 @@ def actor_use(t):
                      "LOG You try to use an object, but you own none.\n")
 
 
-def thingproliferation(t):
-    """To chance of 1/TT_PROLIFERATE, create t offspring in neighbor cell.
+def thingproliferation(t, prol_map):
+    """To chance of 1/TT_PROLIFERATE, create t offspring in open neighbor cell.
 
-    Naturally only works with TT_PROLIFERATE > 0. The neighbor cell must be
-    passable and not be inhabited by a Thing of the same type, or, if Thing is
-    animate, any other animate Thing. If there are several map cell candidates,
-    one is selected randomly.
+    Naturally only works with TT_PROLIFERATE > 0. The neighbor cell must be be
+    marked '.' in prol_map. If there are several map cell candidates, one is
+    selected randomly.
     """
-    def test_cell(t, y, x):
-        if "." == chr(world_db["MAP"][(y * world_db["MAP_LENGTH"]) + x]):
-            for id in [id for id in world_db["Things"]
-                       if y == world_db["Things"][id]["T_POSY"]
-                       if x == world_db["Things"][id]["T_POSX"]
-                       if (t["T_TYPE"] == world_db["Things"][id]["T_TYPE"])
-                       or (t["T_LIFEPOINTS"] and
-                           world_db["Things"][id]["T_LIFEPOINTS"])]:
-                return False
-            return True
-        return False
     prolscore = world_db["ThingTypes"][t["T_TYPE"]]["TT_PROLIFERATE"]
     if prolscore and (1 == prolscore or 1 == (rand.next() % prolscore)):
         candidates = []
         for dir in [directions_db[key] for key in directions_db]:
             mv_result = mv_yx_in_dir_legal(dir, t["T_POSY"], t["T_POSX"])
-            if mv_result[0] and test_cell(t, mv_result[1], mv_result[2]):
+            if mv_result[0] and  ord('.') == prol_map[mv_result[1]
+                                                      * world_db["MAP_LENGTH"]
+                                                      + mv_result[2]]:
                 candidates.append((mv_result[1], mv_result[2]))
         if len(candidates):
             i = rand.next() % len(candidates)
@@ -1034,6 +1024,12 @@ def turn_over():
     id = 0
     whilebreaker = False
     while world_db["Things"][0]["T_LIFEPOINTS"]:
+        proliferable_map = world_db["MAP"][:]
+        for id in [id for id in world_db["Things"]
+                   if not world_db["Things"][id]["carried"]]:
+            y = world_db["Things"][id]["T_POSY"]
+            x = world_db["Things"][id]["T_POSX"]
+            proliferable_map[y * world_db["MAP_LENGTH"] + x] = ord('X')
         for id in [id for id in world_db["Things"]]:  # Only what's from start!
             if not id in world_db["Things"] or \
                world_db["Things"][id]["carried"]:   # May have been consumed or
@@ -1056,7 +1052,7 @@ def turn_over():
                     Thing["T_COMMAND"] = 0
                     Thing["T_PROGRESS"] = 0
                 hunger(Thing)
-            thingproliferation(Thing)
+            thingproliferation(Thing, proliferable_map)
         if whilebreaker:
             break
         world_db["TURN"] += 1
@@ -1121,7 +1117,8 @@ def command_ping():
 def command_quit():
     """Abort server process."""
     if None == opts.replay:
-        save_world()
+        if world_db["WORLD_ACTIVE"]:
+            save_world()
         atomic_write(io_db["path_record"], io_db["record_chunk"], do_append=True)
     raise SystemExit("received QUIT command")
 
@@ -1288,10 +1285,9 @@ def command_worldactive(worldactive_string):
     """Toggle world_db["WORLD_ACTIVE"] if possible.
 
     An active world can always be set inactive. An inactive world can only be
-    set active with a "wait" ThingAction, and a player Thing (of ID 0). On
-    activation, rebuild all Things' FOVs, and the player's map memory.
+    set active with a "wait" ThingAction, and a player Thing (of ID 0), and a
+    map. On activation, rebuild all Things' FOVs, and the player's map memory.
     """
-    # In original version, map existence was also tested (unnecessarily?).
     val = integer_test(worldactive_string, 0, 1)
     if val:
         if 0 != world_db["WORLD_ACTIVE"]:
@@ -1310,7 +1306,7 @@ def command_worldactive(worldactive_string):
                 if 0 == Thing:
                     player_exists = True
                     break
-            if wait_exists and player_exists:
+            if wait_exists and player_exists and "MAP" in world_db:
                 for id in world_db["Things"]:
                     if world_db["Things"][id]["T_LIFEPOINTS"]:
                         build_fov_map(world_db["Things"][id])