示例#1
0
	def __init__(self, windows):
		Window.__init__(self, windows)
		PickBeltWidget.__init__(self)

		self._settings = horizons.globals.fife._setting

		self.widget.mapEvents({
			'okButton': self.apply_settings,
			'defaultButton': self.set_defaults,
			'cancelButton': self._windows.close,
		})

		languages = find_available_languages().keys()
		language_names = [LANGUAGENAMES[x] for x in sorted(languages)]

		fps = {0: _lazy("Disabled"), 30: 30, 45: 45, 60: 60, 90: 90, 120: 120}

		FIFE = SETTINGS.FIFE_MODULE
		UH = SETTINGS.UH_MODULE

		def get_resolutions():
			return get_screen_resolutions(self._settings.get(FIFE, 'ScreenResolution'))

		self._options = [
			# Graphics/Sound/Input
			Setting(FIFE, 'ScreenResolution', 'screen_resolution', get_resolutions, restart=True),
			Setting(FIFE, 'FullScreen', 'enable_fullscreen', restart=True),
			Setting(FIFE, 'FrameLimit', 'fps_rate', fps, restart=True, callback=self._on_FrameLimit_changed),

			Setting(UH, 'VolumeMusic', 'volume_music', callback=self._on_VolumeMusic_changed),
			Setting(UH, 'VolumeEffects', 'volume_effects', callback=self._on_VolumeEffects_changed),
			Setting(FIFE, 'PlaySounds', 'enable_sound', callback=self._on_PlaySounds_changed),
			Setting(UH, 'EdgeScrolling', 'edgescrolling'),
			Setting(UH, 'CursorCenteredZoom', 'cursor_centered_zoom'),
			Setting(UH, 'MiddleMousePan', 'middle_mouse_pan'),
			Setting(FIFE, 'MouseSensitivity', 'mousesensitivity', restart=True),

			# Game
			Setting(UH, 'AutosaveInterval', 'autosaveinterval'),
			Setting(UH, 'AutosaveMaxCount', 'autosavemaxcount'),
			Setting(UH, 'QuicksaveMaxCount', 'quicksavemaxcount'),
			Setting(UH, 'Language', 'uni_language', language_names, callback=self._on_Language_changed),

			Setting(UH, 'MinimapRotation', 'minimaprotation'),
			Setting(UH, 'UninterruptedBuilding', 'uninterrupted_building'),
			Setting(UH, 'AutoUnload', 'auto_unload'),
			Setting(UH, 'DebugLog', 'debug_log', callback=self._on_DebugLog_changed),
			Setting(UH, 'ShowResourceIcons', 'show_resource_icons'),
			Setting(UH, 'ScrollSpeed', 'scrollspeed'),
			Setting(UH, 'QuotesType', 'quotestype', QUOTES_SETTINGS),
			Setting(UH, 'NetworkPort', 'network_port', callback=self._on_NetworkPort_changed),
		]

		self._fill_widgets()

		# key configuration
		hk = HotkeyConfiguration()
		number = self.sections.index(('hotkeys_settings', _('Hotkeys')))
		self.page_widgets[number].addChild(hk.widget)
		self.hotkey_interface = hk
示例#2
0
    def __init__(self, windows):
        Window.__init__(self, windows)
        PickBeltWidget.__init__(self)

        self._settings = horizons.globals.fife._setting

        self.widget.mapEvents(
            {"okButton": self.apply_settings, "defaultButton": self.set_defaults, "cancelButton": self._windows.close}
        )

        languages = find_available_languages().keys()
        language_names = [LANGUAGENAMES[x] for x in sorted(languages)]

        fps = {0: _lazy("Disabled"), 30: 30, 45: 45, 60: 60, 90: 90, 120: 120}

        FIFE = SETTINGS.FIFE_MODULE
        UH = SETTINGS.UH_MODULE

        def get_resolutions():
            return get_screen_resolutions(self._settings.get(FIFE, "ScreenResolution"))

        self._options = [
            # Graphics/Sound/Input
            Setting(FIFE, "ScreenResolution", "screen_resolution", get_resolutions, restart=True),
            Setting(FIFE, "FullScreen", "enable_fullscreen", restart=True),
            Setting(FIFE, "FrameLimit", "fps_rate", fps, restart=True, callback=self._on_FrameLimit_changed),
            Setting(UH, "VolumeMusic", "volume_music", callback=self._on_VolumeMusic_changed),
            Setting(UH, "VolumeEffects", "volume_effects", callback=self._on_VolumeEffects_changed),
            Setting(FIFE, "PlaySounds", "enable_sound", callback=self._on_PlaySounds_changed),
            Setting(UH, "EdgeScrolling", "edgescrolling"),
            Setting(UH, "CursorCenteredZoom", "cursor_centered_zoom"),
            Setting(UH, "MiddleMousePan", "middle_mouse_pan"),
            Setting(FIFE, "MouseSensitivity", "mousesensitivity", restart=True),
            # Game
            Setting(UH, "AutosaveInterval", "autosaveinterval"),
            Setting(UH, "AutosaveMaxCount", "autosavemaxcount"),
            Setting(UH, "QuicksaveMaxCount", "quicksavemaxcount"),
            Setting(UH, "Language", "uni_language", language_names, callback=self._on_Language_changed),
            Setting(UH, "MinimapRotation", "minimaprotation"),
            Setting(UH, "UninterruptedBuilding", "uninterrupted_building"),
            Setting(UH, "AutoUnload", "auto_unload"),
            Setting(UH, "DebugLog", "debug_log", callback=self._on_DebugLog_changed),
            Setting(UH, "ShowResourceIcons", "show_resource_icons"),
            Setting(UH, "ScrollSpeed", "scrollspeed"),
            Setting(UH, "QuotesType", "quotestype", QUOTES_SETTINGS),
            Setting(UH, "NetworkPort", "network_port", callback=self._on_NetworkPort_changed),
        ]

        self._fill_widgets()

        # key configuration
        hk = HotkeyConfiguration()
        number = self.sections.index(("hotkeys_settings", _("Hotkeys")))
        self.page_widgets[number].addChild(hk.widget)
        self.hotkey_interface = hk
	def add_settings(self):
		#self.createAndAddEntry(module, name_in_settings_xml, widgetname,
		#                       applyfunction=None, initialdata=None, requiresrestart=False)
		uh_add = partial(self._setting.createAndAddEntry, UH_MODULE)
		fife_add = partial(self._setting.createAndAddEntry, FIFE_MODULE)

		uh_add("AutosaveInterval", "autosaveinterval")
		uh_add("AutosaveMaxCount", "autosavemaxcount")
		uh_add("QuicksaveMaxCount", "quicksavemaxcount")
		uh_add("EdgeScrolling", "edgescrolling")
		uh_add("CursorCenteredZoom", "cursor_centered_zoom")
		uh_add("ScrollSpeed", "scrollspeed")
		uh_add("MiddleMousePan", "middle_mouse_pan")
		uh_add("UninterruptedBuilding", "uninterrupted_building")
		uh_add("AutoUnload", "auto_unload")
		uh_add("MinimapRotation", "minimaprotation")
		uh_add("QuotesType", "quotestype", initialdata=QUOTES_SETTINGS)
		uh_add("ShowResourceIcons", "show_resource_icons")

		bpp = {0: _lazy("Default"), 16: _lazy("16 bit"), 32: _lazy("32 bit")}
		fife_add("BitsPerPixel", "screen_bpp", initialdata=bpp, requiresrestart=True)

		languages = find_available_languages().keys()
		uh_add("Language", "uni_language", applyfunction=self.update_languages,
		       initialdata=[LANGUAGENAMES[x] for x in sorted(languages)])

		uh_add("VolumeMusic", "volume_music", applyfunction=self.set_volume_music)
		uh_add("VolumeEffects", "volume_effects", applyfunction=self.set_volume_effects)
		uh_add("NetworkPort", "network_port", applyfunction=self.set_network_port)
		uh_add("DebugLog", "debug_log", applyfunction=self.set_debug_log)

		play_sounds = self._setting.entries[FIFE_MODULE]['PlaySounds']
		play_sounds.applyfunction = lambda x: self.engine.sound.setup_sound()
		play_sounds.requiresrestart = False  # This is set to True in FIFE

		render_backend = self._setting.entries[FIFE_MODULE]['RenderBackend']
		render_backend.applyfunction = lambda x: self._show_renderbackend_warning()

		fps = [30, 45, 60, 90, 120]
		fife_add("FrameLimit", "fps_rate", initialdata=fps, requiresrestart=True)

		fife_add("MouseSensitivity", "mousesensitivity", requiresrestart=True)
示例#4
0
    def _strip_translation_marks(self, string):
        """Converts object translation `string` to translated object for in-game display.

		Object properties supposed to be translated are recognized by the
		(subsequently stripped) leading `_ `.
		If `string` is supposed to be translated, returns lazy translation object of `string`.
		If `string` is not supposed to be translated, returns `string` unchanged.
		If `string` is None (not defined or empty in yaml), returns empty unicode.
		"""
        if not string:
            return u''
        if string.startswith("_ "):
            return _lazy(string[2:])
        else:
            return string
示例#5
0
	def _strip_translation_marks(self, string):
		"""Converts object translation `string` to translated object for in-game display.

		Object properties supposed to be translated are recognized by the
		(subsequently stripped) leading `_ `.
		If `string` is supposed to be translated, returns lazy translation object of `string`.
		If `string` is not supposed to be translated, returns `string` unchanged.
		If `string` is None (not defined or empty in yaml), returns empty unicode.
		"""
		if not string:
			return u''
		if string.startswith("_ "):
			return _lazy(string[2:])
		else:
			return string
class SmallProductionOverviewTab(ProductionOverviewTab):
    """Only display productions for which we have a related 'field' in range.
	Requires the building class using this tab to implement get_providers().
	"""
    widget = 'overview_farm.xml'
    helptext = _lazy("Production overview")
    production_line_gui_xml = "overview_farmproductionline.xml"

    # the farm uses small buttons
    ACTIVE_PRODUCTION_ANIM_DIR = "content/gui/images/animations/cogs/small"
    BUTTON_BACKGROUND = "content/gui/images/buttons/msg_button_small.png"

    def get_displayed_productions(self):
        possible_res = set(res for field in self.instance.get_providers()
                           for res in field.provided_resources)
        all_farm_productions = self.instance.get_component(
            Producer).get_productions()
        productions = set([
            p for p in all_farm_productions
            for res in p.get_consumed_resources().keys() if res in possible_res
        ])
        return sorted(productions,
                      key=operator.methodcaller('get_production_line_id'))
示例#7
0
class ShipOverviewTab(OverviewTab):
    widget = 'overview_trade_ship.xml'
    icon_path = 'icons/tabwidget/ship/ship_inv'
    helptext = _lazy("Ship overview")

    def init_widget(self):
        super(ShipOverviewTab, self).init_widget()
        ship_inv = self.instance.get_component(StorageComponent).inventory
        self.widget.child_finder('inventory').init(self.instance.session.db,
                                                   ship_inv)

        # FIXME having to access the WindowManager this way is pretty ugly
        self._windows = self.instance.session.ingame_gui.windows
        self.route_menu = RouteConfig(self._windows, self.instance)

    def _configure_route(self):
        self._windows.toggle(self.route_menu)

    def _refresh_found_settlement_button(self, events):
        island_without_player_settlement_found = False
        helptext = _(
            "The ship needs to be close to an island to found a settlement.")
        for island in self.instance.session.world.get_islands_in_radius(
                self.instance.position, self.instance.radius):
            if not any(settlement.owner.is_local_player
                       for settlement in island.settlements):
                island_without_player_settlement_found = True
            else:
                helptext = _("You already have a settlement on this island.")

        if island_without_player_settlement_found:
            events['found_settlement'] = Callback(
                self.instance.session.ingame_gui._build, BUILDINGS.WAREHOUSE,
                weakref.ref(self.instance))
            self.widget.child_finder('found_settlement_bg').set_active()
            self.widget.child_finder('found_settlement').set_active()
            self.widget.child_finder('found_settlement').helptext = _(
                "Build settlement")
        else:
            events['found_settlement'] = None
            self.widget.child_finder('found_settlement_bg').set_inactive()
            self.widget.child_finder('found_settlement').set_inactive()
            self.widget.child_finder('found_settlement').helptext = helptext

        cb = Callback(
            self.instance.session.ingame_gui.resource_overview.
            set_construction_mode, self.instance,
            Entities.buildings[BUILDINGS.WAREHOUSE].costs)
        events['found_settlement/mouseEntered'] = cb

        cb1 = Callback(self.instance.session.ingame_gui.resource_overview.
                       close_construction_mode)
        cb2 = Callback(
            self.widget.child_finder('found_settlement').hide_tooltip)
        #TODO the tooltip should actually hide on its own. Ticket #1096
        cb = Callback.ChainedCallbacks(cb1, cb2)
        events['found_settlement/mouseExited'] = cb

    def _refresh_trade_button(self, events):
        warehouses = self.instance.get_tradeable_warehouses()

        if warehouses:
            if warehouses[0].owner is self.instance.owner:
                helptext = _('Load/Unload')
            else:
                helptext = _('Buy/Sell')
            events['trade'] = Callback(
                self.instance.get_component(SelectableComponent).show_menu,
                TradeTab)
            self.widget.findChild(name='trade_bg').set_active()
            self.widget.findChild(name='trade').set_active()
            self.widget.findChild(name='trade').helptext = helptext
        else:
            events['trade'] = None
            self.widget.findChild(name='trade_bg').set_inactive()
            self.widget.findChild(name='trade').set_inactive()
            self.widget.findChild(name='trade').helptext = _(
                'Too far from the nearest tradeable warehouse')

    def _refresh_combat(self):  # no combat
        def click_on_cannons(button):
            button.button.capture(
                Callback(
                    self.instance.session.ingame_gui.show_popup,
                    _("Cannot equip trade ship with weapons"),
                    _("It is not possible to equip a trade ship with weapons.")
                ))

        self.widget.findChild(name='inventory').apply_to_buttons(
            click_on_cannons, lambda b: b.res_id == WEAPONS.CANNON)

    def refresh(self):
        # show rename when you click on name
        events = {
            'name':
            Callback(self.instance.session.ingame_gui.show_change_name_dialog,
                     self.instance),
            'configure_route/mouseClicked':
            Callback(self._configure_route)
        }

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

        self.widget.child_finder('inventory').update()
        self._refresh_combat()
        super(ShipOverviewTab, self).refresh()
示例#8
0
class TraderShipOverviewTab(OverviewTab):
    widget = 'overview_tradership.xml'
    icon_path = 'icons/tabwidget/ship/ship_inv'
    helptext = _lazy("Ship overview")
class BoatbuilderTab(UnitbuilderTabBase):
    widget = 'boatbuilder.xml'
    helptext = _lazy("Boat builder overview")

    UNIT_THUMBNAIL = "content/gui/icons/thumbnails/{type_id}.png"
    UNIT_PREVIEW_IMAGE = "content/gui/images/objects/ships/116/{type_id}.png"
import random

import horizons.globals
from horizons.constants import TIER
from horizons.i18n import _lazy
from horizons.gui.util import load_uh_widget
from horizons.gui.windows import Window
from horizons.messaging import LoadingProgress


# list of quotes and gameplay tips that are displayed while loading a game
# NOTE: Try to use not more than 4 lines in a quote/gameplay tip !

FUN_QUOTES = {
	'name': _lazy("Quotes"),
	# Fun Quotes should not be translated...
	'items': [
		"beer, the cause and solution to all problems of humanity",
		"trying is the first step t'wards failing. ",
		"# nobody actually knows how the code below works. ",
		"here be dragons",
		"procrastination is the first step towards getting stuff done",
		"patience is a virtue \n(barra)",
		"you must really, really love to test \n(portal 2)",
		"here be bugs",
		"strength is the capacity to break a chocolate bar into four pieces with your bare hands - and then eat just one of the pieces",
		"If one does not know to which port one is sailing, no wind is favorable",
		"The pessimist complains about the wind; \nthe optimist expects it to change; \nthe realist adjusts the sails",
		"Travel beyond the horizon and discover unknown worlds!",
		u"War… war never changes",
示例#11
0
class BuildRelatedTab(OverviewTab):
    """
	Adds a special tab to each production building with at least one entry in
	the table related_buildings. This tab acts as modified build menu tab and
	only displays those buildings actually related to the selected building.
	Examples: tree for lumberjack; pavilion, school, etc. for inhabitants.
	"""
    widget = 'related_buildings.xml'
    icon_path = 'icons/tabwidget/production/related'
    helptext = _lazy("Build related buildings")
    template_gui_xml = 'related_buildings_container.xml'

    def refresh(self):
        """
		This function is called by the TabWidget to redraw the widget.
		"""
        # remove old data
        parent_container = self.widget.child_finder('related_buildings')
        while parent_container.children:
            parent_container.removeChild(parent_container.children[0])

        # load all related buildings from DB
        building_ids = self.instance.session.db.get_related_building_ids_for_menu(
            self.instance.id)
        sorted_ids = sorted([(b, Entities.buildings[b].settler_level)
                             for b in building_ids],
                            key=lambda x: x[1])
        container = self.__get_new_container()
        self.current_row = min(building[1] for building in sorted_ids)
        for building_id, level in sorted_ids:
            if level <= self.instance.owner.settler_level:  # available in build menu?
                button = self._create_build_buttons(building_id, container)
                # check whether to start new line (for new tier row)
                if level > self.current_row:
                    self.current_row = level
                    parent_container.addChild(container)
                    container = self.__get_new_container()
                container.findChild(
                    name="build_button_container").addChild(button)
                button_bg = Icon(
                    image="content/gui/images/buttons/buildmenu_button_bg.png")
                container.findChild(
                    name="build_button_bg_container").addChild(button_bg)
        # Still need to add last container
        parent_container.addChild(container)
        super(BuildRelatedTab, self).refresh()

    def __get_new_container(self):
        """
		Loads a background container xml file. Returns the loaded widget.
		"""
        gui = load_uh_widget(self.template_gui_xml)
        return gui.findChild(name="buildings_container")

    def _create_build_buttons(self, building_id, container):
        # {{mode}} in double braces because it is replaced as a second step
        building_type = Entities.buildings[building_id]
        build_button = ImageButton(name="build{id}".format(id=building_id),
                                   helptext=building_type.get_tooltip())
        build_button.path = "icons/buildmenu/{id:03d}".format(id=building_id)
        build_button.capture(Callback(self.build_related, building_id))
        return build_button

    def build_related(self, building_id):
        self.hide()
        # deselect all
        for instance in self.instance.session.selected_instances:
            instance.get_component(SelectableComponent).deselect()
        self.instance.session.selected_instances.clear()

        self.instance.session.ingame_gui.set_cursor(
            'building',
            Entities.buildings[building_id],
            ship=None,
            build_related=self.instance)
示例#12
0
class ProductivityLowStatus(StatusIcon):
    """Terminology: productivity = capacity utilization"""
    threshold = 0.25  # display when productivity lower than this
    priority = 400
    icon = 'as_attention_please+idle+45'
    helptext = _lazy("This building has a very low productivity.")
示例#13
0
class DecommissionedStatus(StatusIcon):
    priority = 800
    icon = 'as_decommissioned+idle+45'
    helptext = _lazy("This building is decomissioned.")
示例#14
0
class SettingsDialog(PickBeltWidget, Window):
    """Widget for Options dialog with pickbelt style pages"""

    widget_xml = 'settings.xml'
    sections = (('graphics_settings', _lazy('Graphics')),
                ('hotkeys_settings', _lazy('Hotkeys')), ('game_settings',
                                                         _lazy('Game')))

    def __init__(self, windows):
        Window.__init__(self, windows)
        PickBeltWidget.__init__(self)

        self._settings = horizons.globals.fife._setting

        self.widget.mapEvents({
            'okButton': self.apply_settings,
            'defaultButton': self.set_defaults,
            'cancelButton': self._windows.close,
        })

        languages = find_available_languages().keys()
        language_names = [LANGUAGENAMES[x] for x in sorted(languages)]

        fps = {0: _lazy("Disabled"), 30: 30, 45: 45, 60: 60, 90: 90, 120: 120}

        FIFE = SETTINGS.FIFE_MODULE
        UH = SETTINGS.UH_MODULE

        def get_resolutions():
            return get_screen_resolutions(
                self._settings.get(FIFE, 'ScreenResolution'))

        self._options = [
            # Graphics/Sound/Input
            Setting(FIFE,
                    'ScreenResolution',
                    'screen_resolution',
                    get_resolutions,
                    restart=True),
            Setting(FIFE, 'FullScreen', 'enable_fullscreen', restart=True),
            Setting(FIFE,
                    'FrameLimit',
                    'fps_rate',
                    fps,
                    restart=True,
                    callback=self._on_FrameLimit_changed),
            Setting(UH,
                    'VolumeMusic',
                    'volume_music',
                    callback=self._on_VolumeMusic_changed),
            Setting(UH,
                    'VolumeEffects',
                    'volume_effects',
                    callback=self._on_VolumeEffects_changed),
            Setting(FIFE,
                    'PlaySounds',
                    'enable_sound',
                    callback=self._on_PlaySounds_changed),
            Setting(UH, 'EdgeScrolling', 'edgescrolling'),
            Setting(UH, 'CursorCenteredZoom', 'cursor_centered_zoom'),
            Setting(UH, 'MiddleMousePan', 'middle_mouse_pan'),
            Setting(FIFE, 'MouseSensitivity', 'mousesensitivity',
                    restart=True),

            # Game
            Setting(UH, 'AutosaveInterval', 'autosaveinterval'),
            Setting(UH, 'AutosaveMaxCount', 'autosavemaxcount'),
            Setting(UH, 'QuicksaveMaxCount', 'quicksavemaxcount'),
            Setting(UH,
                    'Language',
                    'uni_language',
                    language_names,
                    callback=self._on_Language_changed),
            Setting(UH, 'MinimapRotation', 'minimaprotation'),
            Setting(UH, 'UninterruptedBuilding', 'uninterrupted_building'),
            Setting(UH, 'AutoUnload', 'auto_unload'),
            Setting(UH,
                    'DebugLog',
                    'debug_log',
                    callback=self._on_DebugLog_changed),
            Setting(UH, 'ShowResourceIcons', 'show_resource_icons'),
            Setting(UH, 'ScrollSpeed', 'scrollspeed'),
            Setting(UH, 'QuotesType', 'quotestype', QUOTES_SETTINGS),
            Setting(UH,
                    'NetworkPort',
                    'network_port',
                    callback=self._on_NetworkPort_changed),
        ]

        self._fill_widgets()

        # key configuration
        hk = HotkeyConfiguration()
        number = self.sections.index(('hotkeys_settings', _('Hotkeys')))
        self.page_widgets[number].addChild(hk.widget)
        self.hotkey_interface = hk

    def show(self):
        self.widget.show()

    def hide(self):
        self.widget.hide()

    def show_restart_popup(self):
        headline = _("Restart required")
        message = _(
            "Some of your changes require a restart of Unknown Horizons.")
        self._windows.open_popup(headline, message)

    def set_defaults(self):
        title = _("Restore default settings")
        msg = _("Restoring the default settings will delete all changes to the settings you made so far.") + \
          u" " + _("Do you want to continue?")

        if self._windows.open_popup(title, msg, show_cancel_button=True):
            self.hotkey_interface.reset_to_default()
            self._settings.set_defaults()
            self.show_restart_popup()
            self._windows.close()

    def apply_settings(self):
        restart_required = False

        for entry in self._options:
            widget = self.widget.findChild(name=entry.widget_name)
            new_value = widget.getData()

            if isinstance(entry.initial_data, collections.Callable):
                initial_data = entry.initial_data()
            else:
                initial_data = entry.initial_data

            if isinstance(initial_data, list):
                new_value = initial_data[new_value]
            elif isinstance(initial_data, dict):
                new_value = initial_data.keys()[new_value]

            old_value = self._settings.get(entry.module, entry.name)

            # Store new setting
            self._settings.set(entry.module, entry.name, new_value)

            # If setting changed, allow applying of new value and sanity checks
            if new_value != old_value:
                if entry.restart:
                    restart_required = True

                if entry.callback:
                    entry.callback(old_value, new_value)

        if restart_required:
            self.show_restart_popup()

        self.hotkey_interface.save_settings()
        self._settings.apply()
        self._settings.save()
        self._windows.close()

    def _fill_widgets(self):
        for entry in self._options:
            value = self._settings.get(entry.module, entry.name)
            widget = self.widget.findChild(name=entry.widget_name)

            if entry.initial_data:
                if isinstance(entry.initial_data, collections.Callable):
                    initial_data = entry.initial_data()
                else:
                    initial_data = entry.initial_data

                if isinstance(initial_data, dict):
                    widget.setInitialData(initial_data.values())
                    value = initial_data.keys().index(value)
                elif isinstance(initial_data, list):
                    widget.setInitialData(initial_data)
                    value = initial_data.index(value)
                else:
                    widget.setInitialData(initial_data)

            widget.setData(value)

            # For sliders, there also is a label showing the current value
            if isinstance(widget, horizons.globals.fife.pychan.widgets.Slider):
                cb = Callback(self.slider_change, widget)
                cb()
                widget.capture(cb)

    def slider_change(self, widget):
        """Callback for updating value label of a slider after dragging it.

		As the numeric values under the hood often do not represent mental
		models of what the setting achieves very well, depending on the
		setting in question we display a modified value, sometimes with
		a '%' suffix."""
        value_label = self.widget.findChild(name=widget.name + '_value')
        value = {
            'volume_music': lambda x: u'%s%%' % int(500 * x),
            'volume_effects': lambda x: u'%s%%' % int(200 * x),
            'mousesensitivity': lambda x: u'%+.1f%%' % (200 * x),
            'autosaveinterval': lambda x: u'%d' % x,
            'autosavemaxcount': lambda x: u'%d' % x,
            'quicksavemaxcount': lambda x: u'%d' % x,
            'scrollspeed': lambda x: u'%.1f' % x,
        }[widget.name](widget.value)
        value_label.text = value

    # callbacks for changes of settings

    def _on_PlaySounds_changed(self, old, new):
        horizons.globals.fife.sound.setup_sound()

    def _on_VolumeMusic_changed(self, old, new):
        horizons.globals.fife.sound.set_volume_bgmusic(new)

    def _on_VolumeEffects_changed(self, old, new):
        horizons.globals.fife.sound.set_volume_effects(new)

    def _on_FrameLimit_changed(self, old, new):
        # handling value 0 for framelimit to disable limiter
        if new == 0:
            self._settings.set(SETTINGS.FIFE_MODULE, 'FrameLimitEnabled',
                               False)
        else:
            self._settings.set(SETTINGS.FIFE_MODULE, 'FrameLimitEnabled', True)

    def _on_NetworkPort_changed(self, old, new):
        """Sets a new value for client network port"""
        # port is saved as string due to pychan limitations
        try:
            # 0 is not a valid port, but a valid value here (used for default)
            parse_port(new)
        except ValueError:
            headline = _("Invalid network port")
            descr = _(
                "The port you specified is not valid. It must be a number between 1 and 65535."
            )
            advice = _(
                "Please check the port you entered and make sure it is in the specified range."
            )
            self._windows.open_error_popup(headline, descr, advice)
            # reset value and reshow settings dlg
            self._settings.set(SETTINGS.UH_MODULE, 'NetworkPort', u"0")
        else:
            # port is valid
            try:
                if NetworkInterface() is None:
                    NetworkInterface.create_instance()
                NetworkInterface().network_data_changed()
            except Exception as e:
                headline = _("Failed to apply new network settings.")
                descr = _(
                    "Network features could not be initialized with the current configuration."
                )
                advice = _(
                    "Check the settings you specified in the network section.")
                if 0 < parse_port(new) < 1024:
                    #i18n This is advice for players seeing a network error with the current config
                    advice += u" " + \
                     _("Low port numbers sometimes require special access privileges, try 0 or a number greater than 1024.")
                details = unicode(e)
                self._windows.open_error_popup(headline, descr, advice,
                                               details)

    def _on_Language_changed(self, old, new):
        language = LANGUAGENAMES.get_by_value(new)
        change_language(language)

    def _on_DebugLog_changed(self, old, new):
        horizons.main.set_debug_log(new)
示例#15
0
    def __init__(self, windows):
        Window.__init__(self, windows)
        PickBeltWidget.__init__(self)

        self._settings = horizons.globals.fife._setting

        self.widget.mapEvents({
            'okButton': self.apply_settings,
            'defaultButton': self.set_defaults,
            'cancelButton': self._windows.close,
        })

        languages = find_available_languages().keys()
        language_names = [LANGUAGENAMES[x] for x in sorted(languages)]

        fps = {0: _lazy("Disabled"), 30: 30, 45: 45, 60: 60, 90: 90, 120: 120}

        FIFE = SETTINGS.FIFE_MODULE
        UH = SETTINGS.UH_MODULE

        def get_resolutions():
            return get_screen_resolutions(
                self._settings.get(FIFE, 'ScreenResolution'))

        self._options = [
            # Graphics/Sound/Input
            Setting(FIFE,
                    'ScreenResolution',
                    'screen_resolution',
                    get_resolutions,
                    restart=True),
            Setting(FIFE, 'FullScreen', 'enable_fullscreen', restart=True),
            Setting(FIFE,
                    'FrameLimit',
                    'fps_rate',
                    fps,
                    restart=True,
                    callback=self._on_FrameLimit_changed),
            Setting(UH,
                    'VolumeMusic',
                    'volume_music',
                    callback=self._on_VolumeMusic_changed),
            Setting(UH,
                    'VolumeEffects',
                    'volume_effects',
                    callback=self._on_VolumeEffects_changed),
            Setting(FIFE,
                    'PlaySounds',
                    'enable_sound',
                    callback=self._on_PlaySounds_changed),
            Setting(UH, 'EdgeScrolling', 'edgescrolling'),
            Setting(UH, 'CursorCenteredZoom', 'cursor_centered_zoom'),
            Setting(UH, 'MiddleMousePan', 'middle_mouse_pan'),
            Setting(FIFE, 'MouseSensitivity', 'mousesensitivity',
                    restart=True),

            # Game
            Setting(UH, 'AutosaveInterval', 'autosaveinterval'),
            Setting(UH, 'AutosaveMaxCount', 'autosavemaxcount'),
            Setting(UH, 'QuicksaveMaxCount', 'quicksavemaxcount'),
            Setting(UH,
                    'Language',
                    'uni_language',
                    language_names,
                    callback=self._on_Language_changed),
            Setting(UH, 'MinimapRotation', 'minimaprotation'),
            Setting(UH, 'UninterruptedBuilding', 'uninterrupted_building'),
            Setting(UH, 'AutoUnload', 'auto_unload'),
            Setting(UH,
                    'DebugLog',
                    'debug_log',
                    callback=self._on_DebugLog_changed),
            Setting(UH, 'ShowResourceIcons', 'show_resource_icons'),
            Setting(UH, 'ScrollSpeed', 'scrollspeed'),
            Setting(UH, 'QuotesType', 'quotestype', QUOTES_SETTINGS),
            Setting(UH,
                    'NetworkPort',
                    'network_port',
                    callback=self._on_NetworkPort_changed),
        ]

        self._fill_widgets()

        # key configuration
        hk = HotkeyConfiguration()
        number = self.sections.index(('hotkeys_settings', _('Hotkeys')))
        self.page_widgets[number].addChild(hk.widget)
        self.hotkey_interface = hk
class AccountTab(MainSquareTab):
    """Display basic income and expenses of a settlement"""
    widget = 'tab_account.xml'
    icon_path = 'icons/tabwidget/warehouse/account'
    helptext = _lazy("Account")

    def init_widget(self):
        super(AccountTab, self).init_widget()
        self.widget.mapEvents({
            'show_production_overview/mouseClicked':
            self.show_production_overview,
        })

        # FIXME having to access the WindowManager this way is pretty ugly
        self._windows = self.instance.session.ingame_gui.windows
        self.prod_overview = ProductionOverview(self._windows, self.settlement)

        self.widget.child_finder(
            'headline').text = self.settlement.get_component(
                NamedComponent).name
        self.widget.child_finder('headline').helptext = _(
            'Click to change the name of your settlement')

        path = 'icons/widgets/cityinfo/settlement_%s' % self.settlement.owner.color.name
        self.widget.child_finder('show_production_overview').path = path

    def show_production_overview(self):
        self._windows.toggle(self.prod_overview)

    def refresh(self):
        super(AccountTab, self).refresh()
        self.refresh_collector_utilization()
        taxes = self.settlement.cumulative_taxes
        running_costs = self.settlement.cumulative_running_costs
        buy_expenses = self.settlement.get_component(
            TradePostComponent).buy_expenses
        sell_income = self.settlement.get_component(
            TradePostComponent).sell_income
        balance = self.settlement.balance
        sign = '+' if balance >= 0 else '-'
        self.widget.child_finder('taxes').text = unicode(taxes)
        self.widget.child_finder('running_costs').text = unicode(running_costs)
        self.widget.child_finder('buying').text = unicode(buy_expenses)
        self.widget.child_finder('sale').text = unicode(sell_income)
        self.widget.child_finder('balance').text = unicode(sign + ' ' +
                                                           str(abs(balance)))
        self.widget.child_finder(
            'headline').text = self.settlement.get_component(
                NamedComponent).name
        rename = Callback(
            self.instance.session.ingame_gui.show_change_name_dialog,
            self.settlement)
        self.widget.mapEvents({'headline': rename})

    def refresh_collector_utilization(self):
        if self.instance.has_component(CollectingComponent):
            utilization = int(
                round(self.instance.get_collector_utilization() * 100))
            utilization = unicode(utilization) + u'%'
        else:
            utilization = u'---'
        self.widget.findChild(name="collector_utilization").text = utilization
示例#17
0
class TradeTab(TabInterface):
    """Ship to trade post's trade tab. International as well as national trade."""
    log = logging.getLogger("gui.tabs.tradetab")

    widget = 'tradetab.xml'
    icon_path = 'icons/tabwidget/warehouse/buysell'
    helptext = _lazy('Trade')

    scheduled_update_delay = 0.3

    # map the size buttons in the gui to an amount
    exchange_size_buttons = {
        1: 'size_1',
        5: 'size_2',
        10: 'size_3',
        20: 'size_4',
        50: 'size_5',
    }

    images = {
        'box_highlighted': 'content/gui/icons/ship/smallbutton_a.png',
        'box': 'content/gui/icons/ship/smallbutton.png',
    }

    def __init__(self, instance):
        """
		@param instance: ship instance used for trading
		"""
        self.instance = instance
        super(TradeTab, self).__init__()

    def init_widget(self):
        events = {}
        for k, v in self.exchange_size_buttons.iteritems():
            events[v] = Callback(self.set_exchange, k)
        self.widget.mapEvents(events)
        self.partner = None
        self.exchange = None
        self.set_exchange(GUI.DEFAULT_EXCHANGE_AMOUNT, initial=True)

    def refresh(self):
        super(TradeTab, self).refresh()
        self.draw_widget()

    def draw_widget(self):
        self.widget.findChild(
            name='ship_name').text = self.instance.get_component(
                NamedComponent).name
        self.partners = self.instance.get_tradeable_warehouses()
        # set up gui dynamically according to partners
        # NOTE: init on inventories will be optimized away internally if it's only an update
        if self.partners:
            partner_label = self.widget.findChild(name='partners')
            nearest_partner = self.get_nearest_partner(self.partners)
            partner_label.text = self.partners[
                nearest_partner].settlement.get_component(NamedComponent).name

            new_partner = self.partners[nearest_partner]
            different_partner = new_partner is not self.partner
            if self.partner is not None and different_partner:
                self.__remove_changelisteners()
            self.partner = new_partner
            if different_partner:
                self.__add_changelisteners()

            is_own = self.partner.owner is self.instance.owner
            if not is_own:  # foreign warehouse => disable exchange widget, enable trade interface
                self.widget.findChild(name='domestic').hide()
                selling_inventory = self.widget.findChild(
                    name='selling_inventory')
                selling_inventory.init(
                    self.instance.session.db,
                    self.partner.get_component(StorageComponent).inventory,
                    self.partner.settlement.get_component(
                        TradePostComponent).sell_list,
                    selling=True)
                for button in self.get_widgets_by_class(
                        selling_inventory, ImageFillStatusButton):
                    button.button.capture(
                        Callback(self.transfer, button.res_id,
                                 self.partner.settlement, True))

                buying_inventory = self.widget.findChild(
                    name='buying_inventory')
                buying_inventory.init(
                    self.instance.session.db,
                    self.partner.get_component(StorageComponent).inventory,
                    self.partner.settlement.get_component(
                        TradePostComponent).buy_list,
                    selling=False)
                for button in self.get_widgets_by_class(
                        buying_inventory, ImageFillStatusButton):
                    button.button.capture(
                        Callback(self.transfer, button.res_id,
                                 self.partner.settlement, False))
                self.widget.findChild(name='international').show()
            else:  # own warehouse => enable exchange widget, disable trade interface
                self.widget.findChild(name='international').hide()
                inv_partner = self.widget.findChild(
                    name='inventory_partner')  # This is no BuySellInventory!
                inv_partner.init(
                    self.instance.session.db,
                    self.partner.get_component(StorageComponent).inventory)
                for button in self.get_widgets_by_class(
                        inv_partner, ImageFillStatusButton):
                    button.button.capture(
                        Callback(self.transfer, button.res_id,
                                 self.partner.settlement, self.instance))
                self.widget.findChild(name='domestic').show()

            inv = self.widget.findChild(name='inventory_ship')
            inv.init(self.instance.session.db,
                     self.instance.get_component(StorageComponent).inventory)
            for button in self.get_widgets_by_class(inv,
                                                    ImageFillStatusButton):
                button.button.capture(
                    Callback(self.transfer, button.res_id,
                             self.partner.settlement, False))
            self.widget.adaptLayout()
        else:
            # no partner in range any more
            pass

    def __remove_changelisteners(self):
        # never redraw on clicks immediately because of
        # http://github.com/fifengine/fifengine/issues/387
        # This way, there is a chance of clicks being noticed by pychan.
        # The cost is to delay all updates, which in this case is 0.3 sec, therefore deemed bearable.

        # need to be idempotent, show/hide calls it in arbitrary order
        if self.instance:
            self.instance.discard_change_listener(self._schedule_refresh)
            inv = self.instance.get_component(StorageComponent).inventory
            inv.discard_change_listener(self._schedule_refresh)
        if self.partner:
            inv = self.partner.get_component(StorageComponent).inventory
            inv.discard_change_listener(self._schedule_refresh)
            tradepost = self.partner.settlement.get_component(
                TradePostComponent)
            tradepost.discard_change_listener(self._schedule_refresh)

    def __add_changelisteners(self):
        # need to be idempotent, show/hide calls it in arbitrary order
        if self.instance:
            self.instance.add_change_listener(self._schedule_refresh,
                                              no_duplicates=True)
            inv = self.instance.get_component(StorageComponent).inventory
            inv.add_change_listener(self._schedule_refresh, no_duplicates=True)
        if self.partner:
            inv = self.partner.get_component(StorageComponent).inventory
            inv.add_change_listener(self._schedule_refresh, no_duplicates=True)
            tradepost = self.partner.settlement.get_component(
                TradePostComponent)
            tradepost.add_change_listener(self._schedule_refresh,
                                          no_duplicates=True)

    def hide(self):
        self.widget.hide()
        self.__remove_changelisteners()

    def show(self):
        self.widget.show()
        self.__add_changelisteners()
        self.refresh()

    def set_exchange(self, size, initial=False):
        """
		Highlight radio button with selected amount and deselect old highlighted.
		@param initial: bool, use it to set exchange size when initing the widget
		"""
        self.log.debug("Tradewidget: exchange size now: %s", size)
        if not initial:
            old_name = self.exchange_size_buttons[self.exchange]
            old_box = self.widget.findChild(name=old_name)
            old_box.up_image = self.images['box']

        self.exchange = size

        new_name = self.exchange_size_buttons[self.exchange]
        box_h = self.widget.findChild(name=new_name)
        box_h.up_image = self.images['box_highlighted']
        if not initial:
            self.draw_widget()

    def transfer(self, res_id, settlement, selling):
        """Buy or sell the resources"""
        if self.instance.position.distance(
                settlement.warehouse.position) <= self.instance.radius:
            is_own = settlement.owner is self.instance.owner
            if selling and not is_own:  # ship sells resources to settlement
                self.log.debug(
                    'InternationalTrade: %s/%s is selling %d of res %d to %s/%s',
                    self.instance.get_component(NamedComponent).name,
                    self.instance.owner.name, self.exchange, res_id,
                    settlement.get_component(NamedComponent).name,
                    settlement.owner.name)
                # international trading has own error handling, no signal_error
                SellResource(settlement.get_component(TradePostComponent),
                             self.instance, res_id,
                             self.exchange).execute(self.instance.session)
            elif selling and is_own:  # transfer from settlement to ship
                self.log.debug(
                    'Trade: Transferring %s of res %s from %s/%s to %s/%s',
                    self.exchange, res_id,
                    settlement.get_component(NamedComponent).name,
                    settlement.owner.name,
                    self.instance.get_component(NamedComponent).name,
                    self.instance.owner.name)
                TransferResource(self.exchange,
                                 res_id,
                                 settlement,
                                 self.instance,
                                 signal_errors=True).execute(
                                     self.instance.session)

            elif not selling and not is_own:  # ship buys resources from settlement
                self.log.debug(
                    'InternationalTrade: %s/%s is buying %d of res %d from %s/%s',
                    self.instance.get_component(NamedComponent).name,
                    self.instance.owner.name, self.exchange, res_id,
                    settlement.get_component(NamedComponent).name,
                    settlement.owner.name)
                # international trading has own error handling, no signal_error
                BuyResource(settlement.get_component(TradePostComponent),
                            self.instance, res_id,
                            self.exchange).execute(self.instance.session)
            elif not selling and is_own:  # transfer from ship to settlement
                self.log.debug(
                    'Trade: Transferring %s of res %s from %s/%s to %s/%s',
                    self.exchange, res_id,
                    self.instance.get_component(NamedComponent).name,
                    self.instance.owner.name,
                    settlement.get_component(NamedComponent).name,
                    settlement.owner.name)
                TransferResource(self.exchange,
                                 res_id,
                                 self.instance,
                                 settlement,
                                 signal_errors=True).execute(
                                     self.instance.session)
            # let gui update be handled by changelisteners (mp-safe)

    def get_widgets_by_class(self, parent_widget, widget_class):
        """Gets all widget of a certain widget class from the tab. (e.g. pychan.widgets.Label for all labels)"""
        children = []

        def _find_widget(widget):
            if isinstance(widget, widget_class):
                children.append(widget)

        parent_widget.deepApply(_find_widget)
        return children

    def get_nearest_partner(self, partners):
        nearest = None
        nearest_dist = None
        for partner in partners:
            dist = partner.position.distance(self.instance.position)
            if nearest_dist is None or dist < nearest_dist:
                nearest_dist = dist
                nearest = partners.index(partner)
        return nearest
import random

import horizons.globals
from horizons.constants import TIER
from horizons.i18n import _lazy
from horizons.gui.util import load_uh_widget
from horizons.gui.windows import Window
from horizons.messaging import LoadingProgress


# list of quotes and gameplay tips that are displayed while loading a game
# NOTE: Try to use not more than 4 lines in a quote/gameplay tip !

FUN_QUOTES = {
    "name": _lazy("Quotes"),
    # Fun Quotes should not be translated...
    "items": [
        "beer, the cause and solution to all problems of humanity",
        "trying is the first step t'wards failing. ",
        "# nobody actually knows how the code below works. ",
        "here be dragons",
        "procrastination is the first step towards getting stuff done",
        "patience is a virtue \n(barra)",
        "you must really, really love to test \n(portal 2)",
        "here be bugs",
        "strength is the capacity to break a chocolate bar into four pieces with your bare hands - and then eat just one of the pieces",
        "If one does not know to which port one is sailing, no wind is favorable",
        "The pessimist complains about the wind; \nthe optimist expects it to change; \nthe realist adjusts the sails",
        "Travel beyond the horizon and discover unknown worlds!",
        u"War… war never changes",
示例#19
0
import random

import horizons.globals
from horizons.constants import TIER
from horizons.i18n import _lazy
from horizons.gui.util import load_uh_widget
from horizons.gui.windows import Window
from horizons.messaging import LoadingProgress


# list of quotes and gameplay tips that are displayed while loading a game
# NOTE: Try to use not more than 4 lines in a quote/gameplay tip !

FUN_QUOTES = {
	'name': _lazy("Quotes"),
	# Fun Quotes should not be translated...
	'items': [
		"Beer, the cause and solution to all problems of humanity.",
		"Trying is the first step t'wards failing.",
		"# nobody actually knows how the code below works.",
		"Here are dragons.",
		"Procrastination is the first step towards getting stuff done.",
		"Patience is a virtue. \n(barra)",
		"You must really, really love to test. \n(portal 2)",
		"Here are bugs.",
		"Strength is the capacity to break a chocolate bar into four pieces with your bare hands - and then eat just one of the pieces.",
		"If one does not know to which port one is sailing, no wind is favorable.",
		"The pessimist complains about the wind; \nthe optimist expects it to change; \nthe realist adjusts the sails.",
		"Travel beyond the horizon and discover unknown worlds!",
		u"War… war never changes.",
示例#20
0
class PestilenceStatus(StatusIcon):
    priority = 2000
    icon = 'as_pestilence+idle+45'
    helptext = _lazy("The inhabitants of this building have the plague.")
class SelectMultiTab(TabInterface):
    """
	Tab shown when multiple units are selected
	"""
    widget = 'overview_select_multi.xml'
    icon_path = 'icons/tabwidget/common/inventory'
    helptext = _lazy("Selected Units")

    max_row_entry_number = 3
    max_column_entry_number = 4

    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__()

    def init_widget(self):
        if self.stance_unit_number != 0:
            self.show_stance_widget()

        self.draw_selected_units_widget()

    def add_entry(self, entry):
        if self.column_number > self.max_column_entry_number - 1:
            self.column_number = 0
            self.row_number += 1
        if self.row_number >= 3:
            # TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
            # This crashes when more than 2 rows are needed.
            # There just aren't any hboxes in the xml.
            # TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
            self.row_number = 2
            return
        self.column_number += 1
        self.widget.findChild(name="hbox_%s" % self.row_number).addChild(
            entry.widget)
        self.entries.append(entry)

    def draw_selected_units_widget(self):
        self.entries = []
        self.row_number = 0
        self.column_number = 0
        # if only one type of units is selected draw individual widgets for selected units
        if len(self.type_number) == 1:
            for instance in self.instances:
                self.add_entry(UnitEntry([instance], False))
        else:
            entry_instances = defaultdict(list)
            for instance in self.instances:
                entry_instances[instance.id].append(instance)
            for instances in entry_instances.values():
                self.add_entry(UnitEntry(instances))

    def hide_selected_units_widget(self):
        for entry in self.entries:
            entry.remove()
        for i in xrange(0, self.max_row_entry_number):
            self.widget.findChild(name="hbox_%s" % i).removeAllChildren()

    def schedule_unit_widget_refresh(self):
        if not self._scheduled_refresh:
            self._scheduled_refresh = True
            Scheduler().add_new_object(self.refresh_unit_widget,
                                       self,
                                       run_in=0)

    def refresh_unit_widget(self):
        if self.instances:
            self._scheduled_refresh = False
            self.hide_selected_units_widget()
            self.draw_selected_units_widget()
            self.toggle_stance()
            self.widget.adaptLayout()
        else:
            # all units were destroyed
            self.hide_selected_units_widget()

    def on_instance_removed(self, instance):
        if hasattr(instance, 'stance'):
            self.stance_unit_number -= 1

        self.instances.remove(instance)
        instance.discard_remove_listener(
            Callback(self.on_instance_removed, instance))

        if self.widget.isVisible():
            if len(self.instances) < 2:
                # hide the multi-selection tab
                instance.session.ingame_gui.hide_menu()
                # if one unit remains, show its menu
                if len(self.instances) == 1:
                    self.instances[0].get_component(
                        SelectableComponent).show_menu()
                return

        self.type_number[instance.id] -= 1
        if self.type_number[instance.id] == 0:
            del self.type_number[instance.id]
            # if one type of units dies, schedule refresh
            self.schedule_unit_widget_refresh()

        # if one type of units is left, any removal would mean refresh
        if len(self.type_number) == 1:
            self.schedule_unit_widget_refresh()

        if self.stance_unit_number == 0:
            self.hide_stance_widget()

    def show_stance_widget(self):
        stance_widget = load_uh_widget('stancewidget.xml')
        self.widget.findChild(name='stance').addChild(stance_widget)
        self.toggle_stance()
        events = dict(
            (i.NAME, Callback(self.set_stance, i)) for i in DEFAULT_STANCES)
        self.widget.mapEvents(events)

    def hide_stance_widget(self):
        Scheduler().rem_all_classinst_calls(self)
        self.widget.findChild(name='stance').removeAllChildren()

    def set_stance(self, stance):
        for i in self.instances:
            if hasattr(i, 'stance'):
                SetStance(i, stance).execute(i.session)
        self.toggle_stance()

    def toggle_stance(self):
        """
		Toggles the stance. Assumes at least one stance unit is selected.
		"""
        for stance in DEFAULT_STANCES:
            self.widget.findChild(name=stance.NAME).set_inactive()
        # get first unit stance
        stance_units = [u for u in self.instances if hasattr(u, "stance")]
        stance = stance_units[0].stance
        for unit in stance_units[1:]:
            if unit.stance != stance:
                # not all have the same stance, toggle none
                return
        self.widget.findChild(name=stance.NAME).set_active()
class BoatbuilderTab(_BoatbuilderOverviewTab):
    widget = 'boatbuilder.xml'
    helptext = _lazy("Boat builder overview")

    SHIP_THUMBNAIL = "content/gui/icons/thumbnails/{type_id}.png"
    SHIP_PREVIEW_IMG = "content/gui/images/objects/ships/116/{type_id}.png"

    def show(self):
        super(BoatbuilderTab, self).show()
        Scheduler().add_new_object(Callback(self.refresh),
                                   self,
                                   run_in=GAME_SPEED.TICKS_PER_SECOND,
                                   loops=-1)

    def hide(self):
        super(BoatbuilderTab, self).hide()
        Scheduler().rem_all_classinst_calls(self)

    def refresh(self):
        """This function is called by the TabWidget to redraw the widget."""
        super(BoatbuilderTab, self).refresh()

        main_container = self.widget.findChild(name="BB_main_tab")
        container_active = main_container.findChild(name="container_active")
        container_inactive = main_container.findChild(
            name="container_inactive")
        progress_container = main_container.findChild(
            name="BB_progress_container")
        cancel_container = main_container.findChild(name="BB_cancel_container")
        needed_res_container = self.widget.findChild(
            name="BB_needed_resources_container")

        # a boatbuilder is considered active here if it builds sth, no matter if it's paused
        production_lines = self.producer.get_production_lines()

        if production_lines:
            cancel_container.parent.showChild(cancel_container)

            # Set progress
            progress_container.parent.showChild(progress_container)
            progress = math.floor(self.producer.get_production_progress() *
                                  100)
            self.widget.findChild(name='progress').progress = progress
            progress_perc = self.widget.findChild(name='BB_progress_perc')
            progress_perc.text = u'{progress}%'.format(progress=progress)

            container_active.parent.showChild(container_active)
            if (Fife.getVersion() >= (0, 4, 0)):
                container_inactive.parent.hideChild(container_inactive)
            else:
                if not container_inactive in container_inactive.parent.hidden_children:
                    container_inactive.parent.hideChild(container_inactive)

            # Update boatbuilder queue
            queue = self.producer.get_unit_production_queue()
            queue_container = container_active.findChild(
                name="queue_container")
            queue_container.removeAllChildren()
            for place_in_queue, unit_type in enumerate(queue):
                image = self.__class__.SHIP_THUMBNAIL.format(type_id=unit_type)
                helptext = _("{ship} (place in queue: {place})").format(
                    ship=self.instance.session.db.get_unit_type_name(
                        unit_type),
                    place=place_in_queue + 1)
                # people don't count properly, always starting at 1..
                icon_name = "queue_elem_" + str(place_in_queue)
                icon = Icon(name=icon_name, image=image, helptext=helptext)
                rm_from_queue_cb = Callback(
                    RemoveFromQueue(self.producer, place_in_queue).execute,
                    self.instance.session)
                icon.capture(rm_from_queue_cb, event_name="mouseClicked")
                queue_container.addChild(icon)

            # Set built ship info
            production_line = self.producer._get_production(
                production_lines[0])
            produced_unit_id = production_line.get_produced_units().keys()[0]

            name = self.instance.session.db.get_unit_type_name(
                produced_unit_id)

            container_active.findChild(
                name="headline_BB_builtship_label").text = _(name)
            ship_icon = container_active.findChild(name="BB_cur_ship_icon")
            ship_icon.helptext = self.instance.session.db.get_ship_tooltip(
                produced_unit_id)
            ship_icon.image = self.__class__.SHIP_PREVIEW_IMG.format(
                type_id=produced_unit_id)

            button_active = container_active.findChild(
                name="toggle_active_active")
            button_inactive = container_active.findChild(
                name="toggle_active_inactive")
            to_active = not self.producer.is_active()

            if not to_active:  # swap what we want to show and hide
                button_active, button_inactive = button_inactive, button_active
            if (Fife.getVersion() >= (0, 4, 0)):
                button_active.parent.hideChild(button_active)
            else:
                if not button_active in button_active.parent.hidden_children:
                    button_active.parent.hideChild(button_active)
            button_inactive.parent.showChild(button_inactive)

            set_active_cb = Callback(self.producer.set_active,
                                     active=to_active)
            button_inactive.capture(set_active_cb, event_name="mouseClicked")

            upgrades_box = container_active.findChild(name="BB_upgrades_box")
            upgrades_box.removeAllChildren()

            # Update needed resources
            production = self.producer.get_productions()[0]
            needed_res = production.get_consumed_resources()
            # Now sort! -amount is the positive value, drop unnecessary res (amount 0)
            needed_res = dict((res, -amount)
                              for res, amount in needed_res.iteritems()
                              if amount < 0)
            needed_res = sorted(needed_res.iteritems(),
                                key=itemgetter(1),
                                reverse=True)
            needed_res_container.removeAllChildren()
            for i, (res, amount) in enumerate(needed_res):
                icon = create_resource_icon(res, self.instance.session.db)
                icon.max_size = icon.min_size = icon.size = (16, 16)
                label = Label(name="needed_res_lbl_%s" % i)
                label.text = u'{amount}t'.format(amount=amount)
                new_hbox = HBox(name="needed_res_box_%s" % i)
                new_hbox.addChildren(icon, label)
                needed_res_container.addChild(new_hbox)

            cancel_button = self.widget.findChild(name="BB_cancel_button")
            cancel_cb = Callback(
                CancelCurrentProduction(self.producer).execute,
                self.instance.session)
            cancel_button.capture(cancel_cb, event_name="mouseClicked")

        else:  # display sth when nothing is produced
            container_inactive.parent.showChild(container_inactive)
            for w in (container_active, progress_container, cancel_container):
                if (Fife.getVersion() >= (0, 4, 0)):
                    w.parent.hideChild(w)
                else:
                    if not w in w.parent.hidden_children:
                        w.parent.hideChild(w)

        self.widget.adaptLayout()
import random

import horizons.globals
from horizons.constants import TIER
from horizons.i18n import _lazy
from horizons.gui.util import load_uh_widget
from horizons.gui.windows import Window
from horizons.messaging import LoadingProgress


# list of quotes and gameplay tips that are displayed while loading a game
# NOTE: Try to use not more than 4 lines in a quote/gameplay tip !

FUN_QUOTES = {
	'name': _lazy("Quotes"),
	# Fun Quotes should not be translated...
	'items': [
		"beer, the cause and solution to all problems of humanity",
		"trying is the first step t'wards failing. ",
		"# nobody actually knows how the code below works. ",
		"here be dragons",
		"procrastination is the first step towards getting stuff done",
		"patience is a virtue \n(barra)",
		"you must really, really love to test \n(portal 2)",
		"here be bugs",
		"strength is the capacity to break a chocolate bar into four pieces with your bare hands - and then eat just one of the pieces",
		"If one does not know to which port one is sailing, no wind is favorable",
		"The pessimist complains about the wind; \nthe optimist expects it to change; \nthe realist adjusts the sails",
		"Travel beyond the horizon and discover unknown worlds!",
		u"War… war never changes",
示例#24
0
class GroundUnitOverviewTab(OverviewTab):
    widget = 'overview_war_groundunit.xml'
    helptext = _lazy("Groundunit overview")

    def init_widget(self):
        super(GroundUnitOverviewTab, self).init_widget()
class ProductionOverviewTab(OverviewTab):
    widget = 'overview_productionbuilding.xml'
    helptext = _lazy("Production overview")
    production_line_gui_xml = 'overview_productionline.xml'

    ACTIVE_PRODUCTION_ANIM_DIR = "content/gui/images/animations/cogs/large"
    BUTTON_BACKGROUND = "content/gui/images/buttons/msg_button.png"
    ARROW_TOP = "content/gui/icons/templates/production/production_arrow_top.png"
    ARROW_MID = "content/gui/icons/templates/production/production_arrow_start.png"
    ARROW_BOTTOM = "content/gui/icons/templates/production/production_arrow_bottom.png"
    ARROW_CONNECT_UP = "content/gui/icons/templates/production/production_arrow_connect_up.png"
    ARROW_CONNECT_DOWN = "content/gui/icons/templates/production/production_arrow_connect_down.png"

    def __init__(self, instance):
        self._animations = []
        super(ProductionOverviewTab, self).__init__(instance=instance)

    def get_displayed_productions(self):
        """List all possible productions of a buildings sorted by production line id.
		Overwritten in some child classes (e.g. farm tab).
		"""
        productions = self.instance.get_component(Producer).get_productions()
        return sorted(productions,
                      key=operator.methodcaller('get_production_line_id'))

    def refresh(self):
        """This function is called by the TabWidget to redraw the widget."""
        self._refresh_utilization()

        # remove old production line data
        parent_container = self.widget.child_finder('production_lines')
        while parent_container.children:
            child = parent_container.children[-1]
            if hasattr(child, "anim"):
                child.anim.stop()
                del child.anim
            parent_container.removeChild(child)

        # create a container for each production
        # sort by production line id to have a consistent (basically arbitrary) order
        for production in self.get_displayed_productions():
            # we need to be notified of small production changes
            # that aren't passed through the instance
            production.add_change_listener(self._schedule_refresh,
                                           no_duplicates=True)

            gui = load_uh_widget(self.production_line_gui_xml)
            # fill in values to gui reflecting the current game state
            container = gui.findChild(name="production_line_container")
            self._set_resource_amounts(container, production)

            centered_container = container.findChild(
                name='centered_production_icons')
            self._connect_input_res(centered_container, container, production)

            if production.is_paused():
                centered_container.removeChild(
                    centered_container.findChild(name="toggle_active_active"))
                toggle_icon = centered_container.findChild(
                    name="toggle_active_inactive")
                toggle_icon.name = "toggle_active"
            else:
                centered_container.removeChild(
                    centered_container.findChild(
                        name="toggle_active_inactive"))
                toggle_icon = centered_container.findChild(
                    name="toggle_active_active")
                toggle_icon.name = "toggle_active"

                if production.get_state() == PRODUCTION.STATES.producing:
                    bg = Icon(image=self.__class__.BUTTON_BACKGROUND)
                    bg.position = toggle_icon.position
                    centered_container.addChild(bg)
                    centered_container.removeChild(
                        toggle_icon)  # fix z-ordering
                    centered_container.addChild(toggle_icon)
                    anim = PychanAnimation(
                        toggle_icon, self.__class__.ACTIVE_PRODUCTION_ANIM_DIR)
                    centered_container.anim = anim
                    anim.start(1.0 / 12,
                               -1)  # always start anew, people won't notice
                    self._animations.append(weakref.ref(anim))

            # fill it with input and output resources
            in_res_container = container.findChild(name="input_res")
            self._add_resource_icons(in_res_container,
                                     production.get_consumed_resources(),
                                     marker=True)
            out_res_container = container.findChild(name="output_res")
            self._add_resource_icons(out_res_container,
                                     production.get_produced_resources())

            # active toggle_active button
            toggle_active = ToggleActive(self.instance.get_component(Producer),
                                         production)
            centered_container.mapEvents({
                'toggle_active':
                Callback(toggle_active.execute, self.instance.session)
            })
            # NOTE: this command causes a refresh, so we needn't change the toggle_active-button-image
            parent_container.addChild(container)
        super(ProductionOverviewTab, self).refresh()

    def _connect_input_res(self, centered_container, container, production):
        """Draws incoming arrows for production line container."""
        input_amount = len(production.get_consumed_resources())
        if input_amount == 0:
            # Do not draw input arrows if there is no input
            return

        # center the production line
        icon_height = ImageFillStatusButton.CELL_SIZE[
            1] + ImageFillStatusButton.PADDING
        center_y = (icon_height // 2) * (input_amount - 1)
        centered_container.position = (0, center_y)

        if input_amount % 2:
            # Add center arrow for 1, 3, 5, ... but not 2, 4, ...
            mid_arrow = Icon(image=self.__class__.ARROW_MID)
            mid_arrow.position = (58, 17 + center_y)
            container.insertChild(mid_arrow, 0)

        for res in xrange(input_amount // 2):
            # --\                      <= placed for res = 1
            # --\| <= place connector  <= placed for res = 0
            # ---O-->                  <= placed above (mid_arrow)
            # --/| <= place connector  <= placed for res = 0
            # --/                      <= placed for res = 1
            offset = -17 + (icon_height // 2) * (2 * res +
                                                 (input_amount % 2) + 1)

            top_arrow = Icon(image=self.__class__.ARROW_TOP)
            top_arrow.position = (58, center_y - offset)
            container.insertChild(top_arrow, 0)

            bottom_arrow = Icon(image=self.__class__.ARROW_BOTTOM)
            bottom_arrow.position = (58, center_y + offset)
            container.insertChild(bottom_arrow, 0)

            # Place a connector image (the | in above sketch) that vertically connects
            # the input resource arrows. We need those if the production line has more
            # than three input resources. Connectors are placed in the inner loop parts.
            place_connectors = (1 + 2 * res) < (input_amount // 2)
            if place_connectors:
                # the connector downwards connects top_arrows
                down_connector = Icon(image=self.__class__.ARROW_CONNECT_DOWN)
                down_connector.position = (98, center_y - offset)
                container.insertChild(down_connector, 0)
                # the connector upwards connects up_arrows
                up_connector = Icon(image=self.__class__.ARROW_CONNECT_UP)
                up_connector.position = (98, center_y + offset)
                container.insertChild(up_connector, 0)

    def _set_resource_amounts(self, container, production):
        for res, amount in production.get_consumed_resources().iteritems():
            # consumed resources are negative!
            label = Label(text=unicode(-amount), margins=(0, 15))
            container.findChild(name='input_box').addChild(label)

        for res, amount in production.get_produced_resources().iteritems():
            label = Label(text=unicode(amount).rjust(2), margins=(0, 15))
            container.findChild(name='output_box').addChild(label)

    def destruct_building(self):
        self.instance.session.ingame_gui.hide_menu()
        Tear(self.instance).execute(self.instance.session)

    def _refresh_utilization(self):
        utilization = 0
        if self.instance.has_component(Producer):
            utilization = int(
                round(
                    self.instance.get_component(Producer).capacity_utilization
                    * 100))
        self.widget.child_finder(
            'capacity_utilization').text = unicode(utilization) + u'%'

    def _add_resource_icons(self, container, resources, marker=False):
        calculate_position = lambda amount: (amount * 100
                                             ) // inventory.get_limit(res)
        for res in resources:
            inventory = self.instance.get_component(StorageComponent).inventory
            filled = calculate_position(inventory[res])
            marker_level = calculate_position(-resources[res]) if marker else 0
            image_button = ImageFillStatusButton.init_for_res(
                self.instance.session.db,
                res,
                inventory[res],
                filled,
                marker=marker_level,
                use_inactive_icon=False,
                uncached=True)
            container.addChild(image_button)

    def show(self):
        super(ProductionOverviewTab, self).show()
        Scheduler().add_new_object(Callback(self._refresh_utilization),
                                   self,
                                   run_in=GAME_SPEED.TICKS_PER_SECOND,
                                   loops=-1)

    def hide(self):
        super(ProductionOverviewTab, self).hide()
        self._cleanup()

    def on_instance_removed(self):
        self._cleanup()
        super(ProductionOverviewTab, self).on_instance_removed()

    def _cleanup(self):
        Scheduler().rem_all_classinst_calls(self)
        for production in self.get_displayed_productions():
            production.discard_change_listener(self._schedule_refresh)
        for anim in self._animations:
            if anim():
                anim().stop()
        self._animations = []
示例#26
0
class SettlerOverviewTab(OverviewTab):
    widget = 'overview_settler.xml'
    helptext = _lazy("Settler overview")

    def init_widget(self):
        super(SettlerOverviewTab, self).init_widget()
        name = self.instance.settlement.get_component(NamedComponent).name
        self.widget.findChild(name="headline").text = name
        setup_tax_slider(self.widget.child_finder('tax_slider'),
                         self.widget.child_finder('tax_val_label'),
                         self.instance.settlement, self.instance.level)

        taxes = self.instance.settlement.tax_settings[self.instance.level]
        self.widget.child_finder('tax_val_label').text = unicode(taxes)
        action_set = ActionSetLoader.get_sets()[self.instance._action_set_id]
        action_gfx = action_set.items()[0][1]
        image = action_gfx[45].keys()[0]
        self.widget.findChild(name="building_image").image = image

    def on_settler_level_change(self, message):
        assert isinstance(message, SettlerUpdate)
        setup_tax_slider(self.widget.child_finder('tax_slider'),
                         self.widget.child_finder('tax_val_label'),
                         self.instance.settlement, message.level)
        taxes = self.instance.settlement.tax_settings[self.instance.level]
        self.widget.child_finder('tax_val_label').text = unicode(taxes)
        imgs = ActionSetLoader.get_sets()[
            self.instance._action_set_id].items()[0][1]
        self.widget.findChild(name="building_image").image = imgs[45].keys()[0]

    def show(self):
        super(SettlerOverviewTab, self).show()
        SettlerUpdate.subscribe(self.on_settler_level_change,
                                sender=self.instance)

    def hide(self):
        SettlerUpdate.discard(self.on_settler_level_change,
                              sender=self.instance)
        super(SettlerOverviewTab, self).hide()

    def refresh(self):
        image, helptext = get_happiness_icon_and_helptext(
            self.instance.happiness, self.instance.session)
        self.widget.child_finder('happiness_label').image = image
        self.widget.child_finder('happiness_label').helptext = helptext
        self.widget.child_finder(
            'happiness').progress = self.instance.happiness
        self.widget.child_finder('inhabitants').text = u"%s/%s" % (
            self.instance.inhabitants, self.instance.inhabitants_max)
        self.widget.child_finder('taxes').text = unicode(
            self.instance.last_tax_payed)
        self.update_consumed_res()
        name = self.instance.settlement.get_component(NamedComponent).name
        self.widget.findChild(name="headline").text = name
        events = {
            'headline':
            Callback(self.instance.session.ingame_gui.show_change_name_dialog,
                     self.instance.settlement)
        }
        self.widget.mapEvents(events)
        super(SettlerOverviewTab, self).refresh()

    def update_consumed_res(self):
        """Updates the container that displays the needed resources of the settler"""
        container = self.widget.findChild(name="needed_res")
        # remove icons from the container
        container.removeAllChildren()

        # create new ones
        resources = self.instance.get_currently_not_consumed_resources()
        for res in resources:
            icon = create_resource_icon(res, self.instance.session.db)
            icon.max_size = icon.min_size = icon.size = (32, 32)
            container.addChild(icon)

        container.adaptLayout()
示例#27
0
class FireStatusIcon(StatusIcon):
    """ Fire disaster """
    priority = 3000
    icon = 'as_on_fire+idle+45'
    helptext = _lazy("This building is on fire!")
示例#28
0
class SettlerNotConnectedStatus(StatusIcon):
    # threshold is the inhabitants decrease level
    priority = 1700
    icon = 'as_mainsquare_access+idle+45'
    helptext = _lazy("These residents don't have access to a main square.")
示例#29
0
class OverviewTab(TabInterface):
    widget = 'overviewtab.xml'
    icon_path = 'icons/tabwidget/common/building_overview'
    helptext = _lazy("Overview")

    has_stance = False

    def __init__(self, instance, widget=None, icon_path=None):
        self.instance = instance
        super(OverviewTab, self).__init__(widget=widget, icon_path=icon_path)

    def init_widget(self):
        # set player emblem
        if self.widget.child_finder('player_emblem'):
            if self.instance.owner is not None:
                player_color = self.instance.owner.color.name
            else:
                player_color = 'no_player'
            emblem = 'content/gui/images/tabwidget/emblems/emblem_%s.png'
            self.widget.child_finder(
                'player_emblem').image = emblem % player_color

        if self.__class__.has_stance:
            self.init_stance_widget()

    def refresh(self):
        if (hasattr(self.instance, 'name')
                or self.instance.has_component(NamedComponent)
            ) and self.widget.child_finder('name'):
            name_widget = self.widget.child_finder('name')
            # Named objects can't be translated.
            if self.instance.has_component(NamedComponent):
                name_widget.text = self.instance.get_component(
                    NamedComponent).name
            else:
                name_widget.text = _(self.instance.name)

        if hasattr(self.instance, 'running_costs') and \
           self.widget.child_finder('running_costs'):
            self.widget.child_finder('running_costs').text = \
                unicode(self.instance.running_costs)

        self.widget.adaptLayout()

    def show(self):
        super(OverviewTab, self).show()
        if not self.instance.has_change_listener(self.refresh):
            self.instance.add_change_listener(self.refresh)
        if not self.instance.has_remove_listener(self.on_instance_removed):
            self.instance.add_remove_listener(self.on_instance_removed)
        if hasattr(self.instance, 'settlement') and \
           self.instance.settlement is not None and \
           not self.instance.settlement.has_change_listener(self._schedule_refresh):
            # listen for settlement name changes displayed as tab headlines
            self.instance.settlement.add_change_listener(
                self._schedule_refresh)

    def hide(self):
        super(OverviewTab, self).hide()
        if self.instance is not None:
            self.instance.discard_change_listener(self.refresh)
            self.instance.discard_remove_listener(self.on_instance_removed)
        if hasattr(self.instance,
                   'settlement') and self.instance.settlement is not None:
            self.instance.settlement.discard_change_listener(
                self._schedule_refresh)

    def on_instance_removed(self):
        self.on_remove()
        self.instance = None

    def init_stance_widget(self):
        """Call this for tabs with stances."""
        stance_widget = self.widget.findChild(name='stance')
        stance_widget.init(self.instance)
        self.add_remove_listener(stance_widget.remove)
示例#30
0
class SettlerUnhappyStatus(StatusIcon):
    # threshold is the inhabitants decrease level
    priority = 1700
    icon = 'as_attention_please+idle+45'
    helptext = _lazy("These residents are unhappy.")