X-Git-Url: https://plomlompom.com/repos/?a=blobdiff_plain;f=roguelike-server;h=ff799fb74a36d86eedaf6cb51b5cebaa2e0c8444;hb=aec8de097645ebfda6d92adcdf27efa5deb00af0;hp=344f5a5618f59f80ae521404587334a467dbca38;hpb=c82cb693d765d228aacb5e28005f5967de821187;p=plomrogue diff --git a/roguelike-server b/roguelike-server index 344f5a5..ff799fb 100755 --- a/roguelike-server +++ b/roguelike-server @@ -109,7 +109,8 @@ def obey(command, prefix, replay=False, do_record=False): is called (and io_db["record_chunk"] written) if 15 seconds have passed since the last time it was called. The prefix string is inserted into the server's input message between its beginning 'input ' and ':'. All activity - is preceded by a server_test() call. + is preceded by a server_test() call. Commands that start with a lowercase + letter are ignored when world_db["WORLD_ACTIVE"] is False/0. """ server_test() if io_db["verbose"]: @@ -123,6 +124,8 @@ def obey(command, prefix, replay=False, do_record=False): and len(tokens) == commands_db[tokens[0]][0] + 1: if commands_db[tokens[0]][1]: commands_db[tokens[0]][2](*tokens[1:]) + elif tokens[0][0].islower() and not world_db["WORLD_ACTIVE"]: + print("Ignoring lowercase-starting commands when world inactive.") elif replay: print("Due to replay mode, reading command as 'go on in record'.") line = io_db["file_record"].readline() @@ -139,7 +142,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"] @@ -171,10 +175,11 @@ def save_world(): return '"' + string.replace('"', '\u005C"') + '"' def mapsetter(key): - def helper(id): + def helper(id=None): string = "" - if world_db["Things"][id][key]: - map = world_db["Things"][id][key] + if key == "MAP" or world_db["Things"][id][key]: + map = world_db["MAP"] if key == "MAP" \ + else world_db["Things"][id][key] length = world_db["MAP_LENGTH"] for i in range(length): line = map[i * length:(i * length) + length].decode() @@ -206,9 +211,9 @@ def save_world(): string = "" for key in sorted(world_db.keys()): if (not isinstance(world_db[key], dict)) and key != "MAP" and \ - key != "WORLD_ACTIVE" and key != "SEED_MAP": + key != "WORLD_ACTIVE": string = string + key + " " + str(world_db[key]) + "\n" - string = string + "SEED_MAP " + str(world_db["SEED_MAP"]) + "\n" + string = string + mapsetter("MAP")() string = string + helper("ThingActions", "TA_ID") string = string + helper("ThingTypes", "TT_ID", {"TT_CORPSE_ID": False}) for id in sorted(world_db["ThingTypes"].keys()): @@ -304,7 +309,7 @@ def try_worldstate_update(): def draw_visible_Things(map, run): for id in world_db["Things"]: type = world_db["Things"][id]["T_TYPE"] - consumable = world_db["ThingTypes"][type]["TT_CONSUMABLE"] + consumable = world_db["ThingTypes"][type]["TT_TOOL"] == "food" alive = world_db["ThingTypes"][type]["TT_LIFEPOINTS"] if (0 == run and not consumable and not alive) \ or (1 == run and consumable and not alive) \ @@ -348,7 +353,7 @@ def try_worldstate_update(): mem = world_db["Things"][0]["T_MEMMAP"][:] for i in range(2): for mt in world_db["Things"][0]["T_MEMTHING"]: - consumable = world_db["ThingTypes"][mt[0]]["TT_CONSUMABLE"] + consumable = world_db["ThingTypes"][mt[0]]["TT_TOOL"] == "food" if (i == 0 and not consumable) or (i == 1 and consumable): c = world_db["ThingTypes"][mt[0]]["TT_SYMBOL"] mem[(mt[1] * length) + mt[2]] = ord(c) @@ -409,7 +414,7 @@ def play_game(): obey(read_command(), "in file", do_record=True) -def remake_map(): +def make_map(): """(Re-)make island map. Let "~" represent water, "." land, "X" trees: Build island shape randomly, @@ -418,6 +423,7 @@ def remake_map(): to land. The cycle ends when a land cell is due to be created at the map's border. Then put some trees on the map (TODO: more precise algorithm desc). """ + def is_neighbor(coordinates, type): y = coordinates[0] x = coordinates[1] @@ -440,8 +446,7 @@ def remake_map(): and type == chr(world_db["MAP"][pos + length - (not ind)])): return True return False - store_seed = rand.seed - rand.seed = world_db["SEED_MAP"] + world_db["MAP"] = bytearray(b'~' * (world_db["MAP_LENGTH"] ** 2)) length = world_db["MAP_LENGTH"] add_half_width = (not (length % 2)) * int(length / 2) @@ -465,12 +470,12 @@ def remake_map(): and ((not single_allowed) or is_neighbor((y, x), "X")): world_db["MAP"][pos] = ord("X") i_trees += 1 - rand.seed = store_seed # This all-too-precise replica of the original C code misses iter_limit(). 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") @@ -486,6 +491,7 @@ def update_map_memory(t, age_map=True): 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"]: @@ -500,10 +506,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"] @@ -573,18 +578,31 @@ def build_fov_map(t): raise RuntimeError("Malloc error in build_fov_Map().") +def log_help(): + """Send quick usage info to log.""" + strong_write(io_db["file_out"], "LOG See README file for help.\n") + + def decrement_lifepoints(t): """Decrement t's lifepoints by 1, and if to zero, corpse it. 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. + Dying actors drop all their things. """ t["T_LIFEPOINTS"] -= 1 if 0 == t["T_LIFEPOINTS"]: + for id in t["T_CARRIES"]: + t["T_CARRIES"].remove(id) + world_db["Things"][id]["T_POSY"] = t["T_POSY"] + world_db["Things"][id]["T_POSX"] = t["T_POSX"] + world_db["Things"][id]["carried"] = False 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)) strong_write(io_db["file_out"], "LOG You die.\n") + strong_write(io_db["file_out"], + "LOG See README on how to start over.\n") else: t["fovmap"] = False t["T_MEMMAP"] = False @@ -650,15 +668,19 @@ 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. + # Topmostness is actually not defined so far. Picks most nutritious Thing. 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 + highest_id = ids[0] + nutritious = 0 for id in ids: - if id > highest_id: + type = world_db["Things"][id]["T_TYPE"] + if world_db["ThingTypes"][type]["TT_TOOL"] == "food" \ + and world_db["ThingTypes"][type]["TT_TOOLPOWER"] > nutritious: + nutritious = world_db["ThingTypes"][type]["TT_TOOLPOWER"] highest_id = id world_db["Things"][highest_id]["carried"] = True t["T_CARRIES"].append(highest_id) @@ -689,10 +711,10 @@ def actor_use(t): if len(t["T_CARRIES"]): id = t["T_CARRIES"][t["T_ARGUMENT"]] type = world_db["Things"][id]["T_TYPE"] - if world_db["ThingTypes"][type]["TT_CONSUMABLE"]: + if world_db["ThingTypes"][type]["TT_TOOL"] == "food": t["T_CARRIES"].remove(id) del world_db["Things"][id] - t["T_SATIATION"] += world_db["ThingTypes"][type]["TT_CONSUMABLE"] + t["T_SATIATION"] += world_db["ThingTypes"][type]["TT_TOOLPOWER"] if t == world_db["Things"][0]: strong_write(io_db["file_out"], "LOG You consume this object.\n") @@ -704,31 +726,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) @@ -828,7 +840,7 @@ def get_dir_to_target(t, filter): for mt in t["T_MEMTHING"]: if ' ' != chr(t["T_MEMMAP"][(mt[1] * world_db["MAP_LENGTH"]) + mt[2]]) \ - and world_db["ThingTypes"][mt[0]]["TT_CONSUMABLE"]: + and world_db["ThingTypes"][mt[0]]["TT_TOOL"] == "food": return True return False @@ -880,7 +892,7 @@ def get_dir_to_target(t, filter): if ord_blank != t["T_MEMMAP"][mt[1] * world_db["MAP_LENGTH"] + mt[2]] - if world_db["ThingTypes"][mt[0]]["TT_CONSUMABLE"]]: + if world_db["ThingTypes"][mt[0]]["TT_TOOL"] == "food"]: set_map_score(mt[1] * world_db["MAP_LENGTH"] + mt[2], 0) elif "s" == filter: zero_score_map_where_char_on_memdepthmap(mem_depth_c[0]) @@ -966,26 +978,27 @@ def get_dir_to_target(t, filter): return dir_to_target -def standing_on_consumable(t): +def standing_on_food(t): """Return True/False whether t is standing on a consumable.""" for id in [id for id in world_db["Things"] if world_db["Things"][id] != t if world_db["Things"][id]["T_POSY"] == t["T_POSY"] if world_db["Things"][id]["T_POSX"] == t["T_POSX"] if world_db["ThingTypes"][world_db["Things"][id]["T_TYPE"]] - ["TT_CONSUMABLE"]]: + ["TT_TOOL"] == "food"]: return True return False def get_inventory_slot_to_consume(t): """Return slot Id of strongest consumable in t's inventory, else -1.""" - cmp_consumability = 0 + cmp_food = 0 selection = -1 i = 0 for id in t["T_CARRIES"]: type = world_db["Things"][id]["T_TYPE"] - if world_db["ThingTypes"][type]["TT_CONSUMABLE"] > cmp_consumability: - cmp_consumability = world_db["ThingTypes"][type]["TT_CONSUMABLE"] + if world_db["ThingTypes"][type]["TT_TOOL"] == "food" \ + and world_db["ThingTypes"][type]["TT_TOOLPOWER"] > cmp_food: + cmp_food = world_db["ThingTypes"][type]["TT_TOOLPOWER"] selection = i i += 1 return selection @@ -1011,7 +1024,7 @@ def ai(t): if world_db["ThingActions"][id]["TA_NAME"] == "use"][0] t["T_ARGUMENT"] = sel - elif standing_on_consumable(t): + elif standing_on_food(t): t["T_COMMAND"] = [id for id in world_db["ThingActions"] if world_db["ThingActions"][id]["TA_NAME"] == "pick_up"][0] @@ -1025,6 +1038,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 @@ -1038,16 +1057,17 @@ def turn_over(): break ai(Thing) try_healing(Thing) - Thing["T_PROGRESS"] += 1 - taid = [a for a in world_db["ThingActions"] - if a == Thing["T_COMMAND"]][0] - ThingAction = world_db["ThingActions"][taid] - if Thing["T_PROGRESS"] == ThingAction["TA_EFFORT"]: - eval("actor_" + ThingAction["TA_NAME"])(Thing) - Thing["T_COMMAND"] = 0 - Thing["T_PROGRESS"] = 0 hunger(Thing) - thingproliferation(Thing) + if Thing["T_LIFEPOINTS"]: + Thing["T_PROGRESS"] += 1 + taid = [a for a in world_db["ThingActions"] + if a == Thing["T_COMMAND"]][0] + ThingAction = world_db["ThingActions"][taid] + if Thing["T_PROGRESS"] == ThingAction["TA_EFFORT"]: + eval("actor_" + ThingAction["TA_NAME"])(Thing) + Thing["T_COMMAND"] = 0 + Thing["T_PROGRESS"] = 0 + thingproliferation(Thing, proliferable_map) if whilebreaker: break world_db["TURN"] += 1 @@ -1111,8 +1131,10 @@ def command_ping(): 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: + 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") @@ -1185,22 +1207,17 @@ def command_seedrandomness(seed_string): rand.seed = val -def command_seedmap(seed_string): - """Set world_db["SEED_MAP"] to int(seed_string), then (re-)make map.""" - setter(None, "SEED_MAP", 0, 4294967295)(seed_string) - remake_map() - - def command_makeworld(seed_string): """(Re-)build game world, i.e. map, things, to a new turn 1 from seed. - Seed rand with seed, fill it into world_db["SEED_MAP"]. Do more only with a - "wait" ThingAction and world["PLAYER_TYPE"] matching ThingType of - TT_START_NUMBER > 0. Then, world_db["Things"] emptied, call remake_map() - and set world_db["WORLD_ACTIVE"], world_db["TURN"] to 1. Build new Things + Seed rand with seed. Do more only with a "wait" ThingAction and + world["PLAYER_TYPE"] matching ThingType of TT_START_NUMBER > 0. Then, + world_db["Things"] emptied, call make_map() and set + world_db["WORLD_ACTIVE"], world_db["TURN"] to 1. Build new Things according to ThingTypes' TT_START_NUMBERS, with Thing of ID 0 to ThingType of ID = world["PLAYER_TYPE"]. Place Things randomly, and actors not on each other. Init player's memory map. Write "NEW_WORLD" line to out file. + Call log_help(). """ def free_pos(): @@ -1228,7 +1245,6 @@ def command_makeworld(seed_string): if None == val: return rand.seed = val - world_db["SEED_MAP"] = val player_will_be_generated = False playertype = world_db["PLAYER_TYPE"] for ThingType in world_db["ThingTypes"]: @@ -1237,8 +1253,7 @@ def command_makeworld(seed_string): player_will_be_generated = True break if not player_will_be_generated: - print("Ignoring beyond SEED_MAP: " + - "No player type with start number >0 defined.") + print("Ignoring: No player type with start number >0 defined.") return wait_action = False for ThingAction in world_db["ThingActions"]: @@ -1249,12 +1264,15 @@ def command_makeworld(seed_string): "No thing action with name 'wait' defined.") return world_db["Things"] = {} - remake_map() + make_map() world_db["WORLD_ACTIVE"] = 1 world_db["TURN"] = 1 for i in range(world_db["ThingTypes"][playertype]["TT_START_NUMBER"]): id = id_setter(-1, "Things") world_db["Things"][id] = new_Thing(playertype, free_pos()) + if not world_db["Things"][0]["fovmap"]: + empty_fovmap = bytearray(b" " * world_db["MAP_LENGTH"] ** 2) + world_db["Things"][0]["fovmap"] = empty_fovmap update_map_memory(world_db["Things"][0]) for type in world_db["ThingTypes"]: for i in range(world_db["ThingTypes"][type]["TT_START_NUMBER"]): @@ -1262,6 +1280,7 @@ def command_makeworld(seed_string): id = id_setter(-1, "Things") world_db["Things"][id] = new_Thing(type, free_pos()) strong_write(io_db["file_out"], "NEW_WORLD\n") + log_help() def command_maplength(maplength_string): @@ -1269,6 +1288,7 @@ def command_maplength(maplength_string): val = integer_test(maplength_string, 1, 256) if None != val: world_db["MAP_LENGTH"] = val + world_db["MAP"] = False set_world_inactive() world_db["Things"] = {} libpr.set_maplength(val) @@ -1278,12 +1298,12 @@ 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. + Also call log_help(). """ - # In original version, map existence was also tested (unnecessarily?). val = integer_test(worldactive_string, 0, 1) - if val: + if None != val: if 0 != world_db["WORLD_ACTIVE"]: if 0 == val: set_world_inactive() @@ -1300,13 +1320,19 @@ 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 world_db["MAP"]: for id in world_db["Things"]: if world_db["Things"][id]["T_LIFEPOINTS"]: build_fov_map(world_db["Things"][id]) if 0 == id: update_map_memory(world_db["Things"][id], False) + if not world_db["Things"][0]["T_LIFEPOINTS"]: + empty_fovmap = bytearray(b" " * world_db["MAP_LENGTH"] ** 2) + world_db["Things"][0]["fovmap"] = empty_fovmap world_db["WORLD_ACTIVE"] = 1 + log_help() + else: + print("Ignoring: Not all conditions for world activation met.") def test_for_id_maker(object, category): @@ -1402,12 +1428,12 @@ def command_tmemthing(str_t, str_y, str_x): def setter_map(maptype): - """Set selected Thing's map of maptype's int(str_int)-th line to mapline. + """Set (world or Thing's) map of maptype's int(str_int)-th line to mapline. - If Thing has no map of maptype yet, initialize it with ' ' bytes first. + If no map of maptype exists yet, initialize it with ' ' bytes first. """ - @test_Thing_id - def helper(str_int, mapline): + + def valid_map_line(str_int, mapline): val = integer_test(str_int, 0, 255) if None != val: if val >= world_db["MAP_LENGTH"]: @@ -1415,15 +1441,36 @@ def setter_map(maptype): elif len(mapline) != world_db["MAP_LENGTH"]: print("Map line length is unequal map width.") else: - length = world_db["MAP_LENGTH"] - map = None - if not world_db["Things"][command_tid.id][maptype]: - map = bytearray(b' ' * (length ** 2)) - else: - map = world_db["Things"][command_tid.id][maptype] - map[val * length:(val * length) + length] = mapline.encode() + return val + return None + + def nonThingMap_helper(str_int, mapline): + val = valid_map_line(str_int, mapline) + if None != val: + length = world_db["MAP_LENGTH"] + if not world_db["MAP"]: + map = bytearray(b' ' * (length ** 2)) + else: + map = world_db["MAP"] + map[val * length:(val * length) + length] = mapline.encode() + if not world_db["MAP"]: + world_db["MAP"] = map + + @test_Thing_id + def ThingMap_helper(str_int, mapline): + val = valid_map_line(str_int, mapline) + if None != val: + length = world_db["MAP_LENGTH"] + if not world_db["Things"][command_tid.id][maptype]: + map = bytearray(b' ' * (length ** 2)) + else: + map = world_db["Things"][command_tid.id][maptype] + map[val * length:(val * length) + length] = mapline.encode() + if not world_db["Things"][command_tid.id][maptype]: world_db["Things"][command_tid.id][maptype] = map - return helper + + return nonThingMap_helper if maptype == "MAP" else ThingMap_helper + def setter_tpos(axis): @@ -1450,18 +1497,20 @@ def setter_tpos(axis): def command_ttid(id_string): """Set ID of ThingType to manipulate. ID unused? Create new one. - Default new ThingType's TT_SYMBOL to "?", TT_CORPSE_ID to self, others: 0. + Default new ThingType's TT_SYMBOL to "?", TT_CORPSE_ID to self, TT_TOOL to + "", others: 0. """ id = id_setter(id_string, "ThingTypes", command_ttid) if None != id: world_db["ThingTypes"][id] = { "TT_NAME": "(none)", - "TT_CONSUMABLE": 0, + "TT_TOOLPOWER": 0, "TT_LIFEPOINTS": 0, "TT_PROLIFERATE": 0, "TT_START_NUMBER": 0, "TT_SYMBOL": "?", - "TT_CORPSE_ID": id + "TT_CORPSE_ID": id, + "TT_TOOL": "" } @@ -1474,6 +1523,12 @@ def command_ttname(name): world_db["ThingTypes"][command_ttid.id]["TT_NAME"] = name +@test_ThingType_id +def command_tttool(name): + """Set TT_TOOL of selected ThingType.""" + world_db["ThingTypes"][command_ttid.id]["TT_TOOL"] = name + + @test_ThingType_id def command_ttsymbol(char): """Set TT_SYMBOL of selected ThingType. """ @@ -1551,25 +1606,25 @@ commands_db = { "PING": (0, True, command_ping), "THINGS_HERE": (2, True, command_thingshere), "MAKE_WORLD": (1, False, command_makeworld), - "SEED_MAP": (1, False, command_seedmap), "SEED_RANDOMNESS": (1, False, command_seedrandomness), "TURN": (1, False, setter(None, "TURN", 0, 65535)), "PLAYER_TYPE": (1, False, setter(None, "PLAYER_TYPE", 0)), "MAP_LENGTH": (1, False, command_maplength), "WORLD_ACTIVE": (1, False, command_worldactive), + "MAP": (2, False, setter_map("MAP")), "TA_ID": (1, False, command_taid), "TA_EFFORT": (1, False, setter("ThingAction", "TA_EFFORT", 0, 255)), "TA_NAME": (1, False, command_taname), "TT_ID": (1, False, command_ttid), "TT_NAME": (1, False, command_ttname), + "TT_TOOL": (1, False, command_tttool), "TT_SYMBOL": (1, False, command_ttsymbol), "TT_CORPSE_ID": (1, False, command_ttcorpseid), - "TT_CONSUMABLE": (1, False, setter("ThingType", "TT_CONSUMABLE", - 0, 65535)), + "TT_TOOLPOWER": (1, False, setter("ThingType", "TT_TOOLPOWER", 0, 65535)), "TT_START_NUMBER": (1, False, setter("ThingType", "TT_START_NUMBER", 0, 255)), "TT_PROLIFERATE": (1, False, setter("ThingType", "TT_PROLIFERATE", - 0, 255)), + 0, 65535)), "TT_LIFEPOINTS": (1, False, setter("ThingType", "TT_LIFEPOINTS", 0, 255)), "T_ID": (1, False, command_tid), "T_ARGUMENT": (1, False, setter("Thing", "T_ARGUMENT", 0, 255)), @@ -1591,15 +1646,16 @@ commands_db = { "use": (1, False, play_commander("use", True)), "ai": (0, False, command_ai) } +# TODO: Unhandled cases: (Un-)killing animates (esp. player!) with T_LIFEPOINTS. """World state database. With sane default values. (Randomness is in rand.)""" world_db = { "TURN": 0, "MAP_LENGTH": 64, - "SEED_MAP": 0, "PLAYER_TYPE": 0, "WORLD_ACTIVE": 0, + "MAP": False, "ThingActions": {}, "ThingTypes": {}, "Things": {}