1 from plomrogue.errors import GameError
7 def __init__(self, world, id_, type_='?', position=[0,0]):
11 self.position = position
15 class Thing(ThingBase):
17 def __init__(self, *args, **kwargs):
18 super().__init__(*args, **kwargs)
20 self._last_task_result = None
23 def move_towards_target(self, target):
24 dijkstra_map = type(self.world.map_)(self.world.map_.size)
26 dijkstra_map.terrain = [n_max for i in range(dijkstra_map.size_i)]
27 dijkstra_map[target] = 0
29 visible_map = self.get_visible_map()
32 for pos in dijkstra_map:
33 if visible_map[pos] != '.':
35 neighbors = dijkstra_map.get_neighbors(tuple(pos))
36 for direction in neighbors:
37 yx = neighbors[direction]
38 if yx is not None and dijkstra_map[yx] < dijkstra_map[pos] - 1:
39 dijkstra_map[pos] = dijkstra_map[yx] + 1
41 neighbors = dijkstra_map.get_neighbors(tuple(self.position))
43 target_direction = None
44 for direction in neighbors:
45 yx = neighbors[direction]
47 n_new = dijkstra_map[yx]
50 target_direction = direction
52 self.set_task('MOVE', (target_direction,))
54 def decide_task(self):
55 visible_things = self.get_visible_things()
57 for t in visible_things:
58 if t.type_ == 'human':
61 if target is not None:
63 self.move_towards_target(target)
69 def set_task(self, task_name, args=()):
70 task_class = self.world.game.tasks[task_name]
71 self.task = task_class(self, args)
72 self.task.check() # will throw GameError if necessary
74 def proceed(self, is_AI=True):
75 """Further the thing in its tasks.
77 Decrements .task.todo; if it thus falls to <= 0, enacts method
78 whose name is 'task_' + self.task.name and sets .task =
79 None. If is_AI, calls .decide_task to decide a self.task.
81 Before doing anything, ensures an empty map visibility stencil
82 and checks that task is still possible, and aborts it
83 otherwise (for AI things, decides a new task).
89 except GameError as e:
91 self._last_task_result = e
99 if self.task.todo <= 0:
100 self._last_task_result = self.task.do()
102 if is_AI and self.task is None:
106 self.set_task('WAIT')
108 def get_stencil(self):
109 if self._stencil is not None:
111 self._stencil = self.world.map_.get_fov_map(self.position)
114 def get_visible_map(self):
115 stencil = self.get_stencil()
116 m = self.world.map_.new_from_shape(' ')
118 if stencil[pos] == '.':
119 m[pos] = self.world.map_[pos]
122 def get_visible_things(self):
123 stencil = self.get_stencil()
125 for thing in self.world.things:
126 if stencil[thing.position] == '.':
127 visible_things += [thing]
128 return visible_things