home · contact · privacy
Server: Optimize thing position calculation.
[plomrogue] / server / actions.py
1 # This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
2 # or any later version. For details on its copyright, license, and warranties,
3 # see the file NOTICE in the root directory of the PlomRogue source package.
4
5
6 from server.config.world_data import world_db
7 from server.io import log
8
9
10 def actor_wait(t):
11     """Make t do nothing (but loudly, if player avatar)."""
12     if t == world_db["Things"][0]:
13         log("You wait")
14
15
16 def actor_move(t):
17     """If passable, move/collide(=attack) thing into T_ARGUMENT's direction.
18
19     On attack, return 0 on non-kill and TT_LIFEPOINTS of killed type on kill,
20     plus type id of attacked Thing. On move, return mv_yx_in_dir_legal result.
21     """
22     from server.build_fov_map import build_fov_map
23     from server.config.misc import decrement_lifepoints
24     from server.utils import mv_yx_in_dir_legal
25     from server.config.world_data import directions_db, symbols_passable
26     passable = False
27     move_result = mv_yx_in_dir_legal(chr(t["T_ARGUMENT"]),
28                                      t["T_POSY"], t["T_POSX"])
29     if 1 == move_result[0]:
30         pos = (move_result[1] * world_db["MAP_LENGTH"]) + move_result[2]
31         hitted = [id for id in world_db["Things"]
32                   if world_db["Things"][id] != t
33                   if world_db["Things"][id]["T_LIFEPOINTS"]
34                   if world_db["Things"][id]["T_POSY"] == move_result[1]
35                   if world_db["Things"][id]["T_POSX"] == move_result[2]]
36         if len(hitted):
37             hit_id = hitted[0]
38             hitted_tid = world_db["Things"][hit_id]["T_TYPE"]
39             if t == world_db["Things"][0]:
40                 hitted_name = world_db["ThingTypes"][hitted_tid]["TT_NAME"]
41                 log("You WOUND " + hitted_name + ".")
42             elif 0 == hit_id:
43                 hitter_name = world_db["ThingTypes"][t["T_TYPE"]]["TT_NAME"]
44                 log(hitter_name +" WOUNDS you.")
45             decr_test = decrement_lifepoints(world_db["Things"][hit_id])
46             if decr_test > 0 and t == world_db["Things"][0]:
47                 log(hitted_name + " dies.")
48             return decr_test, hitted_tid
49         from server.config.actions import actor_move_attempts_hook
50         if actor_move_attempts_hook(t, move_result, pos):
51             return
52         passable = chr(world_db["MAP"][pos]) in symbols_passable
53     dir = [dir for dir in directions_db
54            if directions_db[dir] == chr(t["T_ARGUMENT"])][0]
55     if passable:
56         t["T_POSY"] = move_result[1]
57         t["T_POSX"] = move_result[2]
58         t["pos"] = move_result[1] * world_db["MAP_LENGTH"] + move_result[2]
59         for id in t["T_CARRIES"]:
60             world_db["Things"][id]["T_POSY"] = move_result[1]
61             world_db["Things"][id]["T_POSX"] = move_result[2]
62             world_db["Things"][id]["pos"] = t["pos"]
63         build_fov_map(t)
64         if t == world_db["Things"][0]:
65             log("You MOVE " + dir + ".")
66         return move_result
67
68
69 def actor_pickup(t):
70     """Make t pick up (topmost?) Thing from ground into inventory. Return it.
71
72     Define topmostness by how low the thing's type ID is.
73     """
74     ids = [id for id in world_db["Things"] if world_db["Things"][id] != t
75            if not world_db["Things"][id]["carried"]
76            if world_db["Things"][id]["pos"] == t["pos"]]
77     if len(ids):
78         lowest_tid = -1
79         for iid in ids:
80             tid = world_db["Things"][iid]["T_TYPE"]
81             from server.config.actions import actor_pickup_test_hook
82             if (lowest_tid == -1 or tid < lowest_tid) and \
83                     actor_pickup_test_hook(t, tid):
84                 id = iid
85                 lowest_tid = tid
86         world_db["Things"][id]["carried"] = True
87         t["T_CARRIES"].append(id)
88         if t == world_db["Things"][0]:
89                 log("You PICK UP an object.")
90         return world_db["Things"][id]
91
92 def actor_drop(t):
93     """Drop to ground from t's inventory, return T_ARGUMENT-indexed Thing."""
94     # TODO: Handle case where T_ARGUMENT matches nothing.
95     if len(t["T_CARRIES"]):
96         id = t["T_CARRIES"][t["T_ARGUMENT"]]
97         t["T_CARRIES"].remove(id)
98         world_db["Things"][id]["carried"] = False
99         if t == world_db["Things"][0]:
100             log("You DROP an object.")
101             return world_db["Things"][id]
102
103 def actor_use(t):
104     """Make t use (for now: consume) T_ARGUMENT-indexed Thing in inventory."""
105     # TODO: Handle case where T_ARGUMENT matches nothing.
106     if len(t["T_CARRIES"]):
107         id = t["T_CARRIES"][t["T_ARGUMENT"]]
108         type = world_db["Things"][id]["T_TYPE"]
109         if world_db["ThingTypes"][type]["TT_TOOL"] == "food":
110             t["T_CARRIES"].remove(id)
111             del world_db["Things"][id]
112             t["T_SATIATION"] += world_db["ThingTypes"][type]["TT_TOOLPOWER"]
113             if t == world_db["Things"][0]:
114                 log("You CONSUME this thing.")
115         else:
116             from server.config.actions import actor_use_attempts_hook
117             actor_use_attempts_hook(t, type)