def find_warehouse_location(cls, ship, land_manager): """ Finds a location for the warehouse on the given island @param LandManager: the LandManager of the island @return _BuildPosition: a possible build location """ moves = [(-1, 0), (0, -1), (0, 1), (1, 0)] island = land_manager.island world = island.session.world personality = land_manager.owner.personality_manager.get('FoundSettlement') options = [] for (x, y), tile in sorted(island.ground_map.iteritems()): ok = False for x_offset, y_offset in moves: for d in xrange(2, 6): coords = (x + d * x_offset, y + d * y_offset) if coords in world.water_body and world.water_body[coords] == world.water_body[ship.position.to_tuple()]: # the planned warehouse should be reachable from the ship's water body ok = True if not ok: continue build_info = None point = Point(x, y) warehouse = Builder(BUILDINGS.WAREHOUSE, land_manager, point, ship = ship) if not warehouse: continue cost = 0 for coords in land_manager.village: distance = point.distance(coords) if distance < personality.too_close_penalty_threshold: cost += personality.too_close_constant_penalty + personality.too_close_linear_penalty / (distance + 1.0) else: cost += distance for settlement_manager in land_manager.owner.settlement_managers: cost += warehouse.position.distance(settlement_manager.settlement.warehouse.position) * personality.linear_warehouse_penalty options.append((cost, warehouse)) for _, build_info in sorted(options): (x, y) = build_info.position.get_coordinates()[4] if ship.check_move(Circle(Point(x, y), BUILDINGS.BUILD.MAX_BUILDING_SHIP_DISTANCE)): return build_info return None