1 from plomrogue.errors import GameError
8 def __init__(self, world, id_=None, position=[0,0]):
10 self.position = position
12 self.id_ = self.world.new_thing_id()
18 class Thing(ThingBase):
26 class ThingItem(Thing):
31 class ThingAnimate(Thing):
34 def __init__(self, *args, **kwargs):
35 super().__init__(*args, **kwargs)
37 self._last_task_result = None
40 def move_towards_target(self, target):
41 dijkstra_map = type(self.world.map_)(self.world.map_.size)
43 dijkstra_map.terrain = [n_max for i in range(dijkstra_map.size_i)]
44 dijkstra_map[target] = 0
46 visible_map = self.get_visible_map()
49 for pos in dijkstra_map:
50 if visible_map[pos] != '.':
52 neighbors = dijkstra_map.get_neighbors(tuple(pos))
53 for direction in neighbors:
54 yx = neighbors[direction]
55 if yx is not None and dijkstra_map[yx] < dijkstra_map[pos] - 1:
56 dijkstra_map[pos] = dijkstra_map[yx] + 1
58 neighbors = dijkstra_map.get_neighbors(tuple(self.position))
60 target_direction = None
61 for direction in neighbors:
62 yx = neighbors[direction]
64 n_new = dijkstra_map[yx]
67 target_direction = direction
69 self.set_task('MOVE', (target_direction,))
71 def decide_task(self):
72 visible_things = self.get_visible_things()
74 for t in visible_things:
75 if t.type_ == 'human':
78 if target is not None:
80 self.move_towards_target(target)
86 def set_task(self, task_name, args=()):
87 task_class = self.world.game.tasks[task_name]
88 self.task = task_class(self, args)
89 self.task.check() # will throw GameError if necessary
91 def proceed(self, is_AI=True):
92 """Further the thing in its tasks.
94 Decrements .task.todo; if it thus falls to <= 0, enacts method
95 whose name is 'task_' + self.task.name and sets .task =
96 None. If is_AI, calls .decide_task to decide a self.task.
98 Before doing anything, ensures an empty map visibility stencil
99 and checks that task is still possible, and aborts it
100 otherwise (for AI things, decides a new task).
106 except GameError as e:
108 self._last_task_result = e
113 self.set_task('WAIT')
116 if self.task.todo <= 0:
117 self._last_task_result = self.task.do()
119 if is_AI and self.task is None:
123 self.set_task('WAIT')
125 def get_stencil(self):
126 if self._stencil is not None:
128 self._stencil = self.world.map_.get_fov_map(self.position)
131 def get_visible_map(self):
132 stencil = self.get_stencil()
133 m = self.world.map_.new_from_shape(' ')
135 if stencil[pos] == '.':
136 m[pos] = self.world.map_[pos]
139 def get_visible_things(self):
140 stencil = self.get_stencil()
142 for thing in self.world.things:
143 if stencil[thing.position] == '.':
144 visible_things += [thing]
145 return visible_things
149 class ThingHuman(ThingAnimate):
154 class ThingMonster(ThingAnimate):