コード例 #1
0
ファイル: shapes.py プロジェクト: carnivoro/unknown-horizons
	def testPoint(self):
		p1 = Point(0,0)
		p2 = Point(0,2)
		self.assertEqual(p1.distance(p2), 2)
		self.assertEqual(p1.distance((0,1)), 1)
		self.assertEqual(p1.get_coordinates(), [(0,0)])
		self.assertEqual(p1, p1.copy())
コード例 #2
0
    def get_random_possible_ship_position(self):
        """Returns a position in water, that is not at the border of the world"""
        offset = 2
        while True:
            x = self.session.random.randint(self.min_x + offset,
                                            self.max_x - offset)
            y = self.session.random.randint(self.min_y + offset,
                                            self.max_y - offset)

            if (x, y) in self.ship_map:
                continue  # don't place ship where there is already a ship

            # check if there is an island nearby (check only important coords)
            position_possible = True
            for first_sign in (-1, 0, 1):
                for second_sign in (-1, 0, 1):
                    point_to_check = Point(x + offset * first_sign,
                                           y + offset * second_sign)
                    if self.get_island(point_to_check) is not None:
                        position_possible = False
                        break
            if not position_possible:  # propagate break
                continue

            break  # all checks successful

        return Point(x, y)
コード例 #3
0
    def get_next_step(self):
        """Returns the next step in the current movement
		@return: Point"""
        if self.cur is None:
            return None

        self.cur += 1
        if not self.path or self.cur == len(self.path):
            self.cur = None
            # movement finished
            return None

        if self._check_for_obstacles(self.path[self.cur]):
            # path is suddenly blocked, find another path
            self.cur -= 1  # reset, since move is not possible
            # try to calculate another path
            if not self.calc_path(Point(*self.path[-1]),
                                  self.destination_in_building):
                self.log.info("tile suddenly %s %s blocked for %s %s", \
                       self.path[self.cur][0], self.path[self.cur][1], self.unit, self.unit.worldid)
                # no other path can be found. since the problem cannot be fixed here,
                # we raise an exception
                raise PathBlockedError

        # check if we have to change visibility because of entering or leaving a building
        if self.destination_in_building and self.cur == len(self.path) - 1:
            self.destination_in_building = False
            self.unit.hide()
        elif self.source_in_building and self.cur == 2:
            self.source_in_building = False
            self.unit.show()

        return Point(*self.path[self.cur])
コード例 #4
0
 def __init__(self, x, y, rotation, owner, island, level=None, **kwargs):
     super(BasicBuilding, self).__init__(x=x, y=y, rotation=rotation, owner=owner, \
                                   island=island, **kwargs)
     self.__init(Point(x, y), rotation, owner, level)
     self.island = island
     self.settlement = self.island.get_settlement(Point(x, y)) or \
       self.island.add_settlement(self.position, self.radius, owner) if \
       owner is not None else None
コード例 #5
0
	def testCircle(self):
		c1 = Circle(Point(0,0), 1)
		c2 = Circle(Point(0,0), 2)
		c3 = Circle(Point(0,0), 0)
		self.assertFalse(c1 == c2)
		self.assertTrue(c1 != c2)
		self.assertNotEqual(c1, c2)
		self.assertEqual(c1.get_coordinates(), [(-1, 0), (0, -1), (0, 0), (0, 1), (1, 0)])
		self.assertEqual(c3.get_coordinates(), [(0,0)])
コード例 #6
0
ファイル: island.py プロジェクト: savionok/unknown-horizons
    def __init(self, origin, filename, preview=False):
        """
		Load the actual island from a file
		@param origin: Point
		@param filename: String, filename of island db or random map id
		@param preview: flag, map preview mode
		"""
        self.file = filename
        self.origin = origin
        db = self._get_island_db()

        p_x, p_y, width, height = db(
            "SELECT (MIN(x) + ?), (MIN(y) + ?), (1 + MAX(x) - MIN(x)), (1 + MAX(y) - MIN(y)) FROM ground",
            self.origin.x,
            self.origin.y,
        )[0]

        # rect for quick checking if a tile isn't on this island
        # NOTE: it contains tiles, that are not on the island!
        self.rect = Rect(Point(p_x, p_y), width, height)

        self.ground_map = {}
        for (rel_x, rel_y, ground_id, action_id, rotation) in db(
            "SELECT x, y, ground_id, action_id, rotation FROM ground"
        ):  # Load grounds
            if not preview:  # actual game, need actual tiles
                ground = Entities.grounds[ground_id](self.session, self.origin.x + rel_x, self.origin.y + rel_y)
                ground.act(action_id, rotation)
            else:
                ground = Point(self.origin.x + rel_x, self.origin.y + rel_y)
                ground.classes = tuple()
                ground.settlement = None
                # These are important for pathfinding and building to check if the ground tile
                # is blocked in any way.
            self.ground_map[(ground.x, ground.y)] = ground

        self._init_cache()

        self.settlements = []
        self.wild_animals = []
        self.num_trees = 0

        # define the rectangle with the smallest area that contains every island tile its position
        min_x = min(zip(*self.ground_map.keys())[0])
        max_x = max(zip(*self.ground_map.keys())[0])
        min_y = min(zip(*self.ground_map.keys())[1])
        max_y = max(zip(*self.ground_map.keys())[1])
        self.position = Rect.init_from_borders(min_x, min_y, max_x, max_y)

        if not preview:  # this isn't needed for previews, but it is in actual games
            self.path_nodes = IslandPathNodes(self)

            # repopulate wild animals every 2 mins if they die out.
            Scheduler().add_new_object(self.check_wild_animal_population, self, Scheduler().get_ticks(120), -1)

        """TUTORIAL:
コード例 #7
0
	def __init(self, x, y):
		self.position = Point(x, y)
		self.last_position = Point(x, y)
		self._next_target = Point(x, y)

		self.move_callbacks = WeakMethodList()
		self._conditional_callbacks = {}

		self.__is_moving = False

		self.path = self.pather_class(self, session=self.session)
コード例 #8
0
	def testRect(self):
		r1 = Rect(Point(0,0), 1, 1)
		r2 = Rect(0, 0, 1 ,1)
		r3 = Rect(Point(2, 2), 1, 1)
		self.assertEqual(r1, r2)
		self.assertTrue(r1 == r2)
		self.assertFalse(r1.contains(Point(-1,-1)))
		self.assertTrue(r2.contains(Point(0,0)))
		self.assertTrue(r2.contains(Point(1,1)))
		self.assertTrue(r1.intersects(r2))
		self.assertFalse(r1.intersects(r3))
コード例 #9
0
 def on_click(self, event):
     """Scrolls screen to the point, where the cursor points to on the minimap"""
     icon_pos = Point(*self.overlay_icon.getAbsolutePos())
     mouse_position = Point(event.getX(), event.getY())
     abs_mouse_position = icon_pos + mouse_position
     if not self.location.contains(abs_mouse_position):
         # mouse click was on icon but not acctually on minimap
         return
     abs_mouse_position = self._get_from_rotated_coords(
         abs_mouse_position.to_tuple())
     map_coord = self._minimap_coord_to_world_coord(abs_mouse_position)
     self.session.view.center(*map_coord)
コード例 #10
0
ファイル: minimap.py プロジェクト: volpino/unknown-horizons
	def _get_event_coord(self, event):
		"""Returns position of event as uh map coordinate tuple or None"""
		mouse_position = Point(event.getX(), event.getY())
		if not hasattr(self, "icon"):
			icon_pos = Point(*self.overlay_icon.getAbsolutePos())
			abs_mouse_position = icon_pos + mouse_position
			if not self.location.contains(abs_mouse_position):
				# mouse click was on icon but not actually on minimap
				return
			abs_mouse_position = abs_mouse_position.to_tuple()
		else:
			abs_mouse_position = mouse_position.to_tuple()
		if self._get_rotation_setting():
			abs_mouse_position = self._get_from_rotated_coords(abs_mouse_position)
		return self._minimap_coord_to_world_coord(abs_mouse_position)
コード例 #11
0
    def highlight_buildable(self, building_tool, tiles_to_check=None):
        """Highlights all buildable tiles.
		@param tiles_to_check: list of tiles to check for coloring."""
        # resolved variables from inner loops
        is_tile_buildable = building_tool._class.is_tile_buildable
        session = building_tool.session
        player = session.world.player
        buildable_tiles_add = building_tool._buildable_tiles.add

        if tiles_to_check is not None:  # only check these tiles
            for tile in tiles_to_check:
                if is_tile_buildable(session, tile, None):
                    building_tool._color_buildable_tile(tile)

        else:  #default build on island
            for settlement in session.world.settlements:
                if settlement.owner == player:
                    island = session.world.get_island(
                        Point(*settlement.ground_map.iterkeys().next()))
                    for tile in settlement.ground_map.itervalues():
                        if is_tile_buildable(session,
                                             tile,
                                             None,
                                             island,
                                             check_settlement=False):
                            building_tool._color_buildable_tile(tile)
コード例 #12
0
    def check_build_line(cls, session, point1, point2, rotation=45, ship=None):

        # Pathfinding currently only supports buildingsize 1x1, so don't use it in this case
        if cls.size != (1, 1):
            return [
                cls.check_build(session, point2, rotation=rotation, ship=ship)
            ]

        # use pathfinding to get a path, then try to build along it
        island = session.world.get_island(point1)
        if island is None:
            return []

        path = StaticPather.get_direct_path(island, point1, point2)
        if path is None:  # can't find a path between these points
            return []  # TODO: maybe implement alternative strategy

        possible_builds = []

        for i in path:
            action = ''
            for action_char, offset in \
                sorted(BUILDINGS.ACTION.action_offset_dict.iteritems()): # order is important here
                if (offset[0] + i[0], offset[1] + i[1]) in path:
                    action += action_char
            if action == '':
                action = 'ac'  # default

            build = cls.check_build(session, Point(*i))
            build.action = action
            possible_builds.append(build)

        return possible_builds
コード例 #13
0
 def _load(self, db, worldid):
     super(Pirate, self)._load(db, worldid)
     home = db("SELECT x, y FROM pirate_home_point")[0]
     self.home_point = Point(home[0], home[1])
     self.log.debug(
         "Pirate: home at (%d, %d), radius %d" %
         (self.home_point.x, self.home_point.y, self.home_radius))
コード例 #14
0
ファイル: island.py プロジェクト: court-jus/unknown-horizons
    def __init__(self, db, islandid, session):
        """
		@param db: db instance with island table
		@param islandid: id of island in that table
		@param session: reference to Session instance
		"""
        super(Island, self).__init__(worldid=islandid)
        self.session = session

        x, y, filename = db(
            "SELECT x, y, file FROM island WHERE rowid = ? - 1000",
            islandid)[0]
        self.__init(Point(x, y), filename)

        # create building indexers
        self.building_indexers = {}
        self.building_indexers[BUILDINGS.TREE_CLASS] = BuildingIndexer(
            WildAnimal.walking_range, self, self.session.random)

        # load settlements
        for (settlement_id, ) in db(
                "SELECT rowid FROM settlement WHERE island = ?", islandid):
            Settlement.load(db, settlement_id, self.session)

        # load buildings
        from horizons.world import load_building
        for (building_worldid, building_typeid) in \
            db("SELECT rowid, type FROM building WHERE location = ?", islandid):
            load_building(self.session, db, building_typeid, building_worldid)
コード例 #15
0
	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_to_tuple(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
コード例 #16
0
    def _get_world_location_from_event(self, evt):
        """Returns the coordinates of an event at the map.
		@return Point with int coordinates"""
        screenpoint = fife.ScreenPoint(evt.getX(), evt.getY())
        mapcoord = self.session.view.cam.toMapCoordinates(screenpoint, False)
        # undocumented legacy formula to correct coords, probably
        return Point(int(round(math.floor(mapcoord.x + mapcoord.x) / 2.0 + 0.25)), \
                     int(round(math.floor(mapcoord.y + mapcoord.y) / 2.0 + 0.25)))
コード例 #17
0
	def testPoint(self):
		p1 = Point(0,0)
		p2 = Point(0,2)
		self.assertEqual(p1.distance(p2), 2)
		self.assertEqual(p1.distance((0,1)), 1)
		self.assertEqual(p1.get_coordinates(), [(0,0)])
		self.assertEqual(p1, p1.copy())
コード例 #18
0
 def __init__(self, consumerbuilding):
     super(ConsumerBuildingPathNodes, self).__init__()
     self.nodes = {}
     for coordinate in consumerbuilding.position.get_radius_coordinates(
             consumerbuilding.radius, include_self=False):
         tile = consumerbuilding.island.get_tile(
             Point(coordinate[0], coordinate[1]))
         if tile is not None and not 'coastline' in tile.classes:
             self.nodes[coordinate] = self.NODE_DEFAULT_SPEED
コード例 #19
0
    def __call__(self, issuer):
        """Execute the command
		@param issuer: the issuer of the command
		"""
        if self.position is None:
            AmbientSound.play_special(self.sound)
        else:
            AmbientSound.play_special(
                self.sound, Point(self.position[0], self.position[1]))
コード例 #20
0
 def handle_no_possible_job(self):
     """Walk around on field, search again, when we arrive"""
     for coord in self._get_random_positions_on_object(self.home_building):
         try:
             self.move(Point(*coord), callback=self.search_job)
             self.state = self.states.no_job_walking_randomly
             return
         except MoveNotPossible:
             pass
     # couldn't find location, so don't move
     super(FarmAnimal, self).handle_no_possible_job()
コード例 #21
0
    def calculate_visibility_points(self, pirate_ship):
        """Finds out the points from which the entire map will be accessible.
		Should be called only once either during initialization or loading"""
        rect = self.session.world.map_dimensions.get_corners()
        x_min, x_max, y_min, y_max = rect[0][0], rect[1][0], rect[0][0], rect[
            2][1]

        # Necessary points (with tolerable overlapping) which cover the entire map
        # Each element contains two values: it's co-ordinate, and frequency of player ship's visit
        self.visibility_points = []
        y = y_min + self.sight_radius
        while y <= y_max:
            x = x_min + self.sight_radius
            while x <= x_max:
                self.visibility_points.append([Point(x, y), 0])
                x += self.sight_radius  # should be 2*self.sight_radius for no overlap
            y += self.sight_radius

        self.log.debug("Pirate %s: %s, visibility points" %
                       (self.worldid, pirate_ship.name))
        copy_points = list(self.visibility_points)
        for point in copy_points:
            if not self.session.world.get_tile(point[0]).is_water:
                # Make a position compromise to obtain a water tile on the point
                for x in (3, -3, 2, -2, 1, -1, 0):
                    for y in (3, -3, 2, -2, 1, -1, 0):
                        new_point = Point(point[0].x + x, point[0].y + y)
                        if self.session.world.get_tile(new_point).is_water:
                            self.visibility_points.remove(
                                point)  #remove old point
                            point[0] = new_point
                            self.visibility_points.append([point[0],
                                                           0])  #add new point
                            break
                    if self.session.world.get_tile(point[0]).is_water: break
                if not self.session.world.get_tile(point[0]).is_water:
                    self.visibility_points.remove(point)
                    continue
            self.log.debug("(%d, %d)" % (point[0].x, point[0].y))
        # A list needed to reduce visibility frequencies of a point if player is not sighted on that point
        self.visible_player = []
コード例 #22
0
    def get_random_possible_coastal_ship_position(self):
        """Returns a position in water, that is not at the border of the world but on the coast of an island"""
        offset = 2
        while True:
            x = self.session.random.randint(self.min_x + offset,
                                            self.max_x - offset)
            y = self.session.random.randint(self.min_y + offset,
                                            self.max_y - offset)

            if (x, y) in self.ship_map:
                continue  # don't place ship where there is already a ship

            result = Point(x, y)
            if self.get_island(result) is not None:
                continue  # don't choose a point on an island

            # check if there is an island nearby (check only important coords)
            for first_sign in (-1, 0, 1):
                for second_sign in (-1, 0, 1):
                    point_to_check = Point(x + first_sign, y + second_sign)
                    if self.get_island(point_to_check) is not None:
                        return result
コード例 #23
0
    def get_random_location(self, in_range):
        """Returns a random location in walking_range, that we can find a path to
		@param in_range: int, max distance to returned point from current position
		@return: Instance of Point or None"""
        possible_walk_targets = Circle(self.position,
                                       in_range).get_coordinates()
        possible_walk_targets.remove(self.position.to_tuple())
        self.session.random.shuffle(possible_walk_targets)
        for coord in possible_walk_targets:
            target = Point(*coord)
            if self.check_move(target):
                return target
        return None
コード例 #24
0
 def _make_surrounding_transparent(self, building_position):
     """Makes the surrounding of building_position transparent"""
     world_contains = self.session.world.map_dimensions.contains_without_border
     get_tile = self.session.world.get_tile
     for coord in building_position.get_radius_coordinates(
             self.nearby_objects_radius, include_self=True):
         p = Point(*coord)
         if not world_contains(p):
             continue
         tile = get_tile(p)
         if tile.object is not None and tile.object.buildable_upon:
             tile.object.fife_instance.get2dGfxVisual().setTransparency( \
               self.nearby_objects_transparency )
             self._modified_objects.add(tile.object)
コード例 #25
0
    def mouseMoved(self, evt):
        if not self.session.world.inited:
            return

        mousepoint = fife.ScreenPoint(evt.getX(), evt.getY())

        # Status menu update
        current = self.session.view.cam.toMapCoordinates(mousepoint, False)
        if abs((current.x - self.lastmoved.x)**2 +
               (current.y - self.lastmoved.y)**2) >= 4**2:
            self.lastmoved = current
            island = self.session.world.get_island(
                Point(int(round(current.x)), int(round(current.y))))
            if island:
                settlement = island.get_settlement(
                    Point(int(round(current.x)), int(round(current.y))))
                if settlement:
                    self.session.ingame_gui.resourceinfo_set(settlement)
                else:
                    self.session.ingame_gui.resourceinfo_set(None)
            else:
                self.session.ingame_gui.resourceinfo_set(None)
        # Mouse scrolling
        x, y = 0, 0
        if mousepoint.x < 5:
            x -= 5 - mousepoint.x
        elif mousepoint.x >= (self.session.view.cam.getViewPort().right() - 5):
            x += 6 + mousepoint.x - self.session.view.cam.getViewPort().right()
        if mousepoint.y < 5:
            y -= 5 - mousepoint.y
        elif mousepoint.y >= (self.session.view.cam.getViewPort().bottom() -
                              5):
            y += 6 + mousepoint.y - self.session.view.cam.getViewPort().bottom(
            )
        x *= 10
        y *= 10
        self.session.view.autoscroll(x, y)
コード例 #26
0
    def check_build_line(cls, session, point1, point2, rotation=45, ship=None):
        possible_builds = []
        area = Rect.init_from_corners(point1, point2)
        # correct placement for large buildings (mouse should be at center of building)
        area.left -= (cls.size[0] - 1) / 2
        area.right -= (cls.size[0] - 1) / 2
        area.top -= (cls.size[1] - 1) / 2
        area.bottom -= (cls.size[1] - 1) / 2

        for x in xrange(area.left, area.right + 1, cls.size[0]):
            for y in xrange(area.top, area.bottom + 1, cls.size[1]):
                possible_builds.append( \
                  cls.check_build(session, Point(x, y), rotation=rotation, ship=ship) \
                )
        return possible_builds
コード例 #27
0
    def begin_current_job(self):
        # we can only move on 1 building; simulate this by choosing a random location with
        # the building
        coords = self._get_random_positions_on_object(self.job.object)

        # move to first walkable target coord we find
        for coord in coords:
            # job target is walkable, so at least one coord of it has to be
            # so we can safely assume, that we will find a walkable coord
            target_location = Point(*coord)
            if self.check_move(target_location):
                super(FarmAnimal,
                      self).begin_current_job(job_location=target_location)
                return
        assert False
コード例 #28
0
ファイル: ship.py プロジェクト: court-jus/unknown-horizons
    def go(self, x, y):
        """Moves the ship.
		This is called when a ship is selected and RMB is pressed outside the ship"""
        self.stop()

        #disable the trading route
        if hasattr(self, 'route'):
            self.route.disable()
        ship_id = self.worldid  # this has to happen here,

        # cause a reference to self in a temporary function is implemented
        # as a hard reference, which causes a memory leak
        def tmp():
            if self.session.world.player == self.owner:
                self.session.view.renderer['GenericRenderer'].removeAll(
                    "buoy_" + str(ship_id))

        tmp()
        move_target = Point(int(round(x)), int(round(y)))
        try:
            self.move(move_target, tmp)
        except MoveNotPossible:
            # find a near tile to move to
            target_found = False
            surrounding = Circle(move_target, radius=0)
            while not target_found and surrounding.radius < 4:
                surrounding.radius += 1
                for move_target in surrounding:
                    try:
                        self.move(move_target, tmp)
                    except MoveNotPossible:
                        continue
                    target_found = True
                    break
        if self.session.world.player == self.owner:
            if self.position.x != move_target.x or self.position.y != move_target.y:
                move_target = self.get_move_target()
            if move_target is not None:
                loc = fife.Location(self.session.view.layers[LAYERS.OBJECTS])
                loc.thisown = 0
                coords = fife.ModelCoordinate(move_target.x, move_target.y)
                coords.thisown = 0
                loc.setLayerCoordinates(coords)
                self.session.view.renderer['GenericRenderer'].addAnimation(
                    "buoy_" + str(self.worldid), fife.GenericRendererNode(loc),
                    horizons.main.fife.animationpool.addResourceFromFile(
                        "as_buoy0-idle-45"))
コード例 #29
0
    def calc_path(self,
                  destination,
                  destination_in_building=False,
                  check_only=False,
                  source=None):
        """Calculates a path to destination
		@param destination: a destination supported by pathfinding
		@param destination_in_building: bool, whether destination is in a building.
		                                this makes the unit "enter the building"
		@param check_only: if True the path isn't saved
		@param source: use this as source of movement instead of self.unit.position
		@return: True iff movement is possible"""
        # calculate our source
        if source is None:
            source = self.unit.position
            if self.unit.is_moving() and self.path:
                # we are moving, use next step as source
                source = Point(*self.path[self.cur])
            else:
                # check if we are in a building
                building = self.session.world.get_building(self.unit.position)
                if building is not None:
                    source = building

        # call algorithm
        # to use a different pathfinding code, just change the following line
        path = FindPath()(source, destination, self._get_path_nodes(),
                 self._get_blocked_coords(), self.move_diagonal, \
                 self.make_target_walkable)

        if path is None:
            return False

        if not check_only:
            # prepare movement
            self.path = path
            if self.unit.is_moving():
                self.cur = 0
                self.unit.show()  # make sure unit is displayed
            else:
                self.cur = -1
            self.source_in_building = hasattr(
                source, 'is_building') and source.is_building
            self.destination_in_building = destination_in_building

        return True
コード例 #30
0
ファイル: island.py プロジェクト: court-jus/unknown-horizons
    def __init(self, origin, filename):
        """
		Load the actual island from a file
		@param origin: Point
		@param filename: String, filename of island db or random map id
		"""
        self.file = filename
        self.origin = origin

        # check if filename is a random map
        if random_map.is_random_island_id_string(filename):
            # it's a random map id, create this map and load it
            db = random_map.create_random_island(filename)
        else:
            db = DbReader(
                filename
            )  # Create a new DbReader instance to load the maps file.

        p_x, p_y, width, height = db(
            "SELECT (MIN(x) + ?), (MIN(y) + ?), (1 + MAX(x) - MIN(x)), (1 + MAX(y) - MIN(y)) FROM ground",
            self.origin.x, self.origin.y)[0]

        # rect for quick checking if a tile isn't on this island
        # NOTE: it contains tiles, that are not on the island!
        self.rect = Rect(Point(p_x, p_y), width, height)

        self.ground_map = {}
        for (rel_x, rel_y, ground_id
             ) in db("SELECT x, y, ground_id FROM ground"):  # Load grounds
            ground = Entities.grounds[ground_id](self.session,
                                                 self.origin.x + rel_x,
                                                 self.origin.y + rel_y)
            # These are important for pathfinding and building to check if the ground tile
            # is blocked in any way.
            self.ground_map[(ground.x, ground.y)] = ground

        self.settlements = []
        self.wild_animals = []

        self.path_nodes = IslandPathNodes(self)

        # repopulate wild animals every 2 mins if they die out.
        Scheduler().add_new_object(self.check_wild_animal_population, self,
                                   Scheduler().get_ticks(120), -1)
        """TUTORIAL:
コード例 #31
0
	def load(self, db, worldid):
		super(BasicBuilding, self).load(db, worldid)
		x, y, self.health, location, rotation, level = db.get_building_row(worldid)

		owner_id = db.get_settlement_owner(location)
		owner = None if owner_id is None else WorldObject.get_object_by_id(owner_id)

		remaining_ticks_of_month = None
		if self.has_running_costs:
			remaining_ticks_of_month = db("SELECT ticks FROM remaining_ticks_of_month WHERE rowid=?", worldid)[0][0]

		self.__init(Point(x, y), rotation, owner, level=level, \
		            remaining_ticks_of_month=remaining_ticks_of_month)

		self.island, self.settlement = self.load_location(db, worldid)

		# island.add_building handles registration of building for island and settlement
		self.island.add_building(self, self.owner)
コード例 #32
0
    def is_walkable(self, coord):
        """Check if a unit may walk on the tile specified by coord on land
		NOTE: nature tiles (trees..) are considered to be walkable (or else they could be used as
		      walls against enemies)
		@param coord: tuple: (x, y)
		"""
        tile_object = self.island.get_tile(Point(*coord))

        if tile_object is None:
            # tile is water
            return False

        # if it's not constructable, it is usually also not walkable
        # NOTE: this isn't really a clean implementation, but it works for now
        # it eliminates e.g. water and beaches, that shouldn't be walked on
        if not "constructible" in tile_object.classes:
            return False
        if tile_object.blocked and not tile_object.object.walkable:
            return False
        # every test is passed, tile is walkable
        return True
コード例 #33
0
    def is_tile_buildable(cls,
                          session,
                          tile,
                          ship,
                          island=None,
                          check_settlement=True):
        """Checks a tile for buildability.
		@param tile: Ground object
		@param ship: Ship instance if building from ship
		@param island: Island instance, if already known. If None, it will be calculated
		@param check_settlement: bool, whether to check for settlement
		@return bool, True for "is buildable" """
        position = Point(tile.x, tile.y)
        try:
            cls._check_island(session, position, island)
            if check_settlement:
                cls._check_settlement(session, position, ship=ship)
            cls._check_buildings(session, position)
        except _NotBuildableError:
            return False
        return True
コード例 #34
0
	def _mark(self, *edges):
		"""Highights building instances and keeps self.selected up to date."""
		if len(edges) == 1:
			edges = (edges[0], edges[0])
		elif len(edges) == 2:
			edges = ((min(edges[0][0], edges[1][0]), min(edges[0][1], edges[1][1])), \
					 (max(edges[0][0], edges[1][0]), max(edges[0][1], edges[1][1])))
		else:
			edges = None
		if self.oldedges != edges or edges is None:
			for i in self.selected:
				self.session.view.renderer['InstanceRenderer'].removeColored(i._instance)
			self.selected = set()
			self.oldedges = edges
		if edges is not None:
			for x in xrange(edges[0][0], edges[1][0] + 1):
				for y in xrange(edges[0][1], edges[1][1] + 1):
					b = self.session.world.get_building(Point(x, y))
					if b is not None and b.tearable and self.session.world.player == b.owner:
						self.selected.add(b)
			for i in self.selected:
				self.session.view.renderer['InstanceRenderer'].addColored(i._instance, \
				                                                          *self.tear_selection_color)
コード例 #35
0
ファイル: minimap.py プロジェクト: volpino/unknown-horizons
	def _recalculate(self, where = None, dump_data=False):
		"""Calculate which pixel of the minimap should display what and draw it
		@param where: Rect of minimap coords. Defaults to self.location
		@param dump_data: Don't draw but return calculated data"""
		self.minimap_image.set_drawing_enabled()

		rt = self.minimap_image.rendertarget
		render_name = self._get_render_name("base")

		if where is None:
			where = self.location
			rt.removeAll(render_name)

		# calculate which area of the real map is mapped to which pixel on the minimap
		pixel_per_coord_x, pixel_per_coord_y = self._world_to_minimap_ratio

		# calculate values here so we don't have to do it in the loop
		pixel_per_coord_x_half_as_int = int(pixel_per_coord_x/2)
		pixel_per_coord_y_half_as_int = int(pixel_per_coord_y/2)

		real_map_point = Point(0, 0)
		world_min_x = self.world.min_x
		world_min_y = self.world.min_y
		get_island_tuple = self.world.get_island_tuple
		island_col = self.COLORS["island"]
		location_left = self.location.left
		location_top = self.location.top
		if dump_data:
			data = []
			drawPoint = lambda name, fife_point, r, g, b : data.append( (fife_point.x, fife_point.y, r, g, b) )
		else:
			drawPoint = rt.addPoint
		fife_point = fife.Point(0,0)

		use_rotation = self._get_rotation_setting()

		# loop through map coordinates, assuming (0, 0) is the origin of the minimap
		# this faciliates calculating the real world coords
		for x in xrange(where.left-self.location.left, where.left+where.width-self.location.left):
			# Optimisation: remember last island
			last_island = None
			island = None
			for y in xrange(where.top-self.location.top, where.top+where.height-self.location.top):

				"""
				This code should be here, but since python can't do inlining, we have to inline
				ourselves for performance reasons
				covered_area = Rect.init_from_topleft_and_size(
				  int(x * pixel_per_coord_x)+world_min_x, \
				  int(y * pixel_per_coord_y)+world_min_y), \
				  int(pixel_per_coord_x), int(pixel_per_coord_y))
				real_map_point = covered_area.center()
				"""
				# use center of the rect that the pixel covers
				real_map_point.x = int(x*pixel_per_coord_x)+world_min_x + \
											pixel_per_coord_x_half_as_int
				real_map_point.y = int(y*pixel_per_coord_y)+world_min_y + \
											pixel_per_coord_y_half_as_int
				real_map_point_tuple = (real_map_point.x, real_map_point.y)

				# check what's at the covered_area
				if last_island is not None and real_map_point_tuple in last_island.ground_map:
					island = last_island
				else:
					island = get_island_tuple(real_map_point_tuple)
				if island is not None:
					last_island = island
					# this pixel is an island
					settlement = island.get_settlement(real_map_point)
					if settlement is None:
						# island without settlement
						color = island_col
					else:
						# pixel belongs to a player
						color = settlement.owner.color.to_tuple()
				else:
					continue

				if use_rotation:
					# inlined _get_rotated_coords
					rot_x, rot_y = self._rotate( (location_left + x, location_top + y), self._rotations)
					fife_point.set(rot_x - location_left, rot_y - location_top)
				else:
					fife_point.set(x, y)

				drawPoint(render_name, fife_point, *color)

		if dump_data:
			return json.dumps( data )
コード例 #36
0
ファイル: minimap.py プロジェクト: lmchawla/unknown-horizons
    def _recalculate(self, where=None):
        """Calculate which pixel of the minimap should display what and draw it
		@param where: Rect of minimap coords. Defaults to self.location"""
        if where is None:
            where = self.location

            # calculate which area of the real map is mapped to which pixel on the minimap
        pixel_per_coord_x, pixel_per_coord_y = self._get_world_to_minimap_ratio()

        # calculate values here so we don't have to do it in the loop
        pixel_per_coord_x_half_as_int = int(pixel_per_coord_x / 2)
        pixel_per_coord_y_half_as_int = int(pixel_per_coord_y / 2)

        real_map_point = Point(0, 0)
        location_left = self.location.left
        location_top = self.location.top
        world_min_x = self.world.min_x
        world_min_y = self.world.min_y
        get_island = self.world.get_island
        water_col, island_col = [self.colors[i] for i in [self.water_id, self.island_id]]
        color = None
        renderer_addPoint = self.renderer.addPoint

        # loop through map coordinates, assuming (0, 0) is the origin of the minimap
        # this faciliates calculating the real world coords
        for x in xrange(where.left - self.location.left, where.left + where.width - self.location.left):
            # Optimisation: remember last island
            last_island = None
            island = None
            for y in xrange(where.top - self.location.top, where.top + where.height - self.location.top):

                """
				This code should be here, but since python can't do inlining, we have to inline
				ourselves for performance reasons
				covered_area = Rect.init_from_topleft_and_size(
				  int(x * pixel_per_coord_x)+world_min_x, \
				  int(y * pixel_per_coord_y)+world_min_y), \
				  int(pixel_per_coord_x), int(pixel_per_coord_y))
				real_map_point = covered_area.center()
				"""
                # use center of the rect that the pixel covers
                real_map_point.x = int(x * pixel_per_coord_x) + world_min_x + pixel_per_coord_x_half_as_int
                real_map_point.y = int(y * pixel_per_coord_y) + world_min_y + pixel_per_coord_y_half_as_int
                real_map_point_tuple = (real_map_point.x, real_map_point.y)
                # we changed the minimap coords, so change back here
                minimap_point = (location_left + x, location_top + y)

                # check what's at the covered_area
                if last_island is not None and real_map_point_tuple in last_island.ground_map:
                    island = last_island
                else:
                    island = get_island(real_map_point)
                if island is not None:
                    last_island = island
                    # this pixel is an island
                    settlement = island.get_settlement(real_map_point)
                    if settlement is None:
                        # island without settlement
                        color = island_col
                    else:
                        # pixel belongs to a player
                        color = settlement.owner.color.to_tuple()
                else:
                    color = water_col

                    # _get_rotated_coords has been inlined here
                renderer_addPoint("minimap", self.renderernodes[self._rotate(minimap_point, self._rotations)], *color)