def highlight_buildable(self, tiles_to_check=None):
		"""Highlights all buildable tiles.
		@param tiles_to_check: list of tiles to check for coloring."""
		self._build_logic.highlight_buildable(self, tiles_to_check)

		# also distinguish related buildings (lumberjack for tree)
		related = frozenset(self.session.db.get_inverse_related_building_ids(self._class.id))
		renderer = self.session.view.renderer['InstanceRenderer']
		if tiles_to_check is None:
			buildings_to_select = [ buildings_to_select for\
			                        settlement in self.session.world.settlements if \
			                        settlement.owner.is_local_player for \
			                        bid in related  for \
			                        buildings_to_select in settlement.buildings_by_id[bid] ]

			tiles = SelectableBuildingComponent.select_many(buildings_to_select, renderer)
			self._related_buildings_selected_tiles = frozenset(tiles)
		else:
			buildings_to_select = [ tile.object for tile in tiles_to_check if \
			                        tile.object is not None and tile.object.id in related ]
			for tile in tiles_to_check:
				# check if we need to recolor the tiles
				if tile in self._related_buildings_selected_tiles:
					SelectableBuildingComponent._add_selected_tile(tile, renderer, remember=False)

		for building in buildings_to_select:
			self._related_buildings.add(building)
	def _draw_preview_building_range(self, building, settlement):
		"""Color the range as if the building was selected"""
		# get required data from component definition (instance doesn't not
		# exist yet
		try:
			template = self._class.get_component_template(SelectableComponent.NAME)
		except KeyError:
			pass
		else:
			radius_only_on_island = True
			if 'range_applies_only_on_island' in template:
				radius_only_on_island =  template['range_applies_only_on_island']

			SelectableBuildingComponent.select_building(self.session, building.position, settlement, self._class.radius, radius_only_on_island)
    def _color_preview_building(self, building, settlement):
        """Draw fancy stuff for build preview
		@param building: return value from buildable, _BuildPosition
		"""
        if building.buildable:
            # Tile might still have not buildable color -> remove it
            self.renderer.removeColored(self.buildings_fife_instances[building])
            self.renderer.addOutlined(
                self.buildings_fife_instances[building],
                self.buildable_color[0],
                self.buildable_color[1],
                self.buildable_color[2],
                GFX.BUILDING_OUTLINE_WIDTH,
                GFX.BUILDING_OUTLINE_THRESHOLD,
            )
            # get required data from component definition (instance doesn't not
            # exist yet
            try:
                template = self._class.get_component_template(SelectableComponent.NAME)
            except KeyError:
                pass
            else:
                radius_only_on_island = True
                if "range_applies_only_on_island" in template:
                    radius_only_on_island = template["range_applies_only_on_island"]
                SelectableBuildingComponent.select_building(
                    self.session, building.position, settlement, self._class.radius, radius_only_on_island
                )

                # highlight directly related buildings (tree for lumberjacks)
                if settlement is not None:
                    related = frozenset(self.session.db.get_related_building_ids(self._class.id))
                    for tile in settlement.get_tiles_in_radius(
                        building.position, self._class.radius, include_self=True
                    ):
                        obj = tile.object
                        if (obj is not None) and (obj.id in related) and (obj not in self._highlighted_buildings):
                            self._highlighted_buildings.add(
                                (obj, False)
                            )  # False: was_selected, see _restore_highlighted_buildings
                            # currently same code as highlight_related_buildings
                            inst = obj.fife_instance
                            self.renderer.addOutlined(inst, *self.related_building_outline)
                            self.renderer.addColored(inst, *self.related_building_color)

        else:  # not buildable
            # must remove other highlight, fife does not support both
            self.renderer.removeOutlined(self.buildings_fife_instances[building])
            self.renderer.addColored(self.buildings_fife_instances[building], *self.not_buildable_color)
    def highlight_buildable(self, tiles_to_check=None, new_buildings=True):
        """Highlights all buildable tiles and select buildings that are inversely related in order to show their range.
		@param tiles_to_check: list of tiles to check for coloring.
		@param new_buildings: Set to true if you have set tiles_to_check and there are new buildings. An internal structure for optimisation will be amended."""
        self._build_logic.highlight_buildable(self, tiles_to_check)

        # Also distinguish inversely related buildings (lumberjack for tree).
        # Highlight their range at all times.
        # (There is another similar highlight, but it only marks building when
        # the current build preview is in its range)
        related = self.session.db.get_inverse_related_building_ids(self._class.id)

        # If the current buildings has related buildings, also show other buildings
        # of this class. You usually don't want overlapping ranges of e.g. lumberjacks.
        if (
            self._class.id in self.session.db.get_buildings_with_related_buildings()
            and self._class.id != BUILDINGS.RESIDENTIAL_CLASS
        ):
            # TODO: generalize settler class exclusion, e.g. when refactoring it into components

            related = related + [self._class.id]  # don't += on retrieved data from db

        related = frozenset(related)

        renderer = self.session.view.renderer["InstanceRenderer"]
        if tiles_to_check is None or new_buildings:  # first run, check all
            buildings_to_select = [
                buildings_to_select
                for settlement in self.session.world.settlements
                if settlement.owner.is_local_player
                for bid in related
                for buildings_to_select in settlement.buildings_by_id[bid]
            ]

            tiles = SelectableBuildingComponent.select_many(buildings_to_select, renderer)
            self._related_buildings_selected_tiles = frozenset(tiles)
        else:  # we don't need to check all
            # duplicates filtered later
            buildings_to_select = [
                tile.object for tile in tiles_to_check if tile.object is not None and tile.object.id in related
            ]
            for tile in tiles_to_check:
                # check if we need to recolor the tiles
                if tile in self._related_buildings_selected_tiles:
                    SelectableBuildingComponent._add_selected_tile(tile, renderer, remember=False)

        for building in buildings_to_select:
            self._related_buildings.add(building)
	def _remove_building_instances(self):
		"""Deletes fife instances of buildings"""

		try:
			self._class.get_component_template(SelectableComponent.NAME)
		except KeyError:
			pass
		else:
			deselected_tiles = SelectableBuildingComponent.deselect_building(self.session)
			# redraw buildables (removal of selection might have tampered with it)
			self.highlight_buildable(deselected_tiles)

		for inst_weakref in self._modified_instances:
			fife_instance = inst_weakref()
			if fife_instance:
				# remove everything that might have been added, we don't keep track of the single changes
				self.renderer.removeOutlined(fife_instance)
				self.renderer.removeColored(fife_instance)
				if not hasattr(fife_instance, "keep_translucency") or not fife_instance.keep_translucency:
					fife_instance.get2dGfxVisual().setTransparency(0)
		for building in self._related_buildings:
			# restore selection, removeOutline can destroy it
			building.get_component(SelectableComponent).set_selection_outline()
		self._modified_instances.clear()
		for fife_instance in self.buildings_fife_instances.itervalues():
			layer = fife_instance.getLocationRef().getLayer()
			# layer might not exist, happens for some reason after a build
			if layer is not None:
				layer.deleteInstance(fife_instance)
	def _remove_building_instances(self):
		"""Deletes fife instances of buildings"""

		try:
			self._class.get_component_template(SelectableComponent.NAME)
		except KeyError:
			pass
		else:
			deselected_tiles = SelectableBuildingComponent.deselect_building(self.session)
			# redraw buildables (removal of selection might have tampered with it)
			self.highlight_buildable(deselected_tiles)

		self._restore_modified_instances()
		for building in self._related_buildings:
			# restore selection, removeOutline can destroy it
			building.get_component(SelectableComponent).set_selection_outline()
		for fife_instance in self.buildings_fife_instances.itervalues():
			layer = fife_instance.getLocationRef().getLayer()
			# layer might not exist, happens for some reason after a build
			if layer is not None:
				layer.deleteInstance(fife_instance)
		self.buildings_fife_instances = {}
	def _clear_caches(self):
		"""Clear all data caches in global namespace related to a session"""
		WorldObject.reset()
		NamedComponent.reset()
		AIPlayer.clear_caches()
		SelectableBuildingComponent.reset()