Package horizons :: Package world :: Package units :: Package collectors :: Module animalcollector
[hide private]
[frames] | no frames]

Source Code for Module horizons.world.units.collectors.animalcollector

  1  # ################################################### 
  2  # Copyright (C) 2008-2017 The Unknown Horizons Team 
  3  # team@unknown-horizons.org 
  4  # This file is part of Unknown Horizons. 
  5  # 
  6  # Unknown Horizons is free software; you can redistribute it and/or modify 
  7  # it under the terms of the GNU General Public License as published by 
  8  # the Free Software Foundation; either version 2 of the License, or 
  9  # (at your option) any later version. 
 10  # 
 11  # This program is distributed in the hope that it will be useful, 
 12  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 13  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 14  # GNU General Public License for more details. 
 15  # 
 16  # You should have received a copy of the GNU General Public License 
 17  # along with this program; if not, write to the 
 18  # Free Software Foundation, Inc., 
 19  # 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
 20  # ################################################### 
 21   
 22  from horizons.constants import GAME_SPEED 
 23  from horizons.scheduler import Scheduler 
 24  from horizons.world.units.collectors.buildingcollector import BuildingCollector 
 25  from horizons.world.units.unitexeptions import MoveNotPossible 
 26   
 27   
28 -class AnimalCollector(BuildingCollector):
29 """ Collector that gets resources from animals. 30 Behavior (timeline): 31 - search for an animal which has resources to pick up 32 - tell animal to stop when its current job is done 33 - wait for callback from this animal, notifying that we can pick it up 34 - walk to animal 35 - walk home (with animal walking along) 36 - stay at home building for a while 37 - release animal 38 """ 39 kill_animal = False # whether we kill the animals 40
41 - def __init__(self, *args, **kwargs):
42 super().__init__(*args, **kwargs)
43
44 - def load(self, db, worldid):
45 super().load(db, worldid)
46
47 - def apply_state(self, state, remaining_ticks=None):
48 super().apply_state(state, remaining_ticks) 49 if state == self.states.waiting_for_animal_to_stop: 50 # register at target 51 self.setup_new_job() 52 self.stop_animal() 53 elif state == self.states.moving_home: 54 if not self.__class__.kill_animal: 55 self.setup_new_job() # register at target if it's still alive
56
57 - def cancel(self, continue_action=None):
58 if self.job is not None: 59 if self.state == self.states.waiting_for_animal_to_stop: 60 if hasattr(self.job.object, 'remove_stop_after_job'): 61 # when loading a game fails and the world is destructed again, the 62 # worldid may not yet have been resolved to an actual in-game object 63 self.job.object.remove_stop_after_job() 64 super().cancel(continue_action=continue_action)
65
66 - def begin_current_job(self):
67 """Tell the animal to stop.""" 68 self.setup_new_job() 69 self.stop_animal() 70 self.state = self.states.waiting_for_animal_to_stop
71
72 - def pickup_animal(self):
73 """Moves collector to animal. Called by animal when it actually stopped""" 74 self.show() 75 try: 76 self.move(self.job.object.loading_area, self.begin_working) 77 except MoveNotPossible: 78 # the animal is now unreachable. 79 self.job.object.search_job() 80 self.state = self.states.idle 81 self.cancel(continue_action=self.search_job) 82 return 83 self.state = self.states.moving_to_target
84
85 - def finish_working(self):
86 """Called when collector arrives at the animal. Move home with the animal""" 87 if self.__class__.kill_animal: 88 # get res now, and kill animal right after 89 super().finish_working() 90 else: 91 self.move_home(callback=self.reached_home) 92 self.get_animal() # get or kill animal
93
94 - def reached_home(self):
95 """Transfer res to home building and such. Called when collector arrives at it's home""" 96 if not self.__class__.kill_animal: 97 # sheep and herder are inside the building now, pretending to work. 98 super().finish_working(collector_already_home=True) 99 self.release_animal() 100 super().reached_home()
101
102 - def get_buildings_in_range(self, reslist=None):
103 return self.get_animals_in_range(reslist)
104
105 - def get_animals_in_range(self, reslist=None):
106 return self.home_building.animals
107
108 - def check_possible_job_target_for(self, target, res):
109 # An animal can only be collected by one collector. 110 # Since a collector only retrieves one type of res, and 111 # an animal might produce more than one, two collectors 112 # could take this animal as a target. 113 # This could also happen, if the animal has an inventory 114 # with a limit > 1. In this case, one collector might register 115 # for the first ton, then the animal produces another one, which 116 # might then be spotted by another collector. 117 # TODO: 118 # The animal class must be producer class that is only 119 # collectable by 1 collector at a time, which also should be checked. 120 # This could be a new abstract class. 121 if target.has_collectors(): 122 return None 123 else: 124 return super().check_possible_job_target_for(target, res)
125
126 - def stop_animal(self):
127 """Tell animal to stop at the next occasion""" 128 self.job.object.stop_after_job(self)
129
130 - def get_animal(self):
131 """Sends animal to collectors home building""" 132 self.log.debug("%s getting animal %s", self, self.job.object) 133 if self.__class__.kill_animal: 134 self.job.object.die() 135 self.job.object = None # there is no target anymore now 136 else: 137 self.job.object.move(self.home_building.position, destination_in_building=True, 138 action='move_full')
139
140 - def release_animal(self):
141 """Let animal free after shearing and schedules search for a new job for animal.""" 142 if not self.__class__.kill_animal: 143 self.log.debug("%s releasing animal %s", self, self.job.object) 144 Scheduler().add_new_object(self.job.object.search_job, self.job.object, 145 GAME_SPEED.TICKS_PER_SECOND)
146 147
148 -class HunterCollector(AnimalCollector):
149 kill_animal = True 150
151 - def get_animals_in_range(self, res=None):
152 dist = self.home_building.position.distance 153 radius = self.home_building.radius 154 return [animal for animal in self.home_building.island.wild_animals if 155 dist(animal.position) <= radius]
156