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
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())
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
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
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)
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)
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)
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
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)
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)
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 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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
def _add_status_icon(self, icon): if not self.__removal_started: AddStatusIcon.broadcast(self, icon)
def test_addstatusicon_queue_emptied(session, player): AddStatusIcon.clear() assert not AddStatusIcon.queue_len()