def movementCost(self, cur, dest): """Return the cost of moving from cur tile to dest tile, taking into account surface type. Only single step movement is considered. Returns 100 when movement is not possible.""" if gridhelper.isDifficultSurface(cur.getSurface()): # moving from difficult terrain if gridhelper.horizontalDistance(cur.coords, dest.coords) == 1: if (cur.coords.z - dest.coords.z) <= 3 and ( cur.coords.z - dest.coords.z) >= -1: return 2 else: # moving from normal terrain if gridhelper.horizontalDistance(cur.coords, dest.coords) == 1: if (cur.coords.z - dest.coords.z) <= 3 and ( cur.coords.z - dest.coords.z) >= -2: return 1 elif gridhelper.horizontalDistance(cur.coords, dest.coords) == 2: if (cur.coords.z - dest.coords.z) <= 3 and (cur.coords.z >= dest.coords.z): x1 = int(cur.coords.x + floor((dest.coords.x - cur.coords.x) / 2.0)) y1 = int(cur.coords.y + floor((dest.coords.y - cur.coords.y) / 2.0)) x2 = int(cur.coords.x + ceil((dest.coords.x - cur.coords.x) / 2.0)) y2 = int(cur.coords.y + ceil((dest.coords.y - cur.coords.y) / 2.0)) loc1 = fife.ExactModelCoordinate(x1, y2, cur.coords.z) loc2 = fife.ExactModelCoordinate(x2, y1, cur.coords.z) if (not self.isBlocked(loc1, 4)) and (not self.isBlocked( loc2, 4)): return 3 return 100
def renderBoundingBox(self, obj): """ Just a hack to render an objects bounding box. """ bbox = copy.copy(obj.boundingbox) #apply the object layer scale bbox.x /= 0.25 bbox.y /= 0.25 bbox.w /= 0.25 bbox.h /= 0.25 obj_topleft = fife.ExactModelCoordinate(bbox.x, bbox.y) obj_topright = fife.ExactModelCoordinate(bbox.x + bbox.w, bbox.y) obj_bottomright = fife.ExactModelCoordinate(bbox.x + bbox.w, bbox.y + bbox.h) obj_bottomleft = fife.ExactModelCoordinate(bbox.x, bbox.y + bbox.h) loc_topleft = fife.Location() loc_topleft.setLayer(self._map.getLayer('boundingbox')) loc_topleft.setExactLayerCoordinates(obj_topleft) loc_topright = fife.Location() loc_topright.setLayer(self._map.getLayer('boundingbox')) loc_topright.setExactLayerCoordinates(obj_topright) loc_bottomright = fife.Location() loc_bottomright.setLayer(self._map.getLayer('boundingbox')) loc_bottomright.setExactLayerCoordinates(obj_bottomright) loc_bottomleft = fife.Location() loc_bottomleft.setLayer(self._map.getLayer('boundingbox')) loc_bottomleft.setExactLayerCoordinates(obj_bottomleft) node_topleft = fife.GenericRendererNode(loc_topleft) node_topright = fife.GenericRendererNode(loc_topright) node_bottomright = fife.GenericRendererNode(loc_bottomright) node_bottomleft = fife.GenericRendererNode(loc_bottomleft) self._genericrenderer.addLine("quads", node_topleft, node_topright, 255, 255, 255) self._genericrenderer.addLine("quads", node_topright, node_bottomright, 255, 255, 255) self._genericrenderer.addLine("quads", node_bottomright, node_bottomleft, 255, 255, 255) self._genericrenderer.addLine("quads", node_bottomleft, node_topleft, 255, 255, 255) #had to do this or it would segfault obj_topleft.thisown = 0 obj_topright.thisown = 0 obj_bottomright.thisown = 0 obj_bottomleft.thisown = 0 loc_topleft.thisown = 0 loc_topright.thisown = 0 loc_bottomright.thisown = 0 loc_bottomleft.thisown = 0 node_topleft.thisown = 0 node_topright.thisown = 0 node_bottomright.thisown = 0 node_bottomleft.thisown = 0
def __init(self, x, y, owner, health=100.0): self.owner = owner class Tmp(fife.InstanceActionListener): pass self.InstanceActionListener = Tmp() self.InstanceActionListener.onInstanceActionFinished = \ WeakMethod(self.onInstanceActionFinished) self.InstanceActionListener.thisown = 0 # fife will claim ownership of this if self._object is None: self.__class__._loadObject() self._instance = self.session.view.layers[LAYERS.OBJECTS].createInstance( \ self._object, fife.ModelCoordinate(int(x), int(y), 0), str(self.worldid)) fife.InstanceVisual.create(self._instance) location = fife.Location(self._instance.getLocation().getLayer()) location.setExactLayerCoordinates( fife.ExactModelCoordinate(x + x, y + y, 0)) self.act(self._action, location, True) self._instance.addActionListener(self.InstanceActionListener) self.health = health self.max_health = 100.0 self.loading_area = self.position
def wrapped(self, evt, *args, **kwargs): screen_point = self.session.view.cam.toScreenCoordinates( fife.ExactModelCoordinate(evt.getX(), evt.getY())) evt = mock.Mock() evt.getX.return_value = screen_point.x evt.getY.return_value = screen_point.y return func(self, evt, *args, **kwargs)
def __render_status(self, instance, status): status_string = self.get_status_string(instance) # Clean icons self.renderer.removeAll(status_string) # pixel-offset on screen (will be constant across zoom-levels) rel = fife.Point(0, -30) pos = instance.position # trial and error has brought me to this (it's supposed to hit the center) loc = fife.Location(self.layer) loc.setExactLayerCoordinates( fife.ExactModelCoordinate( pos.origin.x + float(pos.width) / 4, pos.origin.y + float(pos.height) / 4, )) node = fife.RendererNode(loc, rel) try: # to load an animation anim = horizons.globals.fife.animationloader.loadResource( status.icon) self.renderer.addAnimation(status_string, node, anim) except ValueError: img = horizons.globals.fife.imagemanager.load(status.icon) self.renderer.addImage(status_string, node, img)
def add_instance(self, instance, coords, layer_or_layer_data): """Adds an instance to a layer Args: instance: A fife.Instance coords: A fife.ExactModelCoordinates instance or a tuple with 3 values. layer_or_layer_data: The layer or a tuple with 2 items: The name of the layer and the map of the layer as a string or an map instance. Raises: ValueError if there was no map with that identifier. """ if not isinstance(layer_or_layer_data, fife.Layer): layer_or_layer_data = self.get_layer(layer_or_layer_data[1], layer_or_layer_data[0]) try: iter(coords) coords = fife.ExactModelCoordinate(*coords) except TypeError: pass layer_or_layer_data.addInstance(instance, coords) tmp_filename = instance.getObject().getFilename() tmp_map_name = layer_or_layer_data.getMap().getId() self.increase_refcount(tmp_filename, tmp_map_name)
def __init(self, x, y, owner): self.owner = owner class Tmp(fife.InstanceActionListener): pass self.InstanceActionListener = Tmp() self.InstanceActionListener.onInstanceActionFinished = \ WeakMethod(self.onInstanceActionFinished) self.InstanceActionListener.onInstanceActionFrame = lambda *args: None self.InstanceActionListener.thisown = 0 # fife will claim ownership of this self._instance = self.session.view.layers[ LAYERS.OBJECTS].createInstance( self.__class__._fife_object, fife.ModelCoordinate(int(x), int(y), 0), str(self.worldid)) fife.InstanceVisual.create(self._instance) location = fife.Location(self._instance.getLocation().getLayer()) location.setExactLayerCoordinates( fife.ExactModelCoordinate(x + x, y + y, 0)) self.act(self._action, location, True) self._instance.addActionListener(self.InstanceActionListener) self.loading_area = self.position self._health_displayed = False if self.has_component(HealthComponent): self.get_component(HealthComponent).add_damage_dealt_listener( self._on_damage)
def __render_icon(self, instance, group, res, amount): """ This renders the icon. It calculates the position of the icon. Most parts of this were copied from horizons/world/managers/statusiconmanager.py """ # TODO: Try to unify the __render methods of this class and statusiconmanager.py! self.renderer.removeAll(group) pos = instance.position # self.run[group] is used for the moving up animation # use -50 here to get some more offset in height bg_rel = fife.Point(0, -50 - self.run[group]) rel = fife.Point(-14, -50 - self.run[group]) self.run[group] += self.animation_steps loc = fife.Location(self.layer) loc.setExactLayerCoordinates( fife.ExactModelCoordinate( pos.origin.x + float(pos.width) / 4, pos.origin.y + float(pos.height) / 4, )) bg_node = fife.RendererNode(loc, bg_rel) node = fife.RendererNode(loc, rel) bg_image = horizons.globals.fife.imagemanager.load(self.background) res_icon = horizons.globals.fife.imagemanager.load( get_res_icon_path(res)) font = horizons.globals.fife.pychanmanager.getFont('mainmenu') self.renderer.addImage(group, bg_node, bg_image) self.renderer.resizeImage(group, node, res_icon, 24, 24) self.renderer.addText(group, node, font, ' ' * 9 + '{amount:>2d}'.format(amount=amount))
def testTrajectory(self, coords1, coords2, trajectory, visualize=False): """ Return False if an arc from loc1 to loc2 defined by trajectory is blocked by a wall or outside range, True if the arc is clear and in range. Uses locations slightly above the ones given. Creates an optional visual trajectory. """ # TODO: visualization probably should not be done here ex_coords1 = gridhelper.toExact(coords1) ex_coords2 = gridhelper.toExact(coords2) z_scale = 3.0 dist = gridhelper.horizontalDistance(coords1, coords2) * z_scale if dist == 0: return False z = coords2.z - coords1.z g = 5.0 / z_scale d2 = pow(trajectory.range, 4) - g * (g * pow(dist, 2) + 2 * z * pow(trajectory.range, 2)) if d2 < 0: return False angle1 = atan((pow(trajectory.range, 2) - sqrt(d2)) / (g * dist)) #angle2 = atan((pow(trajectory.range, 2) + sqrt(d2)) / (g * dist)) step = (ex_coords2 - ex_coords1) / 20.0 if self.visual and visualize: los = VisualLOS(self.application) self.application.real_timeline.addTimer( TacticsTimer("line of sight", 1, 1, los.destroy)) for i in range(1, 20): ex_coords = ex_coords1 + step * float(i) ex_coords.z = ex_coords1.z + float(dist) / 20.0 * float(i) * tan( angle1) - g * pow(float(dist) / 20.0 * float(i), 2) / ( 2 * pow(trajectory.range * cos(angle1), 2)) if self.visual and visualize: location = fife.Location(self.maplayer) location.setExactLayerCoordinates( fife.ExactModelCoordinate(ex_coords.x, ex_coords.y, ex_coords.z + 2)) los.addDot(location, self.shadowLocation(location)) if self.isBlockedByWall( fife.ExactModelCoordinate(ex_coords.x, ex_coords.y, ex_coords.z + 1.5), 1): if self.visual and visualize: self.application.gui.sayBubble(los.instances[-1], "blocked", 50) return False return True
def update_agents(self, game_map): """Updates the map to be in sync with the entities Args: game_map: The name of the map, or a Map instance """ if isinstance(game_map, str): game_map = self.maps[game_map] if isinstance(game_map, str): # The map is not yet loaded return object_namespace = self.settings.get("fife-rpg", "ObjectNamespace", "fife-rpg") fife_model = self.engine.getModel() game_map.update_entities() for entity in game_map.entities: agent = getattr(entity, Agent.registered_as) namespace = agent.namespace or object_namespace map_object = fife_model.getObject(agent.gfx, namespace) if not map_object: raise RuntimeError( "There is no object %s in the namespace %s" % (agent.gfx, namespace)) general = getattr(entity, General.registered_as) layer = game_map.get_layer(agent.layer) fife_instance = layer.getInstance(general.identifier) if fife_instance: fife_object = fife_instance.getObject() if (fife_object.getId() != map_object.getId() or fife_object.getNamespace() != map_object.getNamespace()): layer.deleteInstance(fife_instance) fife_instance = None if not fife_instance: position = agent.position fife_instance = layer.createInstance( map_object, fife.ExactModelCoordinate(position.x, position.y, position.z), general.identifier) fife_instance.setRotation(agent.rotation) visual = fife.InstanceVisual.create(fife_instance) if map_object.getAction('default'): target = fife.Location(game_map.actor_layer) fife_instance.actRepeat('default', target) fifeagent = getattr(entity, FifeAgent.registered_as) behaviour_class = BehaviourManager.get_behaviour( agent.behaviour_type) if behaviour_class is None: raise RuntimeError("There is no registered behaviour %s" % agent.behaviour_type) behaviour = behaviour_class(**agent.behaviour_args) behaviour.agent = fife_instance fifeagent.behaviour = behaviour fifeagent.layer = layer fifeagent.instance = fife_instance setup_behaviour(fifeagent) fifeagent.behaviour.idle() else: visual = fife_instance.get2dGfxVisual() visual.setStackPosition(STACK_POSITION[agent.type])
def __init(self, x, y): self.position = Point(x, y) self.last_position = Point(x, y) self._next_target = Point(x, y) self.move_callbacks = WeakMethodList() self.blocked_callbacks = WeakMethodList() self._conditional_callbacks = {} self.__is_moving = False self.path = self.pather_class(self, session=self.session) self._exact_model_coords1 = fife.ExactModelCoordinate() # save instance since construction is expensive (no other purpose) self._exact_model_coords2 = fife.ExactModelCoordinate() # save instance since construction is expensive (no other purpose) self._fife_location1 = None self._fife_location2 = None
def __init__(self, session): super(NavigationTool, self).__init__(session) self._last_mmb_scroll_point = [0, 0] # coordinates of last mouse positions self.last_exact_world_location = fife.ExactModelCoordinate() self._hover_instances_update_scheduled = False self.middle_scroll_active = False class CmdListener(fife.ICommandListener): pass self.cmdlist = CmdListener() horizons.globals.fife.eventmanager.addCommandListener(self.cmdlist) self.cmdlist.onCommand = self.onCommand if not self.__class__.send_hover_instances_update: # clear HoverInstancesChanged.broadcast(self, set()) self.__class__.last_hover_instances = WeakList() else: # need updates about scrolling here self.session.view.add_change_listener( self._schedule_hover_instance_update) self._schedule_hover_instance_update() class CoordsTooltip(object): @classmethod def get_instance(cls, cursor_tool): if cursor_tool.session.ingame_gui.coordinates_tooltip is not None: inst = cursor_tool.session.ingame_gui.coordinates_tooltip inst.cursor_tool = cursor_tool return inst else: return CoordsTooltip(cursor_tool) def __init__(self, cursor_tool, **kwargs): super(CoordsTooltip, self).__init__(**kwargs) cursor_tool.session.ingame_gui.coordinates_tooltip = self self.cursor_tool = cursor_tool self.enabled = False self.icon = Icon(position=( 1, 1)) # 0, 0 is currently not supported by tooltips def toggle(self): self.enabled = not self.enabled if not self.enabled and self.icon.tooltip_shown: self.icon.hide_tooltip() def show_evt(self, evt): if self.enabled: x, y = self.cursor_tool.get_world_location(evt).to_tuple() self.icon.helptext = u'%d, %d ' % (x, y) + _( "Press H to remove this hint") self.icon.position_tooltip(evt) self.icon.show_tooltip() self.tooltip = CoordsTooltip.get_instance(self)
def __init__(self, image, source, dest, needed_ticks, session, offset=True, worldid=None): """ @param image: path to file with bullet image @param source: Point with starting position @param dest: Point with ending position @param speed: Attack speed of the Weapon that fires the canonball @param session: Horizons Session @param offset: True if image should be offseted from start location """ super(Bullet, self).__init__(worldid) self.session = session # get the current position self.x = source.x self.y = source.y # needed for saving the bullet self.dest_x = dest.x self.dest_y = dest.y self.image = image # offset the position so it starts from the middle of the firing instance if offset: self.x += 1 self.y -= 1 # needed ticks to go to the destination self.needed_ticks = needed_ticks self.needed_ticks -= 2 # the thick that the object is currently at self.current_tick = 0 # calculate the axis ratio that is added per tick to move self.x_ratio = float(dest.x - source.x)/self.needed_ticks self.y_ratio = float(dest.y - source.y)/self.needed_ticks if Bullet._fife_object is None: Bullet._fife_object = horizons.globals.fife.engine.getModel().createObject('cb', 'cannonball') fife.ObjectVisual.create(Bullet._fife_object) visual = self._fife_object.get2dGfxVisual() img = horizons.globals.fife.imagemanager.load(str(image)) for rotation in [45, 135, 225, 315]: visual.addStaticImage(rotation, img.getHandle()) self._instance = session.view.layers[LAYERS.FIELDS].createInstance( self._fife_object, fife.ModelCoordinate(int(self.x),int(self.y), 0), str(self.worldid)) fife.InstanceVisual.create(self._instance) location = fife.Location(self._instance.getLocation().getLayer()) location.setExactLayerCoordinates(fife.ExactModelCoordinate(self.x, self.y, 0)) self.session.world.bullets.append(self) self._move_tick()
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 width, length = cls.size if rotation == 135 or rotation == 315: # if you look at a non-square builing from a 45 degree angle it looks # different than from a 135 degree angle # when you rotate it the width becomes the length and the length becomes the width width, length = length, width # the drawing origin is the center of it's area, minus 0.5 # the 0.5 isn't really necessary, but other code is aligned with the 0.5 shift # this is at least for the gridoverlay, and the location of a build preview relative to the mouse # it this is changed, it should also be changed for ground tiles (world/ground.py) and units instance_coords = [x + width / 2 - 0.5, y + length / 2 - 0.5, 0] instance = session.view.layers[cls.layer].createInstance( cls._fife_object, fife.ExactModelCoordinate(*instance_coords), world_id) if action_set_id is None: action_set_id = cls.get_random_action_set(level=level) fife.InstanceVisual.create(instance) action_set = ActionSetLoader.get_set(action_set_id) if action not in action_set: if 'idle' in action_set: action = 'idle' elif 'idle_full' in action_set: action = 'idle_full' else: # set first action action = list(action_set.keys())[0] instance.actRepeat("{}_{}".format(action, action_set_id), rotation) return (instance, action_set_id)
def move_camera_to(self, position): """Move the current camera to the given position Args: position: Position on the map to move the camera to """ location = self.camera.getLocation() coords = fife.ExactModelCoordinate(*position) location.setMapCoordinates(coords) self.camera.setLocation(location)
def onInstanceActionFinished(self, instance, action): """ @param instance: fife.Instance @param action: string representing the action that is finished. """ location = fife.Location(self._instance.getLocation().getLayer()) location.setExactLayerCoordinates(fife.ExactModelCoordinate( \ self.position.x + self.position.x - self.last_position.x, \ self.position.y + self.position.y - self.last_position.y, 0)) self.act(self._action, location, True) self.session.view.cam.refresh()
def _createFIFEInstance(self, layer): """ Should not be called directly. Use the constructor! """ mapmodel = self._gamecontroller.engine.getModel() self._fifeobject = mapmodel.getObject(self._name, self._gamecontroller.settings.get("RPG", "ObjectNamespace", "http://www.fifengine.net/xml/rpg")) self._instance = layer.createInstance(self._fifeobject, fife.ExactModelCoordinate(self._position.x,self._position.y), self._id) fife.InstanceVisual.create(self._instance) self._instance.thisown = 0
def __init__(self, session): super(NavigationTool, self).__init__(session) self.lastScroll = [0, 0] self.lastmoved = fife.ExactModelCoordinate() self.middle_scroll_active = False class CmdListener(fife.ICommandListener): pass self.cmdlist = CmdListener() horizons.main.fife.eventmanager.addCommandListener(self.cmdlist) self.cmdlist.onCommand = self.onCommand
def create(self, model, layer): self.layer = layer self._obj = model.getObject(self._name, "zombieswtf") inst = layer.createInstance( self._obj, fife.ExactModelCoordinate(self.loc.x, self.loc.y), "projectile") InstanceVisual.create(inst) self._instance = inst self._instance.setOverrideBlocking(True) self._instance.setBlocking(False) self.setupMovable(self._instance) self.created = True
def testLOS(self, coords1, coords2): """Return False if a line from loc1 to loc2 is blocked by a wall, True if the line is clear. Uses locations slightly above the ones given.""" ex_coords1 = gridhelper.toExact(coords1) ex_coords2 = gridhelper.toExact(coords2) step = (ex_coords2 - ex_coords1) / 10.0 for i in range(1, 10): ex_coords = ex_coords1 + step * float(i) if self.isBlockedByWall( fife.ExactModelCoordinate(ex_coords.x, ex_coords.y, ex_coords.z + 1), 1): return False return True
def onInstanceActionFinished(self, instance, action): """ @param instance: fife.Instance @param action: string representing the action that is finished. """ location = fife.Location(self._instance.getLocation().getLayer()) location.setExactLayerCoordinates( fife.ExactModelCoordinate( self.position.x + self.position.x - self.last_position.x, self.position.y + self.position.y - self.last_position.y, 0)) if action.getId() != ('move_' + self._action_set_id): self.act(self._action, self._instance.getFacingLocation(), True) else: self.act(self._action, location, True)
def _move_tick(self): if self.current_tick == self.needed_ticks: self._instance.getLocationRef().getLayer().deleteInstance(self._instance) self._instance = None self.session.world.bullets.remove(self) self.remove() return self.current_tick += 1 self.x += self.x_ratio self.y += self.y_ratio fife_location = fife.Location(self._instance.getLocationRef().getLayer()) fife_location.setExactLayerCoordinates(fife.ExactModelCoordinate(self.x, self.y, 0)) self._instance.setLocation(fife_location) Scheduler().add_new_object(self._move_tick, self, 1)
def onInstanceActionFinished(self, instance, action): """ @param instance: fife.Instance @param action: string representing the action that is finished. """ location = fife.Location(self._instance.getLocation().getLayer()) location.setExactLayerCoordinates(fife.ExactModelCoordinate( self.position.x + self.position.x - self.last_position.x, self.position.y + self.position.y - self.last_position.y, 0)) facing_loc = self._instance.getFacingLocation() if action.getId().startswith('move_'): # Remember: this means we *ended* a "move" action just now! facing_loc = location self.act(self._action, facing_loc=facing_loc, repeating=True)
def create_instance(self, layer_or_layer_data, coords, object_or_object_data, identifier=None): """Creates a new instance on the given layer at the given coords using the given object. Args: layer_or_layer_data: The layer or a tuple with 2 items: The name of the layer and the map of the layer as a string or an map instance. coords: The coordinates of the new instance. fife.ModelCoordinate or fife.ExactModelCoordinate instance or a 3 item tuple with number values. object_or_object_data: Either a fife.Object instance or a tuple with the name and namespace, in that order, of the object to use for the instance. identifier: The name of the new instance. """ if not isinstance(layer_or_layer_data, fife.Layer): layer_or_layer_data = self.get_layer(layer_or_layer_data[1], layer_or_layer_data[0]) try: iter(coords) coords = fife.ExactModelCoordinate(*coords) except TypeError: pass if not isinstance(object_or_object_data, fife.Object): object_or_object_data = self.__model.getObject( *object_or_object_data) instance = layer_or_layer_data.createInstance(object_or_object_data, coords, identifier or "") tmp_filename = instance.getObject().getFilename() tmp_map_name = layer_or_layer_data.getMap().getId() self.increase_refcount(tmp_filename, tmp_map_name) return instance
def moveInstances(self, instances, moveBy, exact=False, origLoc=None, origFacing=None): """ Moves provided instances by moveBy. If exact is false, the instances are snapped to closest cell. origLoc and origFacing are only set when an undo/redo operation takes place and will have no effect and should not be used under normal circumstances.""" mname = 'moveInstances' if not self._layer: if self.debug: print 'No layer assigned in %s' % mname return if exact and type(moveBy) != fife.ExactModelCoordinate: moveBy = fife.ExactModelCoordinate(float(moveBy.x), float(moveBy.y), float(moveBy.z)) elif exact is False and type(moveBy) != fife.ModelCoordinate: moveBy = fife.ModelCoordinate(int(round(moveBy.x)), int(round(moveBy.y)), int(round(moveBy.z))) for i in instances: loc = i.getLocation() f = i.getFacingLocation() if exact: newCoords = loc.getExactLayerCoordinates() + moveBy loc.setExactLayerCoordinates(newCoords) f.setExactLayerCoordinates(f.getExactLayerCoordinates() + moveBy) else: # Move instance and snap to closest cell newCoords = loc.getLayerCoordinates() + moveBy loc.setLayerCoordinates(newCoords) f.setLayerCoordinates(f.getLayerCoordinates() + moveBy) if not self._undo: undocall = cbwa(self.moveInstances, [i], moveBy, exact, i.getLocation(), i.getFacingLocation()) redocall = cbwa(self.moveInstances, [i], moveBy, exact, i.getLocation(), i.getFacingLocation()) undoobject = undomanager.UndoObject(undocall, redocall, "Moved instance") self._undomanager.addAction(undoobject) i.setLocation(loc) i.setFacingLocation(f) else: assert(origLoc) assert(origFacing) i.setLocation(origLoc) i.setFacingLocation(origFacing)
def get_instances_at(self, coords, layer_or_layer_data=None, use_exact_coordinates=False): """Get all instances at the given coords Args: coords: Either a 3-value tuple, fife.(Exact)ModelCoordinates instance or a fife.Location instance. layer_or_layer_data: The layer or a tuple with 2 items: The name of the layer and the map of the layer as a string or an map instance. Ignored if coords is a fife.Location instance use_exact_coordinates: if True, comparison is done using exact coordinates. if not, cell coordinates are used. Raises: ValueError if there was no map with that identifier. """ try: iter(coords) coords = fife.ExactModelCoordinate(*coords) except TypeError: pass layer = None if not isinstance(coords, fife.Location): layer = layer_or_layer_data if not isinstance(layer_or_layer_data, fife.Layer): layer = self.get_layer(layer_or_layer_data[1], layer_or_layer_data[0]) tmp_coords = coords coords = fife.Location(layer) coords.setExactLayerCoordinates(tmp_coords) else: layer = coords.getLayer() return layer.getInstancesAt(coords)
def __init__(self, session, x, y): """ @param session: Session instance @param x: int x position the ground is created. @param y: int y position the ground is created. """ self.x = x self.y = y self.settlement = None self.blocked = False self.object = None self.session = session self._tile_set_id = horizons.globals.db.get_random_tile_set(self.id) layer = session.view.layers[self.layer] # actualy this should be x + 0.5, y + 0.5, since that's the center of the tile area # however, other code depends on the current alignment. # it this is changed, it should also be changed for buildings and units self._instance = layer.createInstance( self._fife_objects[self._tile_set_id], fife.ExactModelCoordinate(x, y, 0), "") fife.InstanceVisual.create(self._instance)
def __init__(self): """ Set up all variables and call some initial functions """ self._ignoreToggles = False # A hack to avoid infinite recursion when toggling a button self._controller = None self._mode = MapEditor.SELECTING self._debug = False # TODO: We should have a central system for activating debug messages # GUI self._editor = scripts.editor.getEditor() self._eventlistener = self._editor.getEventListener() self._statusbar = self._editor.getStatusBar() self._toolbar = self._editor.getToolBar() self._toolbox = self._editor.getToolbox() # Currently selected object type self._object = None # Variables used for moving instances self._last_drag_pos_exact = fife.ExactModelCoordinate(0,0,0) self._selected_instances = [] self._undogroup = False # Variables for scrolling the map self._dragx = 0 self._dragy = 0 self._scrollX = 0 self._scrollY = 0 self._initToolboxButtons() self._toolbox.show() events.postMapShown.connect(self._mapChanged) events.preMapClosed.connect(self._mapClosed) events.onObjectSelected.connect(self.setObject)
def update_entities_fife(self): """Updates the fife instances to the values of the agent""" old_entities = self.entities.copy() for entity in old_entities: fifeagent = getattr(entity, FifeAgent.registered_as) if fifeagent: agent = getattr(entity, Agent.registered_as) if agent.new_map is not None and agent.new_map != self.name: self.remove_entity(str(entity.identifier)) continue location = fifeagent.instance.getLocation() if agent.new_layer is not None: location.setLayer(self.get_layer(agent.layer)) if agent.new_position is not None: location.setExactLayerCoordinates( fife.ExactModelCoordinate( *agent.new_position)) fifeagent.instance.setLocation(location) if agent.new_rotation is not None: fifeagent.instance.setRotation(agent.rotation) agent.new_map = None agent.new_layer = None agent.new_position = None agent.new_rotation = None
def parse_instances(self, layerelt, layer): """ create all layers and their instances @type layerelt: object @param layerelt: ElementTree layer branch @type layer: object @param layer: FIFE layer object """ instelt = layerelt.find('instances') instances = [] for attr in ('i', 'inst', 'instance'): instances.extend(instelt.findall(attr)) for instance in instances: _id = instance.get('id') if not _id: _id = '' objectID = '' for attr in ('o', 'object', 'obj'): objectID = instance.get(attr) if objectID: break if not objectID: self._err( '<instance> %s does not specify an object attribute.' % str(objectID)) objectID = str(objectID) nspace = '' for attr in ('namespace', 'ns'): nspace = instance.get(attr) if nspace: break # try to reuse the previous namespace if not nspace and self.nspace: nspace = self.nspace if not nspace and not self.nspace: self._err( '<instance> %s does not specify an object namespace, and no default is available.' % str(objectID)) nspace = str(nspace) self.nspace = nspace # check if there is an object for this instance available, if not -> skip this one object = self.model.getObject(objectID, nspace) if not object: print( "Object with id=%s, ns=%s could not be found. Omitting..." % (objectID, nspace)) continue x = instance.get('x') if x: self.x = x = float(x) else: x = self.x y = instance.get('y') if y: self.y = y = float(y) else: y = self.y z = instance.get('z') if z: z = float(z) else: z = 0.0 inst = layer.createInstance(object, fife.ExactModelCoordinate(x, y, z), _id) rotation = 0 for attr in ('r', 'rotation'): rotation = instance.get(attr) if rotation: break if not rotation: angles = object.get2dGfxVisual().getStaticImageAngles() if angles: rotation = angles[0] else: rotation = 0 else: rotation = int(rotation) inst.setRotation(rotation) over_block = instance.get('override_blocking') if over_block is not None: inst.setOverrideBlocking(bool(over_block)) blocking = instance.get('blocking') if blocking is not None: inst.setBlocking(bool(int(blocking))) fife.InstanceVisual.create(inst) stackpos = instance.get('stackpos') if stackpos: inst.get2dGfxVisual().setStackPosition(int(stackpos)) if (object.getAction('default')): target = fife.Location(layer) inst.actRepeat('default', target)