Example #1
0
	def refresh(self):
		super(PlayersShips, self).refresh()
		player = self.session.world.player
		self._clear_entries()
		#xgettext:python-format
		self._gui.findChild(name='headline').text = _("Ships of {player}").format(player=self.session.world.player.name)

		sequence_number = 0
		events = {}
		for ship in sorted(self.session.world.ships, key = lambda ship: (ship.get_component(NamedComponent).name, ship.worldid)):
			if ship.owner is player and ship.has_component(SelectableComponent):
				sequence_number += 1
				name_label, rename_icon, status_label, status_position = \
				          self._add_line_to_gui(ship, sequence_number)
				events['%s/mouseClicked' % name_label.name] = Callback(self._go_to_ship, ship)
				cb = Callback(self.session.ingame_gui.show_change_name_dialog, ship)
				events['%s/mouseClicked' % rename_icon.name] = cb
				events['%s/mouseClicked' % status_label.name] = Callback(self._go_to_point, status_position)
		self._gui.mapEvents(events)
		self._content_vbox.adaptLayout()
Example #2
0
    def _setup_state_callbacks(self):
        self.combatIntermissions = {
            self.missionStates.sailing_to_target:
            (self.sail_to_target, self.flee_home),
            self.missionStates.chasing_ship: (self.chase_ship, self.flee_home),
            self.missionStates.going_home: (self.go_home, self.flee_home),
            self.missionStates.fleeing_home: (self.flee_home, self.flee_home),
        }

        self._state_fleet_callbacks = {
            self.missionStates.sailing_to_target:
            Callback(self.go_home),
            self.missionStates.chasing_ship:
            Callback(self.chase_ship),
            self.missionStates.going_home:
            Callback(self.report_success, "Pirate routine ended successfully"),
            self.missionStates.fleeing_home:
            Callback(self.report_failure,
                     "Mission was a failure, ships fled home successfully"),
        }
Example #3
0
 def _build_interface(self):
     button_container = self.widget.findChild(name='button_container')
     sec_button_container = self.widget.findChild(
         name='sec_button_container')
     for i, action in enumerate(self.actions):
         button = self._create_button(action, i)
         sec_button = self._create_button(action, i)
         button.mapEvents({
             button.name + '/mouseClicked':
             Callback(self._detect_click_on_button, button, 1)
         })
         sec_button.mapEvents({
             button.name + '/mouseClicked':
             Callback(self._detect_click_on_button, sec_button, 2)
         })
         button_container.addChild(button)
         sec_button_container.addChild(sec_button)
         self.buttons.append(button)
         self.secondary_buttons.append(sec_button)
     self.update_buttons_text()
Example #4
0
    def __init__(self, windows, settlement):
        StatsWidget.__init__(self, settlement.session, center_widget=True)
        Window.__init__(self, windows)

        self.current_page = 0
        self.settlement = settlement
        self.db = self.settlement.session.db
        Scheduler().add_new_object(Callback(self._refresh_tick),
                                   self,
                                   run_in=GAME_SPEED.TICKS_PER_SECOND,
                                   loops=-1)
Example #5
0
    def build_groundunit_info(self, index, groundunit, prodline):
        size = (260, 90)
        widget = Container(name='showcase_%s' % index,
                           position=(0, 20 + index * 90),
                           min_size=size,
                           max_size=size,
                           size=size)
        bg_icon = Icon(image='content/gui/images/background/square_80.png',
                       name='bg_%s' % index)
        widget.addChild(bg_icon)

        image = 'content/gui/images/objects/groundunit/76/{unit_id}.png'.format(
            unit_id=groundunit)
        helptext = self.instance.session.db.get_unit_tooltip(groundunit)
        unit_icon = Icon(image=image,
                         name='icon_%s' % index,
                         position=(2, 2),
                         helptext=helptext)
        widget.addChild(unit_icon)

        # if not buildable, this returns string with reason why to be displayed as helptext
        #groundunit_unbuildable = self.is_groundunit_unbuildable(groundunit)
        groundunit_unbuildable = False
        if not groundunit_unbuildable:
            button = OkButton(position=(60, 50),
                              name='ok_%s' % index,
                              helptext=T('Build this groundunit!'))
            button.capture(Callback(self.start_production, prodline))
        else:
            button = CancelButton(position=(60, 50),
                                  name='ok_%s' % index,
                                  helptext=groundunit_unbuildable)

        widget.addChild(button)

        # Get production line info
        production = self.producer.create_production_line(prodline)
        # consumed == negative, reverse to sort in *ascending* order:
        costs = sorted(production.consumed_res.iteritems(), key=itemgetter(1))
        for i, (res, amount) in enumerate(costs):
            xoffset = 103 + (i % 2) * 55
            yoffset = 20 + (i // 2) * 20
            icon = create_resource_icon(res, self.instance.session.db)
            icon.max_size = icon.min_size = icon.size = (16, 16)
            icon.position = (xoffset, yoffset)
            label = Label(name='cost_%s_%s' % (index, i))
            if res == RES.GOLD:
                label.text = unicode(-amount)
            else:
                label.text = u'{amount:02}t'.format(amount=-amount)
            label.position = (22 + xoffset, yoffset)
            widget.addChild(icon)
            widget.addChild(label)
        return widget
Example #6
0
	def load_ship_states(self, db):
		# load ships one by one from db (ship instances themselves are loaded already, but
		# we have to use them here)
		for ship_id, state_id, remaining_ticks, targeted_warehouse in \
				db("SELECT rowid, state, remaining_ticks, targeted_warehouse FROM trader_ships"):
			state = self.shipStates[state_id]
			ship = WorldObject.get_object_by_id(ship_id)

			self.ships[ship] = state

			if state == self.shipStates.moving_random:
				ship.add_move_callback(Callback(self.ship_idle, ship))
			elif state == self.shipStates.moving_to_warehouse:
				ship.add_move_callback(Callback(self.reached_warehouse, ship))
				assert targeted_warehouse is not None
				self.office[ship.worldid] = WorldObject.get_object_by_id(targeted_warehouse)
			elif state == self.shipStates.reached_warehouse:
				assert remaining_ticks is not None
				Scheduler().add_new_object(
					Callback(self.ship_idle, ship), self, remaining_ticks)
Example #7
0
    def refresh(self):
        events = {
            # show rename when you click on name
            'name':
            Callback(self.instance.session.ingame_gui.show_change_name_dialog,
                     self.instance),
            'configure_route/mouseClicked':
            Callback(self._configure_route),
            'discard_res/mouseClicked':
            Callback(self._discard_resources)
        }

        self._refresh_found_settlement_button(events)
        self._refresh_trade_button(events)
        self.widget.mapEvents(events)

        self.widget.child_finder('inventory').update()
        self._refresh_combat()
        self._refresh_discard_resources()
        super(ShipOverviewTab, self).refresh()
Example #8
0
	def __init(self, ships, destroy_callback=None):
		self.owner = ships[0].owner

		# dictionary of ship => state
		self._ships = WeakKeyDictionary()
		for ship in ships:
			self._ships[ship] = self.shipStates.idle
			#TODO: @below, this caused errors on one occasion but I was not able to reproduce it.
			ship.add_remove_listener(Callback(self._lost_ship, ship))
		self.state = self.fleetStates.idle
		self.destroy_callback = destroy_callback
Example #9
0
    def ship_idle(self, ship):
        """Called if a ship is idle. Sends ship to either a random place or warehouse.
		Probability for 'random warehouse' in percent: TRADER.BUSINESS_SENSE.
		@param ship: ship instance"""
        if self.session.random.randint(0, 100) < TRADER.BUSINESS_SENSE:
            # delay one tick, to allow old movement calls to completely finish
            self.log.debug(
                "Trader %s ship %s: idle, moving to random warehouse",
                self.worldid, ship.worldid)
            Scheduler().add_new_object(Callback(
                self.send_ship_random_warehouse, ship),
                                       self,
                                       run_in=0)
        else:
            self.log.debug(
                "Trader %s ship %s: idle, moving to random location",
                self.worldid, ship.worldid)
            Scheduler().add_new_object(Callback(self.send_ship_random, ship),
                                       self,
                                       run_in=0)
    def __init(self, target_ship):
        self.target_ship = target_ship

        self.combatIntermissions = {
            self.missionStates.sailing_to_target:
            (self.sail_to_target, self.flee_home),
            self.missionStates.in_combat:
            (self.check_ship_alive, self.flee_home),
            self.missionStates.fleeing_home: (self.flee_home, self.flee_home),
        }

        self._state_fleet_callbacks = {
            self.missionStates.sailing_to_target:
            Callback(self.was_reached),
            self.missionStates.fleeing_home:
            Callback(self.report_failure,
                     "Combat was lost, ships fled home successfully"),
        }

        ShipDestroyed.subscribe(self._on_ship_destroyed)
	def _schedule_refresh(self):
		"""Schedule a refresh soon, dropping all other refresh request, that appear until then.
		This saves a lot of CPU time, if you have a huge island, or play on high speed."""
		if not self._refresh_scheduled:
			self._refresh_scheduled = True
			def unset_flag():
				# set the flag here and not in refresh() since we can't be sure whether
				# refresh() of this class will be reached or a subclass will not call super()
				self._refresh_scheduled = False
			ExtScheduler().add_new_object(Callback.ChainedCallbacks(unset_flag, self.refresh),
			                              self, run_in=self.__class__.scheduled_update_delay)
Example #12
0
    def __init(self, target_point, starting_point):
        self.target_point = target_point
        self.starting_point = starting_point

        self.combatIntermissions = {
            self.missionStates.sailing_to_target:
            (self.sail_to_target, self.flee_home),
            self.missionStates.going_back: (self.go_back, self.flee_home),
            self.missionStates.fleeing_home: (self.flee_home, self.flee_home),
        }

        self._state_fleet_callbacks = {
            self.missionStates.sailing_to_target:
            Callback(self.go_back),
            self.missionStates.going_back:
            Callback(self.report_success, "Ships arrived at the target"),
            self.missionStates.fleeing_home:
            Callback(self.report_failure,
                     "Combat was lost, ships fled home successfully"),
        }
Example #13
0
	def __init__(self, world_editor, ingame_gui):
		super(SettingsTab, self).__init__(widget=self.widget)

		self._world_editor = world_editor

		# Brush size
		for i in range(1, 6):
			b = self.widget.findChild(name='size_%d' % i)
			b.capture(Callback(self._change_brush_size, i))

		# Activate radio button for default brush size
		self._change_brush_size(self._world_editor.brush_size)

		# Tile selection
		for tile_type in ('default_land', 'sand', 'shallow_water', 'water'):
			image = self.widget.findChild(name=tile_type)
			tile = getattr(GROUND, tile_type.upper())
			image.up_image = self._get_tile_image(tile)
			image.size = image.min_size = image.max_size = (64, 32)
			image.capture(Callback(ingame_gui.set_cursor, 'tile_layer', tile))
Example #14
0
 def tick(self):
     Scheduler().add_new_object(Callback(self.tick),
                                self,
                                run_in=self.tick_interval)
     self.settlement_founder.tick()
     self.handle_enemy_expansions()
     self.handle_settlements()
     self.special_domestic_trade_manager.tick()
     self.international_trade_manager.tick()
     self.unit_manager.tick()
     self.combat_manager.tick()
Example #15
0
 def show(self):
     run_in = PLAYER.STATS_UPDATE_FREQUENCY / GAME_SPEED.TICKS_PER_SECOND
     ExtScheduler().add_new_object(Callback(self._refresh_tick),
                                   self,
                                   run_in=run_in,
                                   loops=-1)
     if not self._initialised:
         self._initialised = True
         self._init_gui()
     self.refresh()
     self._gui.show()
Example #16
0
    def load_attacks(cls, session, db):
        """
		Loads ongoing attacks from savegame database
		Creates scheduled calls for on_impact
		"""
        for (ticks, weapon_id, damage, dx, dy) in db(
                "SELECT remaining_ticks, weapon_id, damage, dest_x, dest_y FROM attacks"
        ):
            Scheduler().add_new_object(
                Callback(Weapon.on_impact, session, weapon_id, damage,
                         Point(dx, dy)), Weapon, ticks)
Example #17
0
 def __init__(self, instances, show_number=True):
     self.instances = instances
     self.widget = load_uh_widget("unit_entry_widget.xml")
     # get the icon of the first instance
     self.widget.findChild(
         name="unit_button").up_image = self.get_thumbnail_icon(
             instances[0].id)
     if show_number:
         self.widget.findChild(name="instance_number").text = unicode(
             len(self.instances))
     # only two callbacks are needed so drop unwanted changelistener inheritance
     for i in instances:
         if not i.has_remove_listener(Callback(self.on_instance_removed,
                                               i)):
             i.add_remove_listener(Callback(self.on_instance_removed, i))
         health_component = i.get_component(HealthComponent)
         if not health_component.has_damage_dealt_listener(
                 self.draw_health):
             health_component.add_damage_dealt_listener(self.draw_health)
     self.draw_health()
    def on_instance_removed(self, instance):
        self.instances.remove(instance)
        instance.discard_remove_listener(
            Callback(self.on_instance_removed, instance))
        health_component = instance.get_component(HealthComponent)
        if health_component.has_damage_dealt_listener(self.draw_health):
            health_component.remove_damage_dealt_listener(self.draw_health)

        if self.instances:
            self.widget.findChild(name="instance_number").text = unicode(
                len(self.instances))
 def refresh(self):
     self.widget.child_finder(
         'headline').text = self.settlement.get_component(
             NamedComponent).name
     events = {
         'headline':
         Callback(self.instance.session.ingame_gui.show_change_name_dialog,
                  self.settlement)
     }
     self.widget.mapEvents(events)
     super(MainSquareOverviewTab, self).refresh()
Example #20
0
    def fire(self, destination, position, bullet_delay=0):
        """
		Fires the weapon at a certain destination
		@param destination: Point with position where weapon will be fired
		@param position: position where the weapon is fired from
		@param bullet_delay:
		"""
        self.log.debug("%s fire; ready: %s", self, self.attack_ready)
        if not self.attack_ready:
            return

        distance = round(position.distance(destination.center))
        if not self.check_target_in_range(distance):
            self.log.debug("%s target not in range", self)
            return

        #calculate the ticks until impact
        impact_ticks = int(GAME_SPEED.TICKS_PER_SECOND * distance /
                           self.attack_speed)
        #deal damage when attack reaches target
        Scheduler().add_new_object(
            Callback(Weapon.on_impact, self.session, self.weapon_id,
                     self.get_damage_modifier(), destination), Weapon,
            impact_ticks)

        #calculate the ticks until attack is ready again
        ready_ticks = int(GAME_SPEED.TICKS_PER_SECOND * self.cooldown_time)
        Scheduler().add_new_object(self.make_attack_ready, self, ready_ticks)

        if self.bullet_image:
            Scheduler().add_new_object(Callback(Bullet, self.bullet_image,
                                                position, destination,
                                                impact_ticks - bullet_delay,
                                                self.session),
                                       self,
                                       run_in=bullet_delay)
        self.log.debug("fired %s at %s, impact in %s", self, destination,
                       impact_ticks - bullet_delay)

        self.attack_ready = False
        self.on_weapon_fired()
    def _on_resource_produced(self, message):
        """This is called by the message bus with ResourceProduced messages"""
        assert isinstance(message, ResourceProduced)

        # if we get an empty dictionary, abort
        if (not message.produced_resources or not message.produced_resources.keys()) or \
         not message.caller.instance.owner.is_local_player:
            return

        # makes the animation independent from game speed
        cur_ticks_per_second = Scheduler().timer.ticks_per_second
        interval = None
        if cur_ticks_per_second > GAME_SPEED.TICKS_PER_SECOND:
            interval = (cur_ticks_per_second //
                        GAME_SPEED.TICKS_PER_SECOND) - 1

        display_latency = 1
        for resource_item in message.produced_resources.items():
            res = resource_item[0]  # TODO multiple resources
            amount = message.sender.get_component(
                StorageComponent).inventory[res]

            # abort if amount is zero
            if not amount:
                continue

            group = self.get_resource_string(message.sender, res)
            self.run[group] = self.animation_steps

            tick_callback = Callback(self.__render_icon, message.sender, group,
                                     res, amount)
            finish_callback = Callback(self.remove_icon, group)

            Scheduler().add_new_object(tick_callback,
                                       self,
                                       finish_callback=finish_callback,
                                       run_in=display_latency,
                                       loops=self.animation_duration,
                                       loop_interval=interval)
            display_latency += (self.animation_duration * display_latency) * (
                interval if interval else 1)
    def add_weapon_to_storage(self, weapon_id):
        """
		adds weapon to storage
		@param weapon_id : id of the weapon to be added
		"""
        self.log.debug("%s add weapon %s", self, weapon_id)
        #if weapon is stackable, try to stack
        weapon = None
        if self.equipped_weapon_number == self.total_number_of_weapons:
            self.log.debug("%s weapon storage full", self)
            return False
        if self.session.db.get_weapon_stackable(weapon_id):
            stackable = [
                w for w in self._weapon_storage if weapon_id == w.weapon_id
            ]
            #try to increase the number of weapons for one stackable weapon
            increased = False
            for weapon in stackable:
                try:
                    weapon.increase_number_of_weapons(1)
                    increased = True
                    break
                except SetStackableWeaponNumberError:
                    continue

            if not increased:
                weapon = StackableWeapon(self.session, weapon_id)
        else:
            weapon = Weapon(self.session, weapon_id)
        if weapon:
            self._weapon_storage.append(weapon)
            weapon.add_weapon_fired_listener(
                Callback(self._remove_from_fireable, weapon))
            weapon.add_attack_ready_listener(
                Callback(self._add_to_fireable, weapon))
            weapon.add_weapon_fired_listener(
                self._increase_fired_weapons_number)
            self._fireable.append(weapon)
            self.equipped_weapon_number += 1
        self.on_storage_modified()  # will update the range
        return True
Example #23
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)
    def prepare(self):
        if self._mode == 'load':
            self._map_files, self._map_file_display = SavegameManager.get_saves(
            )
            if not self._map_files:
                self._windows.open_popup(
                    T("No saved games"),
                    T("There are no saved games to load."))
                return False
        elif self._mode == 'save':
            self._map_files, self._map_file_display = SavegameManager.get_regular_saves(
            )
        elif self._mode == 'editor-save':
            self._map_files, self._map_file_display = SavegameManager.get_maps(
            )

        self._gui.distributeInitialData(
            {'savegamelist': self._map_file_display})
        if self._mode == 'load':
            self._gui.distributeData({'savegamelist': 0})

        self._cb = self._create_show_savegame_details(self._gui,
                                                      self._map_files,
                                                      'savegamelist')
        if self._mode in ('save', 'editor-save'):

            def selected_changed():
                """Fills in the name of the savegame in the textbox when selected in the list"""
                if self._gui.collectData(
                        'savegamelist'
                ) == -1:  # set blank if nothing is selected
                    self._gui.findChild(name="savegamefile").text = u""
                else:
                    savegamefile = self._map_file_display[
                        self._gui.collectData('savegamelist')]
                    self._gui.distributeData({'savegamefile': savegamefile})

            self._cb = Callback.ChainedCallbacks(self._cb, selected_changed)

        self._cb()  # Refresh data on start
        self._gui.mapEvents({'savegamelist/action': self._cb})
        self._gui.findChild(name="savegamelist").capture(
            self._cb, event_name="keyPressed")
        self._gui.findChild(name="savegamelist").capture(
            self.check_double_click, event_name="mousePressed")

        self.return_events = {
            OkButton.DEFAULT_NAME: True,
            CancelButton.DEFAULT_NAME: False,
            DeleteButton.DEFAULT_NAME: 'delete'
        }
        if self._mode in ('save', 'editor-save'):
            self.return_events['savegamefile'] = True
Example #25
0
 def apply_new_key(newkey=None):
     if not newkey:
         newkey = free_keys[listbox.selected]
     else:
         listbox.selected = listbox.items.index(newkey)
     self.keyconf.save_new_key(action, newkey=newkey)
     update_hotkey_info(action, newkey)
     lbl.text = self.HELPSTRING_LAYOUT.format(text=lbl.explanation,
                                              key=newkey)
     lbl.capture(
         Callback(self.show_hotkey_change_popup, action, lbl, newkey))
     lbl.adaptLayout()
Example #26
0
	def __init__(self, selected_instances=None):
		self.selected_instances = selected_instances or []

		# keep track of units that have stance
		self.stance_unit_number = 0
		# keep local track of selected instances
		self.instances = []
		# keep track of number of instances per type
		self.type_number = defaultdict(int)

		for i in self.selected_instances:
			if hasattr(i, 'stance'):
				self.stance_unit_number += 1
			self.instances.append(i)
			if not i.has_remove_listener(Callback(self.on_instance_removed, i)):
				i.add_remove_listener(Callback(self.on_instance_removed, i))
			self.type_number[i.id] += 1

		self._scheduled_refresh = False

		super(SelectMultiTab, self).__init__()
Example #27
0
    def _initialize_mission(self):
        """
		Initializes mission after loading is finished.
		"""

        # Add move callback for fleet, dependent on loaded fleet state
        if self.state in self._state_fleet_callbacks:
            self.fleet.callback = self._state_fleet_callbacks[self.state]

        # Add destroy callback, the same for every case of fleet being destroyed
        self.fleet.destroy_callback = Callback(self.cancel,
                                               "All ships were destroyed")
Example #28
0
 def refresh(self):
     self.widget.findChild(
         name="headline").text = self.instance.settlement.get_component(
             NamedComponent).name
     events = {
         'headline':
         Callback(self.instance.session.ingame_gui.show_change_name_dialog,
                  self.instance.settlement)
     }
     self.widget.mapEvents(events)
     self._refresh_collector_utilization()
     super(WarehouseOverviewTab, self).refresh()
 def _create_build_buttons(self, building_id, container):
     # {{mode}} in double braces because it is replaced as a second step
     path = "content/gui/icons/buildmenu/{id:03d}{{mode}}.png".format(
         id=building_id)
     helptext = self.instance.session.db.get_building_tooltip(building_id)
     build_button = ImageButton(name="build{id}".format(id=building_id),
                                helptext=helptext)
     build_button.up_image = path.format(mode='')
     build_button.down_image = build_button.hover_image = path.format(
         mode='_h')
     build_button.capture(Callback(self.build_related, building_id))
     return build_button
Example #30
0
    def _load(self, db, worldid, success_callback, failure_callback):
        db_result = db(
            "SELECT settlement_manager, settlement, ship, bought_resource, sold_resource, state FROM ai_mission_international_trade WHERE rowid = ?",
            worldid)[0]
        self.settlement_manager = WorldObject.get_object_by_id(db_result[0])
        self.settlement = WorldObject.get_object_by_id(db_result[1])
        self.bought_resource = db_result[3]
        self.sold_resource = db_result[4]
        self.state = self.missionStates[db_result[5]]
        super(InternationalTrade,
              self).load(db, worldid, success_callback, failure_callback,
                         WorldObject.get_object_by_id(db_result[2]))

        if self.state is self.missionStates.moving_to_my_settlement:
            self.ship.add_move_callback(Callback(self._reached_my_settlement))
            self.ship.add_blocked_callback(
                Callback(self._move_to_my_settlement))
        elif self.state is self.missionStates.moving_to_other_settlement:
            self.ship.add_move_callback(
                Callback(self._reached_other_settlement))
            self.ship.add_blocked_callback(
                Callback(self._move_to_other_settlement))
        elif self.state is self.missionStates.returning_to_my_settlement:
            self.ship.add_move_callback(
                Callback(self._returned_to_my_settlement))
            self.ship.add_blocked_callback(
                Callback(self._return_to_my_settlement))
        else:
            assert False, 'invalid state'