def _loadObject(cls): """Loads the object with all animations. """ cls.log.debug('Loading unit %s', cls.id) model = horizons.globals.fife.engine.getModel() try: cls._real_object = model.createObject(str(cls.id), 'unit') except RuntimeError: cls.log.debug('Already loaded unit %s', cls.id) cls._real_object = model.getObject(str(cls.id), 'unit') return cls._real_object.setPather(model.getPather('RoutePather')) cls._real_object.setBlocking(False) cls._real_object.setStatic(False) all_action_sets = ActionSetLoader.get_sets() # create load callbacks to be called when the actions are needed #{ action_set : { action_id : [ load0, load1, ..., loadn ]}} # (loadi are load functions of objects, there can be many per as_id and action) # cls.action_sets looks like this: {tier1: {set1: None, set2: preview2, ..}, ..} for set_dict in cls.action_sets.itervalues(): for action_set in set_dict: # set1, set2, ... if not action_set in cls._action_load_callbacks: cls._action_load_callbacks[action_set] = {} for action_id in all_action_sets[action_set]: # idle, move, ... if not action_id in cls._action_load_callbacks[action_set]: cls._action_load_callbacks[action_set][action_id] = [] cls._action_load_callbacks[action_set][action_id].append( Callback(cls._do_load, all_action_sets, action_set, action_id))
def draw_gui(self): if not hasattr(self, "action_set"): try: level = self._class.default_level_on_build except AttributeError: level = self.session.world.player.settler_level action_set = self._class.get_random_action_set(level=level) action_sets = ActionSetLoader.get_sets() for action_option in ['idle', 'idle_full', 'single', 'abcd']: if action_option in action_sets[action_set]: action = action_option break else: # If no idle, idle_full or abcd animation found, use the first you find action = action_sets[action_set].keys()[0] rotation = (self.rotation + int(self.session.view.cam.getRotation()) - 45) % 360 image = sorted(action_sets[action_set][action][rotation].keys())[0] if GFX.USE_ATLASES: # Make sure the preview is loaded horizons.globals.fife.animationloader.load_image(image, action_set, action, rotation) building_icon = self.gui.findChild(name='building') loaded_image = horizons.globals.fife.imagemanager.load(image) building_icon.image = fife.GuiImage(loaded_image) width = loaded_image.getWidth() # TODO: Remove hardcoded 220 max_width = 220 if width > max_width: height = loaded_image.getHeight() size = (max_width, (height * max_width) // width) building_icon.max_size = building_icon.min_size = building_icon.size = size # TODO: Remove hardcoded 70 gui_x, gui_y = self.__class__.gui.size icon_x, icon_y = building_icon.size building_icon.position = (gui_x // 2 - icon_x // 2, gui_y // 2 - icon_y // 2 - 70) self.__class__.gui.adaptLayout()
def draw_gui(self): if not hasattr(self, "action_set"): level = self.session.world.player.settler_level if \ not hasattr(self._class, "default_level_on_build") else \ self._class.default_level_on_build action_set = self._class.get_random_action_set(level=level) action_sets = ActionSetLoader.get_sets() for action_option in ['idle', 'idle_full', 'abcd']: if action_option in action_sets[action_set]: action = action_option break else: # If no idle, idle_full or abcd animation found, use the first you find action = action_sets[action_set].keys()[0] rotation = (self.rotation + int(self.session.view.cam.getRotation()) - 45) % 360 image = sorted(action_sets[action_set][action][rotation].keys())[0] if GFX.USE_ATLASES: # Make sure the preview is loaded horizons.globals.fife.animationloader.load_image(image, action_set, action, rotation) building_icon = self.gui.findChild(name='building') loaded_image = horizons.globals.fife.imagemanager.load(image) building_icon.image = fife.GuiImage(loaded_image) width = loaded_image.getWidth() # TODO: Remove hardcoded 220 max_width = 220 if width > max_width: height = loaded_image.getHeight() size = (max_width, (height * max_width) // width) building_icon.max_size = building_icon.min_size = building_icon.size = size # TODO: Remove hardcoded 70 gui_x, gui_y = self.__class__.gui.size icon_x, icon_y = building_icon.size building_icon.position = (gui_x // 2 - icon_x // 2, gui_y // 2 - icon_y // 2 - 70) self.__class__.gui.adaptLayout()
def __init__(self, instances, show_number=True): self.log = logging.getLogger("gui.tabs") self.instances = instances self.widget = load_uh_widget("unit_entry_widget.xml") # get the icon of the first instance i = instances[0] if i.id < UNITS.DIFFERENCE_BUILDING_UNIT_ID: # A building. Generate dynamic thumbnail from its action set. imgs = ActionSetLoader.get_sets()[i._action_set_id].items()[0][1] thumbnail = imgs[45].keys()[0] else: # Units use manually created thumbnails because those need to be # precise and recognizable in combat situations. thumbnail = self.get_unit_thumbnail(i.id) self.widget.findChild(name="unit_button").up_image = thumbnail 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 __init__(self, instances, show_number=True): self.log = logging.getLogger("gui.tabs") self.instances = instances self.widget = load_uh_widget("unit_entry_widget.xml") # get the icon of the first instance i = instances[0] if i.id < UNITS.DIFFERENCE_BUILDING_UNIT_ID: # A building. Generate dynamic thumbnail from its action set. imgs = ActionSetLoader.get_sets()[i._action_set_id].items()[0][1] thumbnail = imgs[45].keys()[0] else: # Units use manually created thumbnails because those need to be # precise and recognizable in combat situations. thumbnail = self.get_unit_thumbnail(i.id) self.widget.findChild(name="unit_button").up_image = thumbnail 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 draw_gui(self): if not hasattr(self, "action_set"): level = self.session.world.player.settler_level if \ not hasattr(self._class, "default_level_on_build") else \ self._class.default_level_on_build self.action_set = self._class.get_random_action_set(level=level, include_preview=True) action_set, preview_action_set = self.action_set action_sets = ActionSetLoader.get_sets() if preview_action_set in action_sets: action_set = preview_action_set if 'idle' in action_sets[action_set]: action = 'idle' elif 'idle_full' in action_sets[action_set]: action = 'idle_full' else: # If no idle animation found, use the first you find action = action_sets[action_set].keys()[0] rotation = (self.rotation + int(self.session.view.cam.getRotation()) - 45) % 360 image = sorted(action_sets[action_set][action][rotation].keys())[0] if GFX.USE_ATLASES: # Make sure the preview is loaded horizons.globals.fife.animationloader.load_image(image, action_set, action, rotation) building_icon = self.gui.findChild(name='building') building_icon.image = image # TODO: Remove hardcoded 70 gui_x, gui_y = self.__class__.gui.size icon_x, icon_y = building_icon.size building_icon.position = (gui_x // 2 - icon_x // 2, gui_y // 2 - icon_y // 2 - 70) self.__class__.gui.adaptLayout()
def add_overlay(self, overlay_name, z_order): """Creates color overlay recoloring the area defined in *overlay_set* and adds it to fife instance. Note that a color overlay on *z_order* can only be visible if an animation overlay with that specific order exists as well. For order 0, `convertToOverlays()` makes sure they do. """ if not self.fife_instance.isAnimationOverlay(self.identifier): # parameter False: do not convert color overlays attached to base self.fife_instance.convertToOverlays(self.identifier, False) all_action_sets = ActionSetLoader.get_sets() try: overlay_set = all_action_sets[self.action_set][overlay_name] except KeyError: self.log.warning( 'Could not find overlay action set `%s` defined for object ' '`%s` with id `%s`. Not adding overlay for this action.', overlay_name, self.instance, self.identifier) return self.current_overlays[z_order] = overlay_set for rotation, frames in overlay_set.iteritems(): ov_anim = fife.Animation.createAnimation() for frame_img, frame_data in frames.iteritems(): try: frame_length = frame_data[0] except TypeError: # not using atlases frame_length = frame_data pic = horizons.globals.fife.imagemanager.load(frame_img) frame_milliseconds = int(frame_length * 1000) ov_anim.addFrame(pic, frame_milliseconds) overlay = fife.OverlayColors(ov_anim) self.fife_instance.addColorOverlay(self.identifier, rotation, z_order, overlay)
def _loadObject(cls): """Loads the object with all animations. """ cls.log.debug('Loading unit %s', cls.id) model = horizons.globals.fife.engine.getModel() try: cls._real_object = model.createObject(str(cls.id), 'unit') except fife.NameClash: cls.log.debug('Already loaded unit %s', cls.id) cls._real_object = model.getObject(str(cls.id), 'unit') return cls._real_object.setPather(model.getPather('RoutePather')) cls._real_object.setBlocking(False) cls._real_object.setStatic(False) all_action_sets = ActionSetLoader.get_sets() # create load callbacks to be called when the actions are needed #{ action_set : { action_id : [ load0, load1, ..., loadn ]}} # (loadi are load functions of objects, there can be many per as_id and action) # cls.action_sets looks like this: {tier1: {set1: None, set2: preview2, ..}, ..} for set_dict in cls.action_sets.values(): for action_set in set_dict: # set1, set2, ... if action_set not in cls._action_load_callbacks: cls._action_load_callbacks[action_set] = {} for action_id in all_action_sets[ action_set]: # idle, move, ... if action_id not in cls._action_load_callbacks[action_set]: cls._action_load_callbacks[action_set][action_id] = [] cls._action_load_callbacks[action_set][action_id].append( Callback(cls._do_load, all_action_sets, action_set, action_id))
def _init_sets(self): self.sets = [] self.sets.append( ImageSetManager(TileSetLoader.get_sets(), PATHS.TILE_SETS_JSON_FILE)) self.sets.append( ImageSetManager(ActionSetLoader.get_sets(), PATHS.ACTION_SETS_JSON_FILE))
def __init__(self, instance): super(SignalFireOverviewTab, self).__init__( widget='overview_signalfire.xml', instance=instance) 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 self.helptext = _("Overview")
def init_widget(self): super(BarrierOverviewTab, self).init_widget() action_set = ActionSetLoader.get_sets()[self.instance._action_set_id] action_gfx = action_set.get('single', 'abcd') image = action_gfx[45].keys()[0] self.widget.findChild(name="building_image").image = image health_widget = self.widget.findChild(name='health') health_widget.init(self.instance) self.add_remove_listener(health_widget.remove)
def __init__(self, instance): super(SignalFireOverviewTab, self).__init__(widget='overview_signalfire.xml', instance=instance) 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 self.helptext = _("Overview")
def init_widget(self): super().init_widget() action_set = ActionSetLoader.get_sets()[self.instance._action_set_id] action_gfx = action_set.get('single', 'abcd') image = list(action_gfx[45].keys())[0] self.widget.findChild(name="building_image").image = image health_widget = self.widget.findChild(name='health') health_widget.init(self.instance) self.add_remove_listener(health_widget.remove)
def update_overlay(self, res_id, new_amount): """Called when inventory amount of one resource changes. Looks for a fitting animation overlay based on the new inventory amount for that resource. If that overlay is different from the currently displayed one, removes the old overlay for that resource and adds a new one based on what fits *new_amount* best. """ try: overlay_order = self.overlays[self.action_set][ self.instance._action][res_id] except KeyError: self.log.warning( 'No overlays defined for resource `%s`, action `%s` and action set `%s`. ' 'Consider using `null` overlays for amount 0 in this action set.', res_id, self.instance._action, self.action_set) self.current_overlays[res_id] = None return all_action_sets = ActionSetLoader.get_sets() # We use max(0, new_amount) restricted to what exists in overlay_order. # E.g. for # new_amount = 3 # overlay_order = [[0, None], [2, 'as_2'], [5, 'as_full']] # we drop 5 (because it is defined but too large), # ignore 4 and 3 (because they are not defined in overlay_order), # and find 'as_2' as our new overlay for the amount 2. for (amount, overlay_name) in sorted(overlay_order, reverse=True): if amount > new_amount: # This `if` drops defined-but-too-large candidates (i.e. case `5` in above example). continue if amount == self.current_overlays[res_id]: # Nothing to do, continue using the same overlay return if overlay_name is None: # Empty overlay, only display base action set (i.e. case `0` in above example) self.remove_overlay(res_id) return try: overlay_set = all_action_sets[self.action_set][overlay_name] except KeyError: self.log.warning( 'Could not find overlay action set defined for object ' '`%s` with id `%s` for resource `%s` and amount `%s`. ' 'Falling back to next lower overlay.', self.instance, self.identifier, res_id, amount) continue self.remove_overlay(res_id) self.add_overlay(overlay_set, z_order=res_id) self.current_overlays[res_id] = amount return
def update_overlay(self, res_id, new_amount): """Called when inventory amount of one resource changes. Looks for a fitting animation overlay based on the new inventory amount for that resource. If that overlay is different from the currently displayed one, removes the old overlay for that resource and adds a new one based on what fits *new_amount* best. """ try: overlay_order = self.overlays[self.action_set][self.instance. _action][res_id] except KeyError: self.log.warning( 'No overlays defined for resource `%s`, action `%s` and action set `%s`. ' 'Consider using `null` overlays for amount 0 in this action set.', res_id, self.instance._action, self.action_set) self.current_overlays[res_id] = None return all_action_sets = ActionSetLoader.get_sets() # We use max(0, new_amount) restricted to what exists in overlay_order. # E.g. for # new_amount = 3 # overlay_order = [[0, None], [2, 'as_2'], [5, 'as_full']] # we drop 5 (because it is defined but too large), # ignore 4 and 3 (because they are not defined in overlay_order), # and find 'as_2' as our new overlay for the amount 2. for (amount, overlay_name) in sorted(overlay_order, reverse=True): if amount > new_amount: # This `if` drops defined-but-too-large candidates (i.e. case `5` in above example). continue if amount == self.current_overlays[res_id]: # Nothing to do, continue using the same overlay return if overlay_name is None: # Empty overlay, only display base action set (i.e. case `0` in above example) self.remove_overlay(res_id) return try: overlay_set = all_action_sets[self.action_set][overlay_name] except KeyError: self.log.warning( 'Could not find overlay action set defined for object ' '`%s` with id `%s` for resource `%s` and amount `%s`. ' 'Falling back to next lower overlay.', self.instance, self.identifier, res_id, amount) continue self.remove_overlay(res_id) self.add_overlay(overlay_set, z_order=res_id) self.current_overlays[res_id] = amount return
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 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 _loadObjects(self): # get fifedit objects self.model = self._engine.getModel() self.all_action_sets = ActionSetLoader.get_sets() TileSetLoader.load() ActionSetLoader.load() self.animationloader = SQLiteAnimationLoader() self._loadGroundTiles() self._loadBuildings()
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 _loadObject(cls): """Loads building from the db. """ cls.log.debug("Loading building %s", cls.id) try: cls._real_object = horizons.globals.fife.engine.getModel().createObject(str(cls.id), 'building') except RuntimeError: cls.log.debug("Already loaded building %s", cls.id) cls._real_object = horizons.globals.fife.engine.getModel().getObject(str(cls.id), 'building') return all_action_sets = ActionSetLoader.get_sets() # cls.action_sets looks like this: {tier1: {set1: None, set2: preview2, ..}, ..} for action_set_list in cls.action_sets.itervalues(): for action_set in action_set_list: # set1, set2, ... for action_id in all_action_sets[action_set]: # idle, move, ... cls._do_load(all_action_sets, action_set, action_id)
def __init__(self, instance): super(SettlerOverviewTab, self).__init__(widget="overview_settler.xml", instance=instance) self.helptext = _("Settler overview") 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
try: import run_uh except ImportError as e: print e.message print 'Please run from uh root dir' sys.exit(1) from run_uh import init_environment init_environment() import horizons.main from horizons.util.loaders.actionsetloader import ActionSetLoader global db, action_sets db = horizons.main._create_main_db() action_sets = ActionSetLoader.get_sets() from horizons.entities import Entities from horizons.ext.dummy import Dummy from horizons.extscheduler import ExtScheduler ExtScheduler.create_instance(Dummy()) # sometimes needed by entities in subsequent calls def get_entities(type): ret = dict() for e in getattr(Entities, type).itervalues(): level_sets = e.action_sets_by_level di = dict() for (level, list) in level_sets.iteritems(): if list == []: continue images = []
def init_widget(self): super(SignalFireOverviewTab, self).init_widget() 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 getInstance(cls, session, x, y, action='idle', level=0, rotation=45, action_set_id=None, world_id=""): """Get a Fife instance @param x, y: The coordinates @param action: The action, defaults to 'idle' @param level: object level. Relevant for choosing an action set @param rotation: rotation of the object. Any of [ 45 + 90*i for i in xrange(0, 4) ] @param action_set_id: can be set if the action set is already known. If set, level isn't considered. @return: tuple (fife_instance, action_set_id) """ assert isinstance(x, int) assert isinstance(y, int) #rotation = cls.check_build_rotation(session, rotation, x, y) # TODO: replace this with new buildable api # IDEA: save rotation in savegame facing_loc = fife.Location(session.view.layers[cls.layer]) instance_coords = list((x, y, 0)) layer_coords = list((x, y, 0)) width, length = cls.size # NOTE: # nobody actually knows how the code below works. # it's for adapting the facing location and instance coords in # different rotations, and works with all quadratic buildings (tested up to 4x4) # for the first unquadratic building (2x4), a hack fix was put into it. # the plan for fixing this code in general is to wait until there are more # unquadratic buildings, and figure out a pattern of the placement error, # then fix that generally. if rotation == 45: layer_coords[0] = x + width + 3 if width == 2 and length == 4: # HACK: fix for 4x2 buildings instance_coords[0] -= 1 instance_coords[1] += 1 elif rotation == 135: instance_coords[1] = y + length - 1 layer_coords[1] = y - length - 3 if width == 2 and length == 4: # HACK: fix for 4x2 buildings instance_coords[0] += 1 instance_coords[1] -= 1 elif rotation == 225: instance_coords = list(( x + width - 1, y + length - 1, 0)) layer_coords[0] = x - width - 3 if width == 2 and length == 4: # HACK: fix for 4x2 buildings instance_coords[0] += 1 instance_coords[1] -= 1 elif rotation == 315: instance_coords[0] = x + width - 1 layer_coords[1] = y + length + 3 if width == 2 and length == 4: # HACK: fix for 4x2 buildings instance_coords[0] += 1 instance_coords[1] -= 1 else: return None instance = session.view.layers[cls.layer].createInstance( cls._fife_object, fife.ModelCoordinate(*instance_coords), world_id) facing_loc.setLayerCoordinates(fife.ModelCoordinate(*layer_coords)) if action_set_id is None: action_set_id = cls.get_random_action_set(level=level) fife.InstanceVisual.create(instance) action_sets = ActionSetLoader.get_sets() if not action in action_sets[action_set_id]: if 'idle' in action_sets[action_set_id]: action = 'idle' elif 'idle_full' in action_sets[action_set_id]: action = 'idle_full' else: # set first action action = action_sets[action_set_id].keys()[0] if (Fife.getVersion() >= (0, 3, 6)): instance.actRepeat(action+"_"+str(action_set_id), facing_loc) else: instance.act(action+"_"+str(action_set_id), facing_loc, True) return (instance, action_set_id)
def has_action(self, action): """Checks if this unit has a certain action. @param anim: animation id as string""" return (action in ActionSetLoader.get_sets()[self._action_set_id])
def _init_sets(self): self.sets = [] self.sets.append(ImageSetManager(TileSetLoader.get_sets(), PATHS.TILE_SETS_JSON_FILE)) self.sets.append(ImageSetManager(ActionSetLoader.get_sets(), PATHS.ACTION_SETS_JSON_FILE))
def has_action(self, action): """Checks if this unit has a certain action. @param action: animation id as string""" return (action in ActionSetLoader.get_sets()[self._action_set_id])