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):
22 def __init__(self, *args, **kwargs):
23 super().__init__(*args, **kwargs)
31 class ThingItem(Thing):
36 class ThingAnimate(Thing):
39 def __init__(self, *args, **kwargs):
40 super().__init__(*args, **kwargs)
42 self._last_task_result = None
45 def move_towards_target(self, target):
46 dijkstra_map = type(self.world.map_)(self.world.map_.size)
48 dijkstra_map.terrain = [n_max for i in range(dijkstra_map.size_i)]
49 dijkstra_map[target] = 0
51 visible_map = self.get_visible_map()
54 for pos in dijkstra_map:
55 if visible_map[pos] != '.':
57 neighbors = dijkstra_map.get_neighbors(tuple(pos))
58 for direction in neighbors:
59 yx = neighbors[direction]
60 if yx is not None and dijkstra_map[yx] < dijkstra_map[pos] - 1:
61 dijkstra_map[pos] = dijkstra_map[yx] + 1
63 neighbors = dijkstra_map.get_neighbors(tuple(self.position))
65 target_direction = None
66 for direction in sorted(neighbors.keys()):
67 yx = neighbors[direction]
69 n_new = dijkstra_map[yx]
72 target_direction = direction
74 self.set_task('MOVE', (target_direction,))
76 def decide_task(self):
77 visible_things = self.get_visible_things()
79 for t in visible_things:
80 if t.type_ == 'human':
83 if target is not None:
85 self.move_towards_target(target)
91 def set_task(self, task_name, args=()):
92 task_class = self.world.game.tasks[task_name]
93 self.task = task_class(self, args)
94 self.task.check() # will throw GameError if necessary
96 def proceed(self, is_AI=True):
97 """Further the thing in its tasks.
99 Decrements .task.todo; if it thus falls to <= 0, enacts method
100 whose name is 'task_' + self.task.name and sets .task =
101 None. If is_AI, calls .decide_task to decide a self.task.
103 Before doing anything, ensures an empty map visibility stencil
104 and checks that task is still possible, and aborts it
105 otherwise (for AI things, decides a new task).
111 except GameError as e:
113 self._last_task_result = e
118 self.set_task('WAIT')
121 if self.task.todo <= 0:
122 self._last_task_result = self.task.do()
124 if is_AI and self.task is None:
128 self.set_task('WAIT')
130 def get_stencil(self):
131 if self._stencil is not None:
133 self._stencil = self.world.map_.get_fov_map(self.position)
136 def get_visible_map(self):
137 stencil = self.get_stencil()
138 m = self.world.map_.new_from_shape(' ')
140 if stencil[pos] == '.':
141 m[pos] = self.world.map_[pos]
144 def get_visible_things(self):
145 stencil = self.get_stencil()
147 for thing in self.world.things:
148 if (not thing.in_inventory) and stencil[thing.position] == '.':
149 visible_things += [thing]
150 return visible_things
152 def get_pickable_items(self):
154 for t in [t for t in self.get_visible_things() if
155 isinstance(t, ThingItem) and
156 (t.position == self.position or
158 self.world.map_.get_neighbors(self.position).values())]:
159 pickable_ids += [t.id_]
164 class ThingHuman(ThingAnimate):
169 class ThingMonster(ThingAnimate):