Package horizons :: Package world :: Module buildingowner
[hide private]
[frames] | no frames]

Source Code for Module horizons.world.buildingowner

  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.util.shapes import Point, RadiusRect 
 23  from horizons.world.providerhandler import ProviderHandler 
 24   
 25   
 26  """ 
 27  Simple building management functionality. 
 28  Inherited mainly by Island, but also by World for buildings at sea such as fish. 
 29  Island adds more functionality to these functions (e.g. settlement handling), 
 30  this implementation can be viewed as the the common denominator of building handling 
 31  required by World and Island. 
 32  The instances need to provide a get_tile function. 
 33  """ 
 34   
 35   
36 -class BuildingOwner:
37 - def __init__(self, *args, **kwargs):
38 super().__init__(*args, **kwargs) # TODO: check if call is needed 39 self.provider_buildings = ProviderHandler() 40 self.buildings = []
41
42 - def add_building(self, building, player, load=False):
43 """Adds a building to the island at the position x, y with player as the owner. 44 @param building: Building class instance of the building that is to be added. 45 @param player: int id of the player that owns the settlement""" 46 # Set all tiles in the buildings position(rect) 47 for point in building.position: 48 tile = self.get_tile(point) 49 tile.blocked = True # Set tile blocked 50 tile.object = building # Set tile's object to the building 51 self.buildings.append(building) 52 building.init() 53 return building
54
55 - def remove_building(self, building):
56 assert building.island == self 57 58 # Reset the tiles this building was covering 59 for point in building.position: 60 tile = self.get_tile(point) 61 tile.blocked = False 62 tile.object = None 63 64 # Remove this building from the buildings list 65 self.buildings.remove(building) 66 assert building not in self.buildings
67
68 - def get_settlements(self, rect, player=None):
69 """Returns the list of settlements for the coordinates describing a rect. 70 @param rect: Area to search for settlements 71 @return: list of Settlement instances at that position.""" 72 settlements = set() 73 for point in rect: 74 try: 75 if player is None or self.get_tile(point).settlement.owner == player: 76 settlements.add(self.get_tile(point).settlement) 77 except AttributeError: 78 # some tiles don't have settlements, we don't explicitly check for them cause 79 # its faster this way. 80 pass 81 settlements.discard(None) # None values might have been added, we don't want them 82 return list(settlements)
83
84 - def get_building(self, point):
85 """Returns the building at the point 86 @param point: position of the tile to look on 87 @return: Building class instance or None if none is found. 88 """ 89 try: 90 return self.get_tile(point).object 91 except AttributeError: 92 return None
93
94 - def get_settlement(self, point):
95 """Look for a settlement at a specific coordinate 96 @return: Settlement at point, or None""" 97 try: 98 return self.get_tile(point).settlement 99 # some tiles might be none, so we have to catch that error here 100 except AttributeError: 101 return None
102
103 - def get_tile(self, point):
104 """Returns the tile at Point or None""" 105 assert isinstance(point, Point) 106 raise NotImplementedError
107
108 - def get_providers_in_range(self, radiusrect, res=None, reslist=None, player=None):
109 """Returns all instances of provider within the specified shape. 110 NOTE: Specifing the res parameter is usually a huge speed gain. 111 @param radiusrect: instance of RadiusShape 112 @param res: optional; only return providers that provide res. conflicts with reslist 113 @param reslist: optionally; list of res to search providers for. conflicts with res 114 @param player: Player instance, only buildings belonging to this player 115 @return: list of providers""" 116 assert not (bool(res) and bool(reslist)) 117 assert isinstance(radiusrect, RadiusRect) 118 # find out relevant providers 119 if res is not None: 120 provider_list = self.provider_buildings.provider_by_resources[res] 121 elif reslist: 122 provider_list = set() 123 for _res in reslist: 124 provider_list = provider_list.union(self.provider_buildings.provider_by_resources[_res]) 125 else: 126 # worst case: search all provider buildings 127 provider_list = self.provider_buildings 128 # filter out those that aren't in range 129 r2 = radiusrect.center 130 radius_squared = radiusrect.radius ** 2 131 for provider in provider_list: 132 if (player is None or player == provider.owner): 133 # inline of : 134 #provider.position.distance_to_rect(radiusrect.center) <= radiusrect.radius: 135 r1 = provider.position 136 if ((max(r1.left - r2.right, 0, r2.left - r1.right) ** 2) + (max(r1.top - r2.bottom, 0, r2.top - r1.bottom) ** 2)) <= radius_squared: 137 yield provider
138
139 - def save(self, db):
140 for building in self.buildings: 141 building.save(db)
142
143 - def end(self):
144 if self.buildings is not None: 145 # remove all buildings 146 # this iteration style is the most robust; sometimes the ai reacts to removals 147 # by building/tearing, effectively changing the list, therefore iterating over a 148 # copy would either miss instances or remove some twice. 149 while self.buildings: 150 self.buildings[-1].remove() 151 self.provider_buildings = None 152 self.buildings = None
153