Ejemplo n.º 1
0
	def _on_production_change(self):
		"""Makes the instance act according to the producers
		current state"""
		state = self._get_current_state()
		new_action = 'idle'
		if state is PRODUCTION.STATES.producing:
			new_action = "work"
		elif state is PRODUCTION.STATES.inventory_full:
			new_action = "idle_full"

		# don't force restarts as not to disturb sequences such as tree growth
		self.instance.act(new_action, repeating=True, force_restart=False)

		if self.instance.has_status_icon:
			full = state is PRODUCTION.STATES.inventory_full
			if full and not hasattr(self, "_producer_status_icon"):
				affected_res = set() # find them:
				for prod in self.get_productions():
					affected_res = affected_res.union( prod.get_unstorable_produced_res() )
				self._producer_status_icon = InventoryFullStatus(self.instance, affected_res)
				AddStatusIcon.broadcast(self, self._producer_status_icon)

			if not full and hasattr(self, "_producer_status_icon"):
				RemoveStatusIcon.broadcast(self, self.instance, InventoryFullStatus)
				del self._producer_status_icon
Ejemplo n.º 2
0
	def set_active(self, production=None, active=True):
		"""Pause or unpause a production (aka set it active/inactive).
		see also: is_active, toggle_active
		@param production: instance of Production. if None, we do it to all productions.
		@param active: whether to set it active or inactive"""
		if production is None:
			# set all
			for production in self.get_productions():
				self.set_active(production, active)
		else:
			line_id = production.get_production_line_id()
			if active:
				if not self.is_active(production):
					self.log.debug("ResHandler %s: reactivating production %s", self.instance.worldid, line_id)
					self._productions[line_id] = production
					del self._inactive_productions[line_id]
					production.pause(pause=False)
			else:
				if self.is_active(production):
					self.log.debug("ResHandler %s: deactivating production %s", self.instance.worldid, line_id)
					self._inactive_productions[line_id] = production
					del self._productions[line_id]
					production.pause()

			if self.is_active() is not self.__active:
				self.__active = not self.__active
				if self.__active:
					RemoveStatusIcon.broadcast(self, self.instance, DecommissionedStatus)
				else:
					icon = DecommissionedStatus(self.instance)
					AddStatusIcon.broadcast(self, icon)

		self.instance._changed()
		self.on_activity_changed(self.is_active())
Ejemplo n.º 3
0
    def _on_production_change(self):
        """Makes the instance act according to the producers
		current state"""
        state = self._get_current_state()
        new_action = 'idle'
        if state is PRODUCTION.STATES.producing:
            new_action = "work"
        elif state is PRODUCTION.STATES.inventory_full:
            new_action = "idle_full"

        # don't force restarts as not to disturb sequences such as tree growth
        self.instance.act(new_action, repeating=True, force_restart=False)

        if self.instance.has_status_icon:
            full = state is PRODUCTION.STATES.inventory_full
            if full and not hasattr(self, "_producer_status_icon"):
                affected_res = set()  # find them:
                for prod in self.get_productions():
                    affected_res = affected_res.union(
                        prod.get_unstorable_produced_res())
                self._producer_status_icon = InventoryFullStatus(
                    self.instance, affected_res)
                AddStatusIcon.broadcast(self, self._producer_status_icon)

            if not full and hasattr(self, "_producer_status_icon"):
                RemoveStatusIcon.broadcast(self, self.instance,
                                           InventoryFullStatus)
                del self._producer_status_icon
Ejemplo n.º 4
0
	def _on_production_change(self):
		"""Makes the instance act according to the producers
		current state"""
		state = self._get_current_state()
		if (state is PRODUCTION.STATES.waiting_for_res or\
			state is PRODUCTION.STATES.paused or\
			state is PRODUCTION.STATES.none):
			self.instance.act("idle", repeating=True)
		elif state is PRODUCTION.STATES.producing:
			self.instance.act("work", repeating=True)
		elif state is PRODUCTION.STATES.inventory_full:
			self.instance.act("idle_full", repeating=True)

		if self.instance.has_status_icon:
			full = state is PRODUCTION.STATES.inventory_full
			if full and not hasattr(self, "_producer_status_icon"):
				affected_res = set() # find them:
				for prod in self.get_productions():
					affected_res = affected_res.union( prod.get_unstorable_produced_res() )
				self._producer_status_icon = InventoryFullStatus(self.instance, affected_res)
				AddStatusIcon.broadcast(self, self._producer_status_icon)

			if not full and hasattr(self, "_producer_status_icon"):
				RemoveStatusIcon.broadcast(self, self.instance, InventoryFullStatus)
				del self._producer_status_icon
Ejemplo n.º 5
0
	def update_capacity_utilisation(self):
		"""Called by the scheduler to update the utilisation regularly"""
		if not self.capacity_utilisation_below(ProductivityLowStatus.threshold) is not self.__utilisation_ok:
			self.__utilisation_ok = not self.__utilisation_ok
			if self.__utilisation_ok:
				RemoveStatusIcon.broadcast(self, self.instance, ProductivityLowStatus)
			else:
				icon = ProductivityLowStatus(self.instance)
				AddStatusIcon.broadcast(self, icon)
Ejemplo n.º 6
0
	def update_capacity_utilization(self):
		"""Called by the scheduler to update the utilization regularly"""
		if not self.capacity_utilization_below(ProductivityLowStatus.threshold) is not self.__utilization_ok:
			self.__utilization_ok = not self.__utilization_ok
			if self.__utilization_ok:
				RemoveStatusIcon.broadcast(self, self.instance, ProductivityLowStatus)
			else:
				icon = ProductivityLowStatus(self.instance)
				AddStatusIcon.broadcast(self, icon)
Ejemplo n.º 7
0
	def __init__(self, session):
		self.session = session
		# {instance: [list of icons]}
		self.icons = {}
		# Renderer used to render the icons
		self.renderer = self.session.view.renderer['GenericRenderer']

		AddStatusIcon.subscribe(self.on_add_icon_message)
		RemoveStatusIcon.subscribe(self.on_remove_icon_message)
		WorldObjectDeleted.subscribe(self.on_worldobject_deleted_message)
Ejemplo n.º 8
0
	def _update_status_icon(self):
		if self.has_status_icon:
			unhappy = self.happiness < self.__get_data("happiness_inhabitants_decrease_limit")
			# check for changes
			if unhappy and not hasattr(self, "_settler_status_icon"):
				self._settler_status_icon = SettlerUnhappyStatus(self) # save ref for removal later
				AddStatusIcon.broadcast(self, self._settler_status_icon)
			if not unhappy and hasattr(self, "_settler_status_icon"):
				RemoveStatusIcon.broadcast(self, self, SettlerUnhappyStatus)
				del self._settler_status_icon
Ejemplo n.º 9
0
	def _update_status_icon(self):
		if self.has_status_icon:
			unhappy = self.happiness < self.__get_data("happiness_inhabitants_decrease_limit")
			# check for changes
			if unhappy and not hasattr(self, "_settler_status_icon"):
				self._settler_status_icon = SettlerUnhappyStatus(self) # save ref for removal later
				AddStatusIcon.broadcast(self, self._settler_status_icon)
			if not unhappy and hasattr(self, "_settler_status_icon"):
				RemoveStatusIcon.broadcast(self, self, SettlerUnhappyStatus)
				del self._settler_status_icon
Ejemplo n.º 10
0
	def infect(self, building, load=None):
		"""@load: (db, disaster_worldid), set on restoring infected state of savegame"""
		super(BuildingInfluencingDisaster, self).infect(building, load=load)
		self._affected_buildings.append(building)
		havoc_time = self.TIME_BEFORE_HAVOC
		# keep in sync with load()
		if load:
			db, worldid = load
			havoc_time = db("SELECT remaining_ticks_havoc FROM building_influencing_disaster WHERE disaster = ? AND building = ?", worldid, building.worldid)[0][0]
		Scheduler().add_new_object(Callback(self.wreak_havoc, building), self, run_in=havoc_time)
		AddStatusIcon.broadcast(building, self.STATUS_ICON(building))
		NewDisaster.broadcast(building.owner, building, self.__class__, self)
Ejemplo n.º 11
0
	def _update_decommissioned_icon(self):
		"""Add or remove decommissioned icon."""
		if not self.instance.has_status_icon:
			return

		if self.is_active() is not self.__active:
			self.__active = not self.__active
			if self.__active:
				RemoveStatusIcon.broadcast(self, self.instance, DecommissionedStatus)
			else:
				icon = DecommissionedStatus(self.instance)
				AddStatusIcon.broadcast(self, icon)
Ejemplo n.º 12
0
    def end(self):
        self.tooltip_instance = None
        self.tooltip_icon.hide_tooltip()
        self.tooltip_icon = None

        self.renderer = None
        self.icons = None

        AddStatusIcon.unsubscribe(self.on_add_icon_message)
        HoverInstancesChanged.unsubscribe(self.on_hover_instances_changed)
        RemoveStatusIcon.unsubscribe(self.on_remove_icon_message)
        WorldObjectDeleted.unsubscribe(self.on_worldobject_deleted_message)
	def end(self):
		self.tooltip_instance = None
		self.tooltip_icon.hide_tooltip()
		self.tooltip_icon = None

		self.renderer = None
		self.icons = None

		AddStatusIcon.unsubscribe(self.on_add_icon_message)
		HoverInstancesChanged.unsubscribe(self.on_hover_instances_changed)
		RemoveStatusIcon.unsubscribe(self.on_remove_icon_message)
		WorldObjectDeleted.unsubscribe(self.on_worldobject_deleted_message)
	def infect(self, building, load=None):
		"""@load: (db, disaster_worldid), set on restoring infected state of savegame"""
		super(BuildingInfluencingDisaster, self).infect(building, load=load)
		self._affected_buildings.append(building)
		havoc_time = self.TIME_BEFORE_HAVOC
		# keep in sync with load()
		if load:
			db, worldid = load
			havoc_time = db("SELECT remaining_ticks_havoc FROM building_influencing_disaster WHERE disaster = ? AND building = ?", worldid, building.worldid)[0][0]
		Scheduler().add_new_object(Callback(self.wreak_havoc, building), self, run_in=havoc_time)
		AddStatusIcon.broadcast(building, self.STATUS_ICON(building))
		NewDisaster.broadcast(building.owner, building, self.__class__, self)
Ejemplo n.º 15
0
	def _update_decommissioned_icon(self):
		"""Add or remove decommissioned icon."""
		if not self.instance.has_status_icon:
			return

		if self.is_active() is not self.__active:
			self.__active = not self.__active
			if self.__active:
				RemoveStatusIcon.broadcast(self, self.instance, DecommissionedStatus)
			else:
				icon = DecommissionedStatus(self.instance)
				AddStatusIcon.broadcast(self, icon)
Ejemplo n.º 16
0
def test_decommissioned(session, player):
    settlement, island = settle(session)

    lj = Build(BUILDINGS.LUMBERJACK, 30, 30, island, settlement=settlement)(player)

    cb = mock.Mock()
    AddStatusIcon.subscribe(cb)

    assert not cb.called

    ToggleActive(lj.get_component(Producer))(player)

    assert_called_with_icon(cb, DecommissionedStatus)
Ejemplo n.º 17
0
def test_decommissioned(session, player):
	settlement, island = settle(session)

	lj = Build(BUILDINGS.LUMBERJACK, 30, 30, island, settlement=settlement)(player)

	cb = mock.Mock()
	AddStatusIcon.subscribe(cb)

	assert not cb.called

	ToggleActive(lj.get_component(Producer))(player)

	assert_called_with_icon(cb, DecommissionedStatus)
Ejemplo n.º 18
0
	def infect(self, building, load=None):
		"""Infect a building with fire.
		@load: (db, disaster_worldid), set on restoring infected state of savegame"""
		super(FireDisaster, self).infect(building, load=load)
		# keep in sync with load()
		AddStatusIcon.broadcast(building, FireStatusIcon(building))
		self._affected_buildings.append(building)
		havoc_time = self.TIME_BEFORE_HAVOC
		if load:
			db, worldid = load
			havoc_time = db("SELECT remaining_ticks_havoc FROM fire_disaster WHERE disaster = ? AND building = ?", worldid, building.worldid)[0][0]

		Scheduler().add_new_object(Callback(self.wreak_havoc, building), self, run_in=havoc_time)
Ejemplo n.º 19
0
	def infect(self, building, load=None):
		"""Infect a building with fire.
		@load: (db, disaster_worldid), set on restoring infected state of savegame"""
		super(FireDisaster, self).infect(building, load=load)
		# keep in sync with load()
		AddStatusIcon.broadcast(building, FireStatusIcon(building))
		NewDisaster.broadcast(building.owner, building, FireDisaster)
		self._affected_buildings.append(building)
		havoc_time = self.TIME_BEFORE_HAVOC
		if load:
			db, worldid = load
			havoc_time = db("SELECT remaining_ticks_havoc FROM fire_disaster WHERE disaster = ? AND building = ?", worldid, building.worldid)[0][0]

		Scheduler().add_new_object(Callback(self.wreak_havoc, building), self, run_in=havoc_time)
Ejemplo n.º 20
0
def test_productivity_low(session, player):
	settlement, island = settle(session)

	Build(BUILDINGS.CHARCOAL_BURNER, 30, 30, island, settlement=settlement)(player)

	cb = mock.Mock()
	AddStatusIcon.subscribe(cb)

	# Not yet low
	assert not cb.called

	session.run(seconds=60)

	# Now low
	assert_called_with_icon(cb, ProductivityLowStatus)
Ejemplo n.º 21
0
	def __init__(self, session):
		self.session = session
		# {instance: [list of icons]}
		self.icons = {}
		# Renderer used to render the icons
		self.renderer = self.session.view.renderer['GenericRenderer']

		self.tooltip_instance = None # no weakref:
		# we need to remove the tooltip always anyway, and along with it the entry here
		self.tooltip_icon = Icon(position=(1,1)) # 0, 0 is currently not supported by tooltips

		AddStatusIcon.subscribe(self.on_add_icon_message)
		HoverInstancesChanged.subscribe(self.on_hover_instances_changed)
		RemoveStatusIcon.subscribe(self.on_remove_icon_message)
		WorldObjectDeleted.subscribe(self.on_worldobject_deleted_message)
Ejemplo n.º 22
0
def test_productivity_low(session, player):
    settlement, island = settle(session)

    Build(BUILDINGS.CHARCOAL_BURNER, 30, 30, island, settlement=settlement)(player)

    cb = mock.Mock()
    AddStatusIcon.subscribe(cb)

    # Not yet low
    assert not cb.called

    session.run(seconds=60)

    # Now low
    assert_called_with_icon(cb, ProductivityLowStatus)
Ejemplo n.º 23
0
def test_settler_unhappy(session, player):
	settlement, island = settle(session)

	cb = mock.Mock()
	AddStatusIcon.subscribe(cb)

	settler = Build(BUILDINGS.RESIDENTIAL, 30, 30, island, settlement=settlement)(player)

	# certainly not unhappy
	assert settler.happiness > 0.45
	assert not cb.called

	# make it unhappy
	settler.get_component(StorageComponent).inventory.alter(RES.HAPPINESS, -settler.happiness)
	assert settler.happiness < 0.1
	assert_called_with_icon(cb, SettlerUnhappyStatus)
Ejemplo n.º 24
0
def test_settler_unhappy(session, player):
    settlement, island = settle(session)

    cb = mock.Mock()
    AddStatusIcon.subscribe(cb)

    settler = Build(BUILDINGS.RESIDENTIAL, 30, 30, island, settlement=settlement)(player)

    # certainly not unhappy
    assert settler.happiness > 0.45
    assert not cb.called

    # make it unhappy
    settler.get_component(StorageComponent).inventory.alter(RES.HAPPINESS, -settler.happiness)
    assert settler.happiness < 0.1
    assert_called_with_icon(cb, SettlerUnhappyStatus)
Ejemplo n.º 25
0
	def _check_main_square_in_range(self):
		"""Notifies the user via a message in case there is no main square in range"""
		if not self.owner.is_local_player:
			return # only check this for local player
		for building in self.get_buildings_in_range():
			if building.id == BUILDINGS.MAIN_SQUARE:
				if StaticPather.get_path_on_roads(self.island, self, building) is not None:
					# a main square is in range
					if hasattr(self, "_main_square_status_icon"):
						RemoveStatusIcon.broadcast(self, self, SettlerNotConnectedStatus)
						del self._main_square_status_icon
					return
		if not hasattr(self, "_main_square_status_icon"):
			self._main_square_status_icon = SettlerNotConnectedStatus(self) # save ref for removal later
			AddStatusIcon.broadcast(self, self._main_square_status_icon)
		# no main square found
		# check_duplicate: only trigger once for different settlers of a neighborhood
		self.session.ingame_gui.message_widget.add(point=self.position.origin,
		                                           string_id='NO_MAIN_SQUARE_IN_RANGE', check_duplicate=True)
Ejemplo n.º 26
0
	def __init__(self, renderer, layer):
		"""
		@param renderer: Renderer used to render the icons
		@param layer: map layer, needed to place icon
		"""
		self.layer = layer
		self.renderer = renderer

		# {instance: [list of icons]}
		self.icons = {}

		self.tooltip_instance = None # no weakref:
		# we need to remove the tooltip always anyway, and along with it the entry here
		self.tooltip_icon = Icon(position=(1, 1)) # 0, 0 is currently not supported by tooltips

		AddStatusIcon.subscribe(self.on_add_icon_message)
		HoverInstancesChanged.subscribe(self.on_hover_instances_changed)
		RemoveStatusIcon.subscribe(self.on_remove_icon_message)
		WorldObjectDeleted.subscribe(self.on_worldobject_deleted_message)
Ejemplo n.º 27
0
def test_inventory_full(session, player):
    settlement, island = settle(session)

    lj = Build(BUILDINGS.LUMBERJACK, 30, 30, island, settlement=settlement)(player)

    cb = mock.Mock()
    AddStatusIcon.subscribe(cb)

    # Not full
    assert not cb.called

    inv = lj.get_component(StorageComponent).inventory
    res = RES.BOARDS
    inv.alter(res, inv.get_free_space_for(res))

    session.run(seconds=1)

    # Full
    assert_called_with_icon(cb, InventoryFullStatus)
Ejemplo n.º 28
0
def test_inventory_full(session, player):
	settlement, island = settle(session)

	lj = Build(BUILDINGS.LUMBERJACK, 30, 30, island, settlement=settlement)(player)

	cb = mock.Mock()
	AddStatusIcon.subscribe(cb)

	# Not full
	assert not cb.called

	inv = lj.get_component(StorageComponent).inventory
	res = RES.BOARDS
	inv.alter(res, inv.get_free_space_for( res ) )

	session.run(seconds=1)

	# Full
	assert_called_with_icon(cb, InventoryFullStatus)
Ejemplo n.º 29
0
	def _check_main_square_in_range(self):
		"""Notifies the user via a message in case there is no main square in range"""
		if not self.owner.is_local_player:
			return # only check this for local player
		for building in self.get_buildings_in_range():
			if building.id == BUILDINGS.MAIN_SQUARE:
				if StaticPather.get_path_on_roads(self.island, self, building) is not None:
					# a main square is in range
					if hasattr(self, "_main_square_status_icon"):
						RemoveStatusIcon.broadcast(self, self, SettlerNotConnectedStatus)
						del self._main_square_status_icon
					return
		if not hasattr(self, "_main_square_status_icon"):
			self._main_square_status_icon = SettlerNotConnectedStatus(self) # save ref for removal later
			AddStatusIcon.broadcast(self, self._main_square_status_icon)
		# no main square found
		# check_duplicate: only trigger once for different settlers of a neighborhood
		self.session.ingame_gui.message_widget.add(point=self.position.origin,
		                                           string_id='NO_MAIN_SQUARE_IN_RANGE', check_duplicate=True)
Ejemplo n.º 30
0
 def _add_status_icon(self, icon):
     if not self.__removal_started:
         AddStatusIcon.broadcast(self, icon)
Ejemplo n.º 31
0
def test_addstatusicon_queue_emptied(session, player):
    AddStatusIcon.clear()

    assert not AddStatusIcon.queue_len()
def test_addstatusicon_queue_emptied(session, player):
	AddStatusIcon.clear()

	assert not AddStatusIcon.queue_len()
Ejemplo n.º 33
0
	def _add_status_icon(self, icon):
		if not self.__removal_started:
			AddStatusIcon.broadcast(self, icon)