home · contact · privacy
6b03d0a6ae83f14110732474eeb304ba2651f851
[plomrogue] / server / world.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 from server.utils import rand
9 from server.utils import id_setter
10
11
12 def decrement_lifepoints(t):
13     """Decrement t's lifepoints by 1, and if to zero, corpse it.
14
15     If t is the player avatar, only blank its fovmap, so that the client may
16     still display memory data. On non-player things, erase fovmap and memory.
17     Dying actors drop all their things.
18     """
19     t["T_LIFEPOINTS"] -= 1
20     if 0 == t["T_LIFEPOINTS"]:
21         for id in t["T_CARRIES"]:
22             t["T_CARRIES"].remove(id)
23             world_db["Things"][id]["T_POSY"] = t["T_POSY"]
24             world_db["Things"][id]["T_POSX"] = t["T_POSX"]
25             world_db["Things"][id]["carried"] = False
26         t["T_TYPE"] = world_db["ThingTypes"][t["T_TYPE"]]["TT_CORPSE_ID"]
27         if world_db["Things"][0] == t:
28             t["fovmap"] = bytearray(b' ' * (world_db["MAP_LENGTH"] ** 2))
29             log("You die.")
30             log("See README on how to start over.")
31         else:
32             t["fovmap"] = False
33             t["T_MEMMAP"] = False
34             t["T_MEMDEPTHMAP"] = False
35             t["T_MEMTHING"] = []
36
37
38 def try_healing(t):
39     """If t's HP < max, increment them if well-nourished, maybe waiting."""
40     if t["T_LIFEPOINTS"] < \
41        world_db["ThingTypes"][t["T_TYPE"]]["TT_LIFEPOINTS"]:
42         wait_id = [id for id in world_db["ThingActions"]
43                       if world_db["ThingActions"][id]["TA_NAME"] == "wait"][0]
44         wait_divider = 8 if t["T_COMMAND"] == wait_id else 1
45         testval = int(abs(t["T_SATIATION"]) / wait_divider)
46         if (testval <= 1 or 1 == (rand.next() % testval)):
47             t["T_LIFEPOINTS"] += 1
48             if t == world_db["Things"][0]:
49                 log("You HEAL.")
50
51
52 def hunger_per_turn(type_id):
53     """The amount of satiation score lost per turn for things of given type."""
54     import math
55     return int(math.sqrt(world_db["ThingTypes"][type_id]["TT_LIFEPOINTS"]))
56
57
58 def hunger(t):
59     """Decrement t's satiation,dependent on it trigger lifepoint dec chance."""
60     if t["T_SATIATION"] > -32768:
61         t["T_SATIATION"] -= hunger_per_turn(t["T_TYPE"])
62     if 0 != t["T_SATIATION"] and 0 == int(rand.next() / abs(t["T_SATIATION"])):
63         if t == world_db["Things"][0]:
64             if t["T_SATIATION"] < 0:
65                 log("You SUFFER from hunger.")
66             else:
67                 log("You SUFFER from over-eating.")
68         decrement_lifepoints(t)
69
70
71 def set_world_inactive():
72     """Set world_db["WORLD_ACTIVE"] to 0 and remove worldstate file."""
73     from server.io import safely_remove_worldstate_file
74     safely_remove_worldstate_file()
75     world_db["WORLD_ACTIVE"] = 0
76
77
78 def turn_over():
79     """Run game world and its inhabitants until new player input expected."""
80     from server.config.actions import action_db, ai_func
81     from server.config.misc import thingproliferation_func
82     from server.update_map_memory import update_map_memory
83     id = 0
84     whilebreaker = False
85     while world_db["Things"][0]["T_LIFEPOINTS"]:
86         proliferable_map = world_db["MAP"][:]
87         for id in [id for id in world_db["Things"]
88                    if not world_db["Things"][id]["carried"]]:
89             y = world_db["Things"][id]["T_POSY"]
90             x = world_db["Things"][id]["T_POSX"]
91             proliferable_map[y * world_db["MAP_LENGTH"] + x] = ord('X')
92         for id in [id for id in world_db["Things"]]:  # Only what's from start!
93             if not id in world_db["Things"] or \
94                world_db["Things"][id]["carried"]:   # May have been consumed or
95                 continue                            # picked up during turn …
96             Thing = world_db["Things"][id]
97             if Thing["T_LIFEPOINTS"]:
98                 if not Thing["T_COMMAND"]:
99                     update_map_memory(Thing)
100                     if 0 == id:
101                         whilebreaker = True
102                         break
103                     ai_func(Thing)
104                 try_healing(Thing)
105                 hunger(Thing)
106                 if Thing["T_LIFEPOINTS"]:
107                     Thing["T_PROGRESS"] += 1
108                     taid = [a for a in world_db["ThingActions"]
109                               if a == Thing["T_COMMAND"]][0]
110                     ThingAction = world_db["ThingActions"][taid]
111                     if Thing["T_PROGRESS"] == ThingAction["TA_EFFORT"]:
112                         action = action_db["actor_" + ThingAction["TA_NAME"]]
113                         action(Thing)
114                         Thing["T_COMMAND"] = 0
115                         Thing["T_PROGRESS"] = 0
116             thingproliferation_func(Thing, proliferable_map)
117         if whilebreaker:
118             break
119         world_db["TURN"] += 1