1 from plomrogue.errors import GameError
8 def __init__(self, world, id_, position=[0,0]):
11 self.position = position
15 class Thing(ThingBase):
23 class ThingItem(Thing):
28 class ThingAnimate(Thing):
31 def __init__(self, *args, **kwargs):
32 super().__init__(*args, **kwargs)
34 self._last_task_result = None
37 def move_towards_target(self, target):
38 dijkstra_map = type(self.world.map_)(self.world.map_.size)
40 dijkstra_map.terrain = [n_max for i in range(dijkstra_map.size_i)]
41 dijkstra_map[target] = 0
43 visible_map = self.get_visible_map()
46 for pos in dijkstra_map:
47 if visible_map[pos] != '.':
49 neighbors = dijkstra_map.get_neighbors(tuple(pos))
50 for direction in neighbors:
51 yx = neighbors[direction]
52 if yx is not None and dijkstra_map[yx] < dijkstra_map[pos] - 1:
53 dijkstra_map[pos] = dijkstra_map[yx] + 1
55 neighbors = dijkstra_map.get_neighbors(tuple(self.position))
57 target_direction = None
58 for direction in neighbors:
59 yx = neighbors[direction]
61 n_new = dijkstra_map[yx]
64 target_direction = direction
66 self.set_task('MOVE', (target_direction,))
68 def decide_task(self):
69 visible_things = self.get_visible_things()
71 for t in visible_things:
72 if t.type_ == 'human':
75 if target is not None:
77 self.move_towards_target(target)
83 def set_task(self, task_name, args=()):
84 task_class = self.world.game.tasks[task_name]
85 self.task = task_class(self, args)
86 self.task.check() # will throw GameError if necessary
88 def proceed(self, is_AI=True):
89 """Further the thing in its tasks.
91 Decrements .task.todo; if it thus falls to <= 0, enacts method
92 whose name is 'task_' + self.task.name and sets .task =
93 None. If is_AI, calls .decide_task to decide a self.task.
95 Before doing anything, ensures an empty map visibility stencil
96 and checks that task is still possible, and aborts it
97 otherwise (for AI things, decides a new task).
103 except GameError as e:
105 self._last_task_result = e
110 self.set_task('WAIT')
113 if self.task.todo <= 0:
114 self._last_task_result = self.task.do()
116 if is_AI and self.task is None:
120 self.set_task('WAIT')
122 def get_stencil(self):
123 if self._stencil is not None:
125 self._stencil = self.world.map_.get_fov_map(self.position)
128 def get_visible_map(self):
129 stencil = self.get_stencil()
130 m = self.world.map_.new_from_shape(' ')
132 if stencil[pos] == '.':
133 m[pos] = self.world.map_[pos]
136 def get_visible_things(self):
137 stencil = self.get_stencil()
139 for thing in self.world.things:
140 if stencil[thing.position] == '.':
141 visible_things += [thing]
142 return visible_things
146 class ThingHuman(ThingAnimate):
151 class ThingMonster(ThingAnimate):