home · contact · privacy
Fix replay mode overwriting save file on quit.
[plomrogue] / roguelike-server
index 8cd8162bd63e28954354e1d13f0d01fc5a4b09ce..98a92dff04653ac5cc6063a704d14bc98f63f88e 100755 (executable)
@@ -39,6 +39,12 @@ def prep_library():
     return libpr
 
 
     return libpr
 
 
+def c_pointer_to_bytearray(ba):
+    """Return C char * pointer to ba."""
+    type = ctypes.c_char * len(ba)
+    return type.from_buffer(ba)
+
+
 def strong_write(file, string):
     """Apply write(string), then flush()."""
     file.write(string)
 def strong_write(file, string):
     """Apply write(string), then flush()."""
     file.write(string)
@@ -324,7 +330,10 @@ 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
         string = str(world_db["TURN"]) + "\n" + \
         string = str(world_db["TURN"]) + "\n" + \
+                 str(world_db["GOD_MOOD"]) + "\n" + \
+                 str(world_db["GOD_FAVOR"]) + "\n" + \
                  str(world_db["Things"][0]["T_LIFEPOINTS"]) + "\n" + \
                  str(world_db["Things"][0]["T_SATIATION"]) + "\n" + \
                  inventory + "%\n" + \
                  str(world_db["Things"][0]["T_LIFEPOINTS"]) + "\n" + \
                  str(world_db["Things"][0]["T_SATIATION"]) + "\n" + \
                  inventory + "%\n" + \
@@ -465,6 +474,21 @@ 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 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 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]
+        #             if ord_9 > t["T_MEMDEPTHMAP"][pos]
+        #             if not rand.next() % (2 **
+        #                                   (t["T_MEMDEPTHMAP"][pos] - 48))]:
+        #     t["T_MEMDEPTHMAP"][pos] += 1
+        memdepthmap = c_pointer_to_bytearray(t["T_MEMDEPTHMAP"])
+        fovmap = c_pointer_to_bytearray(t["fovmap"])
+        libpr.age_some_memdepthmap_on_nonfov_cells(memdepthmap, fovmap)
     if not t["T_MEMMAP"]:
         t["T_MEMMAP"] = bytearray(b' ' * (world_db["MAP_LENGTH"] ** 2))
     if not t["T_MEMDEPTHMAP"]:
     if not t["T_MEMMAP"]:
         t["T_MEMMAP"] = bytearray(b' ' * (world_db["MAP_LENGTH"] ** 2))
     if not t["T_MEMDEPTHMAP"]:
@@ -478,21 +502,18 @@ def update_map_memory(t, age_map=True):
         if ord_space == t["T_MEMMAP"][pos]:
             t["T_MEMMAP"][pos] = world_db["MAP"][pos]
     if age_map:
         if ord_space == t["T_MEMMAP"][pos]:
             t["T_MEMMAP"][pos] = world_db["MAP"][pos]
     if age_map:
-        maptype = ctypes.c_char * len(t["T_MEMDEPTHMAP"])
-        memdepthmap = maptype.from_buffer(t["T_MEMDEPTHMAP"])
-        fovmap = maptype.from_buffer(t["fovmap"])
-        libpr.age_some_memdepthmap_on_nonfov_cells(memdepthmap, fovmap)
+        age_some_memdepthmap_on_nonfov_cells()
     for mt in [mt for mt in t["T_MEMTHING"]
     for mt in [mt for mt in t["T_MEMTHING"]
-               if "v" == chr(t["fovmap"][(mt[1] * world_db["MAP_LENGTH"])
-                                         + mt[2]])]:
-         t["T_MEMTHING"].remove(mt)
+               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"]]:
         type = world_db["Things"][id]["T_TYPE"]
         if not world_db["ThingTypes"][type]["TT_LIFEPOINTS"]:
             y = world_db["Things"][id]["T_POSY"]
             x = world_db["Things"][id]["T_POSX"]
     for id in [id for id in world_db["Things"]
                if not world_db["Things"][id]["carried"]]:
         type = world_db["Things"][id]["T_TYPE"]
         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))
 
 
@@ -508,12 +529,12 @@ def integer_test(val_string, min, max=None):
     """Return val_string if possible integer >= min and <= max, else None."""
     try:
         val = int(val_string)
     """Return val_string if possible integer >= min and <= max, else None."""
     try:
         val = int(val_string)
-        if val < min or (max != None and val > max):
+        if val < min or (max is not None and val > max):
             raise ValueError
         return val
     except ValueError:
         msg = "Ignoring: Please use integer >= " + str(min)
             raise ValueError
         return val
     except ValueError:
         msg = "Ignoring: Please use integer >= " + str(min)
-        if max != None:
+        if max is not None:
             msg += " and <= " + str(max)
         msg += "."
         print(msg)
             msg += " and <= " + str(max)
         msg += "."
         print(msg)
@@ -549,11 +570,9 @@ def setter(category, key, min, max=None):
 def build_fov_map(t):
     """Build Thing's FOV map."""
     t["fovmap"] = bytearray(b'v' * (world_db["MAP_LENGTH"] ** 2))
 def build_fov_map(t):
     """Build Thing's FOV map."""
     t["fovmap"] = bytearray(b'v' * (world_db["MAP_LENGTH"] ** 2))
-    maptype = ctypes.c_char * len(world_db["MAP"])
-    test = libpr.build_fov_map(t["T_POSY"], t["T_POSX"],
-                               maptype.from_buffer(t["fovmap"]),
-                               maptype.from_buffer(world_db["MAP"]))
-    if test:
+    fovmap = c_pointer_to_bytearray(t["fovmap"])
+    map = c_pointer_to_bytearray(world_db["MAP"])
+    if libpr.build_fov_map(t["T_POSY"], t["T_POSX"], fovmap, map):
         raise RuntimeError("Malloc error in build_fov_Map().")
 
 
         raise RuntimeError("Malloc error in build_fov_Map().")
 
 
@@ -563,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))
@@ -574,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):
@@ -594,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"])
@@ -607,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]
@@ -635,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):
@@ -696,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"]
@@ -719,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):
@@ -726,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"] \
@@ -734,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):
@@ -753,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)
 
 
@@ -780,10 +811,12 @@ 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):
-        maptype = ctypes.c_char * len(t["T_MEMDEPTHMAP"])
-        map = maptype.from_buffer(t["T_MEMDEPTHMAP"])
-        test = libpr.zero_score_map_where_char_on_memdepthmap(c, map)
-        if test:
+        # 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)
+        map = c_pointer_to_bytearray(t["T_MEMDEPTHMAP"])
+        if libpr.zero_score_map_where_char_on_memdepthmap(c, map):
             raise RuntimeError("No score map allocated for "
                                "zero_score_map_where_char_on_memdepthmap().")
 
             raise RuntimeError("No score map allocated for "
                                "zero_score_map_where_char_on_memdepthmap().")
 
@@ -821,16 +854,25 @@ def get_dir_to_target(t, filter):
                     return True
         return False
 
                     return True
         return False
 
+    def set_cells_passable_on_memmap_to_65534_on_scoremap():
+        # 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)
+        #            if ord_dot == memmap[i]]:
+        #     set_map_score(i, 65534) # i.e. 65535-1
+        map = c_pointer_to_bytearray(t["T_MEMMAP"])
+        if libpr.set_cells_passable_on_memmap_to_65534_on_scoremap(map):
+            raise RuntimeError("No score map allocated for "
+                        "set_cells_passable_on_memmap_to_65534_on_scoremap().")
+
     def init_score_map():
         test = libpr.init_score_map()
         if test:
             raise RuntimeError("Malloc error in init_score_map().")
     def init_score_map():
         test = libpr.init_score_map()
         if test:
             raise RuntimeError("Malloc error in init_score_map().")
-        ord_dot = ord(".")
         ord_v = ord("v")
         ord_blank = ord(" ")
         ord_v = ord("v")
         ord_blank = ord(" ")
-        for i in [i for i in range(world_db["MAP_LENGTH"] ** 2)
-                  if ord_dot == t["T_MEMMAP"][i]]:
-            set_map_score(i, 65535 - 1)
+        set_cells_passable_on_memmap_to_65534_on_scoremap()
         if "a" == filter:
             for id in world_db["Things"]:
                 Thing = world_db["Things"][id]
         if "a" == filter:
             for id in world_db["Things"]:
                 Thing = world_db["Things"][id]
@@ -982,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"):
@@ -991,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")
 
@@ -1093,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")
 
 
@@ -1442,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
         }
@@ -1536,6 +1586,8 @@ commands_db = {
     "SEED_MAP": (1, False, command_seedmap),
     "SEED_RANDOMNESS": (1, False, command_seedrandomness),
     "TURN": (1, False, setter(None, "TURN", 0, 65535)),
     "SEED_MAP": (1, False, command_seedmap),
     "SEED_RANDOMNESS": (1, False, command_seedrandomness),
     "TURN": (1, False, setter(None, "TURN", 0, 65535)),
+    "GOD_MOOD": (1, False, setter(None, "GOD_MOOD", -32768, 32767)),  # #
+    "GOD_FAVOR": (1, False, setter(None, "GOD_FAVOR", -32768, 32767)),  # #
     "PLAYER_TYPE": (1, False, setter(None, "PLAYER_TYPE", 0)),
     "MAP_LENGTH": (1, False, command_maplength),
     "WORLD_ACTIVE": (1, False, command_worldactive),
     "PLAYER_TYPE": (1, False, setter(None, "PLAYER_TYPE", 0)),
     "MAP_LENGTH": (1, False, command_maplength),
     "WORLD_ACTIVE": (1, False, command_worldactive),
@@ -1553,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)),
@@ -1582,6 +1635,8 @@ world_db = {
     "SEED_MAP": 0,
     "PLAYER_TYPE": 0,
     "WORLD_ACTIVE": 0,
     "SEED_MAP": 0,
     "PLAYER_TYPE": 0,
     "WORLD_ACTIVE": 0,
+    "GOD_MOOD": 0,  # #
+    "GOD_FAVOR": 0,  # #
     "ThingActions": {},
     "ThingTypes": {},
     "Things": {}
     "ThingActions": {},
     "ThingTypes": {},
     "Things": {}