home · contact · privacy
Fix replay mode overwriting save file on quit.
[plomrogue] / roguelike-server
index cf836ec90b6b19f9b76aded8851cc9c3b145f1ac..98a92dff04653ac5cc6063a704d14bc98f63f88e 100755 (executable)
@@ -330,7 +330,7 @@ def try_worldstate_update():
                 type_id = world_db["Things"][id]["T_TYPE"]
                 name = world_db["ThingTypes"][type_id]["TT_NAME"]
                 inventory = inventory + name + "\n"
                 type_id = world_db["Things"][id]["T_TYPE"]
                 name = world_db["ThingTypes"][type_id]["TT_NAME"]
                 inventory = inventory + name + "\n"
-        ## 7DRL additions:  GOD_MOOD, GOD_FAVOR
+        # # 7DRL additions:  GOD_MOOD, GOD_FAVOR
         string = str(world_db["TURN"]) + "\n" + \
                  str(world_db["GOD_MOOD"]) + "\n" + \
                  str(world_db["GOD_FAVOR"]) + "\n" + \
         string = str(world_db["TURN"]) + "\n" + \
                  str(world_db["GOD_MOOD"]) + "\n" + \
                  str(world_db["GOD_FAVOR"]) + "\n" + \
@@ -475,7 +475,10 @@ def remake_map():
 def update_map_memory(t, age_map=True):
     """Update t's T_MEMMAP with what's in its FOV now,age its T_MEMMEPTHMAP."""
     def age_some_memdepthmap_on_nonfov_cells():
 def update_map_memory(t, age_map=True):
     """Update t's T_MEMMAP with what's in its FOV now,age its T_MEMMEPTHMAP."""
     def age_some_memdepthmap_on_nonfov_cells():
-        # OUTSOURCED TO libplomrogue.so:
+        # OUTSOURCED FOR PERFORMANCE REASONS TO libplomrogue.so:
+        # ord_v = ord("v")
+        # ord_0 = ord("0")
+        # ord_9 = ord("9")
         # for pos in [pos for pos in range(world_db["MAP_LENGTH"] ** 2)
         #             if not ord_v == t["fovmap"][pos]
         #             if ord_0 <= t["T_MEMDEPTHMAP"][pos]
         # for pos in [pos for pos in range(world_db["MAP_LENGTH"] ** 2)
         #             if not ord_v == t["fovmap"][pos]
         #             if ord_0 <= t["T_MEMDEPTHMAP"][pos]
@@ -501,8 +504,8 @@ def update_map_memory(t, age_map=True):
     if age_map:
         age_some_memdepthmap_on_nonfov_cells()
     for mt in [mt for mt in t["T_MEMTHING"]
     if age_map:
         age_some_memdepthmap_on_nonfov_cells()
     for mt in [mt for mt in t["T_MEMTHING"]
-               if "v" == chr(t["fovmap"][(mt[1] * world_db["MAP_LENGTH"])
-                                         + mt[2]])]:
+               if ord_v == t["fovmap"][(mt[1] * world_db["MAP_LENGTH"])
+                                       + mt[2]]]:
         t["T_MEMTHING"].remove(mt)
     for id in [id for id in world_db["Things"]
                if not world_db["Things"][id]["carried"]]:
         t["T_MEMTHING"].remove(mt)
     for id in [id for id in world_db["Things"]
                if not world_db["Things"][id]["carried"]]:
@@ -510,7 +513,7 @@ def update_map_memory(t, age_map=True):
         if not world_db["ThingTypes"][type]["TT_LIFEPOINTS"]:
             y = world_db["Things"][id]["T_POSY"]
             x = world_db["Things"][id]["T_POSX"]
         if not world_db["ThingTypes"][type]["TT_LIFEPOINTS"]:
             y = world_db["Things"][id]["T_POSY"]
             x = world_db["Things"][id]["T_POSX"]
-            if "v" == chr(t["fovmap"][(y * world_db["MAP_LENGTH"]) + x]):
+            if ord_v == t["fovmap"][(y * world_db["MAP_LENGTH"]) + x]:
                 t["T_MEMTHING"].append((type, y, x))
 
 
                 t["T_MEMTHING"].append((type, y, x))
 
 
@@ -579,8 +582,12 @@ def decrement_lifepoints(t):
     If t is the player avatar, only blank its fovmap, so that the client may
     still display memory data. On non-player things, erase fovmap and memory.
     """
     If t is the player avatar, only blank its fovmap, so that the client may
     still display memory data. On non-player things, erase fovmap and memory.
     """
+    # # 7DRL: also decrements God's mood; deaths heavily so
+    # # 7DRL: return 1 if death, else 0
     t["T_LIFEPOINTS"] -= 1
     t["T_LIFEPOINTS"] -= 1
+    world_db["GOD_MOOD"] -= 1  # #
     if 0 == t["T_LIFEPOINTS"]:
     if 0 == t["T_LIFEPOINTS"]:
+        world_db["GOD_MOOD"] -= 9  # #
         t["T_TYPE"] = world_db["ThingTypes"][t["T_TYPE"]]["TT_CORPSE_ID"]
         if world_db["Things"][0] == t:
             t["fovmap"] = bytearray(b' ' * (world_db["MAP_LENGTH"] ** 2))
         t["T_TYPE"] = world_db["ThingTypes"][t["T_TYPE"]]["TT_CORPSE_ID"]
         if world_db["Things"][0] == t:
             t["fovmap"] = bytearray(b' ' * (world_db["MAP_LENGTH"] ** 2))
@@ -590,7 +597,8 @@ def decrement_lifepoints(t):
             t["T_MEMMAP"] = False
             t["T_MEMDEPTHMAP"] = False
             t["T_MEMTHING"] = []
             t["T_MEMMAP"] = False
             t["T_MEMDEPTHMAP"] = False
             t["T_MEMTHING"] = []
-            strong_write(io_db["file_out"], "LOG It dies.\n")
+        return 1  # #
+    return 0  # #
 
 
 def mv_yx_in_dir_legal(dir, y, x):
 
 
 def mv_yx_in_dir_legal(dir, y, x):
@@ -610,6 +618,7 @@ def actor_wait(t):
 
 def actor_move(t):
     """If passable, move/collide(=attack) thing into T_ARGUMENT's direction."""
 
 def actor_move(t):
     """If passable, move/collide(=attack) thing into T_ARGUMENT's direction."""
+    # # 7DRL: Player wounding (worse: killing) others will lower God's favor.
     passable = False
     move_result = mv_yx_in_dir_legal(chr(t["T_ARGUMENT"]),
                                      t["T_POSY"], t["T_POSX"])
     passable = False
     move_result = mv_yx_in_dir_legal(chr(t["T_ARGUMENT"]),
                                      t["T_POSY"], t["T_POSX"])
@@ -623,15 +632,19 @@ def actor_move(t):
                   if world_db["Things"][id]["T_POSX"] == move_result[2]]
         if len(hitted):
             hit_id = hitted[0]
                   if world_db["Things"][id]["T_POSX"] == move_result[2]]
         if len(hitted):
             hit_id = hitted[0]
-            hitter_name = world_db["ThingTypes"][t["T_TYPE"]]["TT_NAME"]
-            hitter = "You" if t == world_db["Things"][0] else hitter_name
-            hitted_type = world_db["Things"][hit_id]["T_TYPE"]
-            hitted_name = world_db["ThingTypes"][hitted_type]["TT_NAME"]
-            hitted = "you" if hit_id == 0 else hitted_name
-            verb = " wound " if hitter == "You" else " wounds "
-            strong_write(io_db["file_out"], "LOG " + hitter + verb + hitted +
-                                            ".\n")
-            decrement_lifepoints(world_db["Things"][hit_id])
+            if t == world_db["Things"][0]:
+                hitted_type = world_db["Things"][hit_id]["T_TYPE"]
+                hitted_name = world_db["ThingTypes"][hitted_type]["TT_NAME"]
+                strong_write(io_db["file_out"], "LOG You wound " + hitted_name
+                                                + ".\n")
+                world_db["GOD_FAVOR"] -= 1  # #
+            elif 0 == hit_id:
+                hitter_name = world_db["ThingTypes"][t["T_TYPE"]]["TT_NAME"]
+                strong_write(io_db["file_out"], "LOG " + hitter_name +
+                                                " wounds you.\n")
+            test = decrement_lifepoints(world_db["Things"][hit_id])  # #
+            if test and t == world_db["Things"][0]:  # #
+                world_db["GOD_FAVOR"] -= 10  # #
             return
     dir = [dir for dir in directions_db
            if directions_db[dir] == chr(t["T_ARGUMENT"])][0]
             return
     dir = [dir for dir in directions_db
            if directions_db[dir] == chr(t["T_ARGUMENT"])][0]
@@ -651,22 +664,27 @@ def actor_move(t):
 def actor_pick_up(t):
     """Make t pick up (topmost?) Thing from ground into inventory."""
     # Topmostness is actually not defined so far. Picks Thing with highest ID.
 def actor_pick_up(t):
     """Make t pick up (topmost?) Thing from ground into inventory."""
     # Topmostness is actually not defined so far. Picks Thing with highest ID.
-    ids = [id for id in world_db["Things"] if world_db["Things"][id] != t
-           if not world_db["Things"][id]["carried"]
-           if world_db["Things"][id]["T_POSY"] == t["T_POSY"]
-           if world_db["Things"][id]["T_POSX"] == t["T_POSX"]]
-    if len(ids):
-        highest_id = 0
-        for id in ids:
-            if id > highest_id:
-                highest_id = id
-        world_db["Things"][highest_id]["carried"] = True
-        t["T_CARRIES"].append(highest_id)
-        if t == world_db["Things"][0]:
-            strong_write(io_db["file_out"], "LOG You pick up an object.\n")
-    elif t == world_db["Things"][0]:
-        err = "You try to pick up an object, but there is none."
-        strong_write(io_db["file_out"], "LOG " + err + "\n")
+    used_slots = len(t["T_CARRIES"]) # #
+    if used_slots < world_db["ThingTypes"][t["T_TYPE"]]["TT_STORAGE"]: # #
+        ids = [id for id in world_db["Things"] if world_db["Things"][id] != t
+               if not world_db["Things"][id]["carried"]
+               if world_db["Things"][id]["T_POSY"] == t["T_POSY"]
+               if world_db["Things"][id]["T_POSX"] == t["T_POSX"]]
+        if len(ids):
+            highest_id = 0
+            for id in ids:
+                if id > highest_id:
+                    highest_id = id
+            world_db["Things"][highest_id]["carried"] = True
+            t["T_CARRIES"].append(highest_id)
+            if t == world_db["Things"][0]:
+                strong_write(io_db["file_out"], "LOG You pick up an object.\n")
+        elif t == world_db["Things"][0]:
+            err = "You try to pick up an object, but there is none."
+            strong_write(io_db["file_out"], "LOG " + err + "\n")
+    elif t == world_db["Things"][0]: # #
+        strong_write(io_db["file_out"], "LOG Can't pick up object: " + # #
+                                        "No storage room to carry more.\n") # #
 
 
 def actor_drop(t):
 
 
 def actor_drop(t):
@@ -712,6 +730,7 @@ def thingproliferation(t):
     animate, any other animate Thing. If there are several map cell candidates,
     one is selected randomly.
     """
     animate, any other animate Thing. If there are several map cell candidates,
     one is selected randomly.
     """
+    # # 7DRL: success increments God's mood
     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"]
     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"]
@@ -735,6 +754,7 @@ def thingproliferation(t):
             id = id_setter(-1, "Things")
             newT = new_Thing(t["T_TYPE"], (candidates[i][0], candidates[i][1]))
             world_db["Things"][id] = newT
             id = id_setter(-1, "Things")
             newT = new_Thing(t["T_TYPE"], (candidates[i][0], candidates[i][1]))
             world_db["Things"][id] = newT
+            world_db["GOD_MOOD"] += 1  # #
 
 
 def try_healing(t):
 
 
 def try_healing(t):
@@ -742,6 +762,7 @@ def try_healing(t):
 
     On success, decrease satiation score by 32.
     """
 
     On success, decrease satiation score by 32.
     """
+    # # 7DRL: Successful heals increment God's mood.
     if t["T_SATIATION"] > 0 \
        and t["T_LIFEPOINTS"] < \
            world_db["ThingTypes"][t["T_TYPE"]]["TT_LIFEPOINTS"] \
     if t["T_SATIATION"] > 0 \
        and t["T_LIFEPOINTS"] < \
            world_db["ThingTypes"][t["T_TYPE"]]["TT_LIFEPOINTS"] \
@@ -750,12 +771,10 @@ def try_healing(t):
                               if world_db["ThingActions"][id]["TA_NAME"] ==
                                  "wait"][0]:
         t["T_LIFEPOINTS"] += 1
                               if world_db["ThingActions"][id]["TA_NAME"] ==
                                  "wait"][0]:
         t["T_LIFEPOINTS"] += 1
+        world_db["GOD_MOOD"] += 1  # #
         t["T_SATIATION"] -= 32
         if t == world_db["Things"][0]:
             strong_write(io_db["file_out"], "LOG You heal.\n")
         t["T_SATIATION"] -= 32
         if t == world_db["Things"][0]:
             strong_write(io_db["file_out"], "LOG You heal.\n")
-        else:
-            name = world_db["ThingTypes"][t["T_TYPE"]]["TT_NAME"]
-            strong_write(io_db["file_out"], "LOG " + name + "heals.\n")
 
 
 def hunger(t):
 
 
 def hunger(t):
@@ -769,10 +788,6 @@ def hunger(t):
     if int(int(testbase / stomach) / ((rand.next() % stomach) + 1)):
         if t == world_db["Things"][0]:
             strong_write(io_db["file_out"], "LOG You suffer from hunger.\n")
     if int(int(testbase / stomach) / ((rand.next() % stomach) + 1)):
         if t == world_db["Things"][0]:
             strong_write(io_db["file_out"], "LOG You suffer from hunger.\n")
-        else:
-            name = world_db["ThingTypes"][t["T_TYPE"]]["TT_NAME"]
-            strong_write(io_db["file_out"], "LOG " + name +
-                                            " suffers from hunger.\n")
         decrement_lifepoints(t)
 
 
         decrement_lifepoints(t)
 
 
@@ -796,7 +811,7 @@ def get_dir_to_target(t, filter):
     """
 
     def zero_score_map_where_char_on_memdepthmap(c):
     """
 
     def zero_score_map_where_char_on_memdepthmap(c):
-        # OUTSOURCED TO libplomrogue.so:
+        # OUTSOURCED FOR PERFORMANCE REASONS TO libplomrogue.so:
         # for i in [i for i in range(world_db["MAP_LENGTH"] ** 2)
         #           if t["T_MEMDEPTHMAP"][i] == mem_depth_c[0]]:
         #     set_map_score(i, 0)
         # for i in [i for i in range(world_db["MAP_LENGTH"] ** 2)
         #           if t["T_MEMDEPTHMAP"][i] == mem_depth_c[0]]:
         #     set_map_score(i, 0)
@@ -840,7 +855,7 @@ def get_dir_to_target(t, filter):
         return False
 
     def set_cells_passable_on_memmap_to_65534_on_scoremap():
         return False
 
     def set_cells_passable_on_memmap_to_65534_on_scoremap():
-        # OUTSOURCED TO libplomrogue.so:
+        # OUTSOURCED FOR PERFORMANCE REASONS TO libplomrogue.so:
         # ord_dot = ord(".")
         # memmap = t["T_MEMMAP"]
         # for i in [i for i in range(world_db["MAP_LENGTH"] ** 2)
         # ord_dot = ord(".")
         # memmap = t["T_MEMMAP"]
         # for i in [i for i in range(world_db["MAP_LENGTH"] ** 2)
@@ -1009,6 +1024,7 @@ def ai(t):
     none, they will explore parts of the map unseen since ever or for at least
     one turn; if there is nothing to explore, they will simply wait.
     """
     none, they will explore parts of the map unseen since ever or for at least
     one turn; if there is nothing to explore, they will simply wait.
     """
+    # # 7DRL add: Don't pick up or search things when inventory is full.
     t["T_COMMAND"] = [id for id in world_db["ThingActions"]
                       if world_db["ThingActions"][id]["TA_NAME"] == "wait"][0]
     if not get_dir_to_target(t, "f"):
     t["T_COMMAND"] = [id for id in world_db["ThingActions"]
                       if world_db["ThingActions"][id]["TA_NAME"] == "wait"][0]
     if not get_dir_to_target(t, "f"):
@@ -1018,11 +1034,16 @@ def ai(t):
                               if world_db["ThingActions"][id]["TA_NAME"]
                                  == "use"][0]
             t["T_ARGUMENT"] = sel
                               if world_db["ThingActions"][id]["TA_NAME"]
                                  == "use"][0]
             t["T_ARGUMENT"] = sel
-        elif standing_on_consumable(t):
+        elif standing_on_consumable(t) \
+             and (len(t["T_CARRIES"]) < # #
+                 world_db["ThingTypes"][t["T_TYPE"]]["TT_STORAGE"]): # #
             t["T_COMMAND"] = [id for id in world_db["ThingActions"]
                               if world_db["ThingActions"][id]["TA_NAME"]
                                  == "pick_up"][0]
             t["T_COMMAND"] = [id for id in world_db["ThingActions"]
                               if world_db["ThingActions"][id]["TA_NAME"]
                                  == "pick_up"][0]
-        elif (not get_dir_to_target(t, "c")) and \
+        elif (not
+              (len(t["T_CARRIES"]) < # #
+                world_db["ThingTypes"][t["T_TYPE"]]["TT_STORAGE"] # #
+               and get_dir_to_target(t, "c"))) and \
              (not get_dir_to_target(t, "a")):
             get_dir_to_target(t, "s")
 
              (not get_dir_to_target(t, "a")):
             get_dir_to_target(t, "s")
 
@@ -1120,8 +1141,9 @@ def command_ping():
 
 def command_quit():
     """Abort server process."""
 
 def command_quit():
     """Abort server process."""
-    save_world()
-    atomic_write(io_db["path_record"], io_db["record_chunk"], do_append=True)
+    if None == opts.replay:
+        save_world()
+        atomic_write(io_db["path_record"], io_db["record_chunk"], do_append=True)
     raise SystemExit("received QUIT command")
 
 
     raise SystemExit("received QUIT command")
 
 
@@ -1469,6 +1491,7 @@ def command_ttid(id_string):
             "TT_LIFEPOINTS": 0,
             "TT_PROLIFERATE": 0,
             "TT_START_NUMBER": 0,
             "TT_LIFEPOINTS": 0,
             "TT_PROLIFERATE": 0,
             "TT_START_NUMBER": 0,
+            "TT_STORAGE": 0, # #
             "TT_SYMBOL": "?",
             "TT_CORPSE_ID": id
         }
             "TT_SYMBOL": "?",
             "TT_CORPSE_ID": id
         }
@@ -1582,6 +1605,7 @@ commands_db = {
     "TT_PROLIFERATE": (1, False, setter("ThingType", "TT_PROLIFERATE",
                                         0, 255)),
     "TT_LIFEPOINTS": (1, False, setter("ThingType", "TT_LIFEPOINTS", 0, 255)),
     "TT_PROLIFERATE": (1, False, setter("ThingType", "TT_PROLIFERATE",
                                         0, 255)),
     "TT_LIFEPOINTS": (1, False, setter("ThingType", "TT_LIFEPOINTS", 0, 255)),
+    "TT_STORAGE": (1, False, setter("ThingType", "TT_STORAGE", 0, 255)), # #
     "T_ID": (1, False, command_tid),
     "T_ARGUMENT": (1, False, setter("Thing", "T_ARGUMENT", 0, 255)),
     "T_PROGRESS": (1, False, setter("Thing", "T_PROGRESS", 0, 255)),
     "T_ID": (1, False, command_tid),
     "T_ARGUMENT": (1, False, setter("Thing", "T_ARGUMENT", 0, 255)),
     "T_PROGRESS": (1, False, setter("Thing", "T_PROGRESS", 0, 255)),