X-Git-Url: https://plomlompom.com/repos/test.html?a=blobdiff_plain;ds=sidebyside;f=roguelike-server;h=809e03a12c1129cabf215ceb1f8218e3aa65b871;hb=8fb759331fcefbd559de144507f8b90aee3d7fb6;hp=d452efbee6ec250036dd93e2af50077b48f9270a;hpb=3b6de6a3440290478dff65f5849241d57ae431fb;p=plomrogue
diff --git a/roguelike-server b/roguelike-server
index d452efb..809e03a 100755
--- a/roguelike-server
+++ b/roguelike-server
@@ -12,6 +12,7 @@ import shlex
import shutil
import time
import ctypes
+import math # #
class RandomnessIO:
@@ -330,10 +331,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"
- ## 7DRL additions: GOD_MOOD, GOD_FAVOR
- string = str(world_db["GOD_MOOD"]) + "\n" + \
+ # # 7DRL additions: GOD_MOOD, GOD_FAVOR
+ string = str(world_db["TURN"]) + "\n" + \
+ str(world_db["GOD_MOOD"]) + "\n" + \
str(world_db["GOD_FAVOR"]) + "\n" + \
- str(world_db["TURN"]) + "\n" + \
str(world_db["Things"][0]["T_LIFEPOINTS"]) + "\n" + \
str(world_db["Things"][0]["T_SATIATION"]) + "\n" + \
inventory + "%\n" + \
@@ -474,6 +475,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 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"]:
@@ -487,21 +503,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:
- 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"]
- 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"]
- 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))
@@ -517,12 +530,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)
- 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)
- if max != None:
+ if max is not None:
msg += " and <= " + str(max)
msg += "."
print(msg)
@@ -558,11 +571,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))
- 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().")
@@ -571,9 +582,20 @@ 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.
+ Dying actors drop all their things.
"""
+ # # 7DRL: also decrements God's mood; deaths heavily so
+ # # 7DRL: return 1 if death, else 0
t["T_LIFEPOINTS"] -= 1
+ world_db["GOD_MOOD"] -= 1 # #
if 0 == t["T_LIFEPOINTS"]:
+ sadness = world_db["ThingTypes"][t["T_TYPE"]]["TT_LIFEPOINTS"] # #
+ world_db["GOD_MOOD"] -= sadness # #
+ 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))
@@ -583,7 +605,28 @@ def decrement_lifepoints(t):
t["T_MEMMAP"] = False
t["T_MEMDEPTHMAP"] = False
t["T_MEMTHING"] = []
- strong_write(io_db["file_out"], "LOG It dies.\n")
+ return sadness # #
+ return 0 # #
+
+
+def add_gods_favor(i): # #
+ """"Add to GOD_FAVOR, multiplied with factor growing log. with GOD_MOOD."""
+ def favor_multiplier(i):
+ x = 100
+ threshold = math.e * x
+ mood = world_db["GOD_MOOD"]
+ if i > 0:
+ if mood > threshold:
+ i = i * math.log(mood / x)
+ elif -mood > threshold:
+ i = i / math.log(-mood / x)
+ elif i < 0:
+ if -mood > threshold:
+ i = i * math.log(-mood / x)
+ if mood > threshold:
+ i = i / math.log(mood / x)
+ return int(i)
+ world_db["GOD_FAVOR"] += favor_multiplier(i)
def mv_yx_in_dir_legal(dir, y, x):
@@ -603,6 +646,7 @@ def actor_wait(t):
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"])
@@ -616,15 +660,19 @@ def actor_move(t):
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")
+ add_gods_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]) # #(test=)
+ if test and t == world_db["Things"][0]: # #
+ add_gods_favor(-test) # #
return
dir = [dir for dir in directions_db
if directions_db[dir] == chr(t["T_ARGUMENT"])][0]
@@ -643,23 +691,38 @@ 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.
- 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")
+ # Topmostness is actually not defined so far. Picks most nutritious Thing.
+ # 7DRL: Non-player picking up player-dropped consumable -> GOD_FAVOR gain.
+ 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 = ids[0]
+ nutritious = 0
+ for id in ids:
+ type = world_db["Things"][id]["T_TYPE"]
+ if world_db["ThingTypes"][type]["TT_CONSUMABLE"] > nutritious:
+ nutritious = world_db["ThingTypes"][type]["TT_CONSUMABLE"]
+ highest_id = id
+ world_db["Things"][highest_id]["carried"] = True
+ if (t != world_db["Things"][0] and # #
+ world_db["Things"][highest_id]["T_PLAYERDROP"]): # #
+ x = world_db["Things"][highest_id]["T_TYPE"]
+ score = world_db["ThingTypes"][x]["TT_CONSUMABLE"] / 32 # #
+ add_gods_favor(score) # #
+ world_db["Things"][highest_id]["T_PLAYERDROP"] = 0 # #
+ 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):
@@ -671,6 +734,7 @@ def actor_drop(t):
world_db["Things"][id]["carried"] = False
if t == world_db["Things"][0]:
strong_write(io_db["file_out"], "LOG You drop an object.\n")
+ world_db["Things"][id]["T_PLAYERDROP"] = 1 # #
elif t == world_db["Things"][0]:
err = "You try to drop an object, but you own none."
strong_write(io_db["file_out"], "LOG " + err + "\n")
@@ -705,6 +769,7 @@ def thingproliferation(t):
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"]
@@ -728,6 +793,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
+ world_db["GOD_MOOD"] += 1 # #
def try_healing(t):
@@ -735,6 +801,7 @@ def try_healing(t):
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"] \
@@ -743,12 +810,10 @@ def try_healing(t):
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")
- else:
- name = world_db["ThingTypes"][t["T_TYPE"]]["TT_NAME"]
- strong_write(io_db["file_out"], "LOG " + name + "heals.\n")
def hunger(t):
@@ -762,10 +827,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")
- 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)
@@ -789,10 +850,12 @@ def get_dir_to_target(t, filter):
"""
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().")
@@ -831,7 +894,8 @@ def get_dir_to_target(t, filter):
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)
# if ord_dot == memmap[i]]:
@@ -839,13 +903,12 @@ def get_dir_to_target(t, filter):
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().")
+ "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().")
- ord_dot = ord(".")
ord_v = ord("v")
ord_blank = ord(" ")
set_cells_passable_on_memmap_to_65534_on_scoremap()
@@ -1000,6 +1063,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.
"""
+ # # 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"):
@@ -1009,11 +1073,16 @@ def ai(t):
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]
- 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")
@@ -1059,6 +1128,7 @@ def new_Thing(type, pos=(0, 0)):
"T_PROGRESS": 0,
"T_SATIATION": 0,
"T_COMMAND": 0,
+ "T_PLAYERDROP": 0, # #
"T_TYPE": type,
"T_POSY": pos[0],
"T_POSX": pos[1],
@@ -1111,8 +1181,9 @@ 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:
+ save_world()
+ atomic_write(io_db["path_record"], io_db["record_chunk"], do_append=True)
raise SystemExit("received QUIT command")
@@ -1460,6 +1531,7 @@ def command_ttid(id_string):
"TT_LIFEPOINTS": 0,
"TT_PROLIFERATE": 0,
"TT_START_NUMBER": 0,
+ "TT_STORAGE": 0, # #
"TT_SYMBOL": "?",
"TT_CORPSE_ID": id
}
@@ -1554,8 +1626,8 @@ commands_db = {
"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)), ##
+ "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),
@@ -1573,6 +1645,7 @@ commands_db = {
"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)),
@@ -1586,6 +1659,7 @@ commands_db = {
"T_MEMTHING": (3, False, command_tmemthing),
"T_POSY": (1, False, setter_tpos("Y")),
"T_POSX": (1, False, setter_tpos("X")),
+ "T_PLAYERDROP": (1, False, setter("Thing", "T_PLAYERDROP", 0, 1)), # #
"wait": (0, False, play_commander("wait")),
"move": (1, False, play_commander("move")),
"pick_up": (0, False, play_commander("pick_up")),
@@ -1602,8 +1676,8 @@ world_db = {
"SEED_MAP": 0,
"PLAYER_TYPE": 0,
"WORLD_ACTIVE": 0,
- "GOD_MOOD": 0, ##
- "GOD_FAVOR": 0, ##
+ "GOD_MOOD": 0, # #
+ "GOD_FAVOR": 0, # #
"ThingActions": {},
"ThingTypes": {},
"Things": {}