home · contact · privacy
Server, plugin: Refactor make_world modularity.
[plomrogue] / server / make_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, symbols_passable
7 from server.config.make_world_helpers import make_map_func, \
8     world_makable_func, pos_test_func
9 from server.config.io import io_db
10 from server.utils import rand, libpr, id_setter
11 from server.new_thing import new_Thing
12 from server.io import strong_write
13 from server.update_map_memory import update_map_memory
14
15
16 def make_world(seed):
17     """(Re-)build game world, i.e. map, things, to a new turn 1 from seed.
18
19     Seed rand with seed. Do more only with a "wait" ThingAction and
20     world["PLAYER_TYPE"] matching ThingType of TT_START_NUMBER > 0. Then,
21     world_db["Things"] emptied, call make_map() and set
22     world_db["WORLD_ACTIVE"], world_db["TURN"] to 1. Build new Things
23     according to ThingTypes' TT_START_NUMBERS, with Thing of ID 0 to ThingType
24     of ID = world["PLAYER_TYPE"]. Place Things randomly, and actors not on each
25     other. Init player's memory map. Write "NEW_WORLD" line to out file.
26     """
27     def free_pos(type):
28         i = 0
29         while 1:
30             err = "Space to put thing on too hard to find. Map too small?"
31             while 1:
32                 y = rand.next() % world_db["MAP_LENGTH"]
33                 x = rand.next() % world_db["MAP_LENGTH"]
34                 if chr(world_db["MAP"][y * world_db["MAP_LENGTH"] + x]) in \
35                     symbols_passable and pos_test_func(type, y, x):
36                     break
37                 i += 1
38                 if i == 65535:
39                     raise SystemExit(err)
40             # Replica of C code, wrongly ignores animatedness of new Thing.
41             pos_clear = (0 == len([id for id in world_db["Things"]
42                                    if world_db["Things"][id]["T_LIFEPOINTS"]
43                                    if world_db["Things"][id]["T_POSY"] == y
44                                    if world_db["Things"][id]["T_POSX"] == x]))
45             if pos_clear:
46                 break
47         return (y, x)
48
49     playertype = world_makable_func()
50     if playertype < 0:
51         return
52     rand.seed = seed
53     libpr.set_maplength(world_db["MAP_LENGTH"])
54     world_db["Things"] = {}
55     make_map_func()
56     world_db["WORLD_ACTIVE"] = 1
57     world_db["TURN"] = 1
58     for i in range(world_db["ThingTypes"][playertype]["TT_START_NUMBER"]):
59         id = id_setter(-1, "Things")
60         world_db["Things"][id] = new_Thing(playertype, free_pos(playertype))
61     if not world_db["Things"][0]["fovmap"]:
62         empty_fovmap = bytearray(b" " * world_db["MAP_LENGTH"] ** 2)
63         world_db["Things"][0]["fovmap"] = empty_fovmap
64     update_map_memory(world_db["Things"][0])
65     for type in world_db["ThingTypes"]:
66         for i in range(world_db["ThingTypes"][type]["TT_START_NUMBER"]):
67             if type != playertype:
68                 id = id_setter(-1, "Things")
69                 world_db["Things"][id] = new_Thing(type, free_pos(type))
70     strong_write(io_db["file_out"], "NEW_WORLD\n")