def __init__(self, grid, buildconfig): self.grid = grid self.buildconfig = buildconfig self.label = '0' # init this for reuse later self.dir_pairs = [] for d in ('e', 's', 'w', 'n'): direction = Direction(d) self.dir_pairs.append([direction, direction.right_turn()]) self.dir_pairs.append([direction, direction.left_turn()])
def from_json(entity_dict): """Convert a dict representing a JSON object into an entity.""" entity_class = Entity.get_entity_by_id(entity_dict["entity_id"]) entity_pos = Vec(entity_dict["pos"]["x"], entity_dict["pos"]["y"]) entity_velocity = Vec(entity_dict["velocity"]["x"], entity_dict["velocity"]["y"]) entity_facing = Direction.str_to_direction(entity_dict["facing"]) ent = entity_class(entity_pos, entity_velocity, entity_facing) ent.uuid = uuid.UUID(entity_dict["uuid"]) return ent
def parse_startpos(start, width, height): """Transform startpos string like (1,1) or nw to corresponding Point.""" # try (#,#) type syntax m = re.match(r'\(?(\d+)[,;](\d+)\)?', start) if m is not None: return (int(m.group(1)), int(m.group(2))) # try corner-coordinate syntax m = re.match(r'(ne|nw|se|sw)', start.lower()) if m is not None: # convert corner String -> Direction -> (x, y) then magnify (x, y) # by width and height to get the corner coordinate we want (x, y) = Direction(m.group(1)).delta() point = (max(0, x) * (width - 1), max(0, y) * (height - 1)) return point raise ParametersError("Invalid --position parameter '%s'" % start)
def get_nearest_plottable_area_from(grid, start): """ Find the nearest plottable area corner from start. Returns coordinate of nearest plottable area corner. """ # if start is out of bounds for grid, expand dimensions of grid if grid.is_out_of_bounds(*start): grid.expand_dimensions(start[0] + 1, start[1] + 1) # check the cell we started in: if it is plottable, it becomes our # starting cheapest_area cell = grid.get_cell(*start) if cell.plottable and cell.area: return start # start with the innermost ring of cells adjacent to start, then # expand outward ring by ring for ring in xrange(1, 1 + max([grid.width, grid.height])): # starting position in this ring (=NW corner cell of ring) pos = add_points(start, (-ring, -ring)) for direction in (Direction(d) for d in ['e', 's', 'w', 'n']): for _ in xrange(0, 2 * ring): pos = add_points(pos, direction.delta()) # step once in direction if grid.is_out_of_bounds(*pos): continue # outside grid bounds corner = grid.get_cell(*pos) if corner.plottable and corner.area: # cell has an area that can be plotted, return it return pos # found no position with an area we can plot return None
def trace_outline(self): """ Moves the cursor to the northwest corner, then clockwise to each other corner, before returning to the starting position. """ buildconfig = BuildConfig('dig') grid = self.layers[0].grid plotter = AreaPlotter(grid, buildconfig) plotter.expand_fixed_size_areas() # plot cells of d(5x5) format ks = Keystroker(grid, buildconfig) keys = [] # move to each corner beginning with NW, going clockwise, and wait # at each one lastpos = self.start for cornerdir in [ Direction(d) for d in ['nw', 'ne', 'se', 'sw', 'nw'] ]: (x, y) = cornerdir.delta() newpos = (max(0, x) * (grid.width - 1), max(0, y) * (grid.height - 1)) keys += ks.move(lastpos, newpos, allowjumps=False) + ['%'] lastpos = newpos keys += ks.move(lastpos, self.start, allowjumps=False) # trim any pauses off the ends while keys and keys[0] == '%': keys = keys[1:] while keys and keys[-1] == '%': keys = keys[:-1] # if the result is no keys, return a single wait key keys += ['%'] return keys
return [] def move(self, (x1, y1), (x2, y2), zoffset=0, allowjumps=True): """ Returns list of keycodes needed to move DF cursor from (x1, y1) to (x2, y2) and adjust z-level by zoffset if provided. """ keys = [] # do z-moves first if needed keys += Keystroker.get_z_moves(zoffset) allow_overshoot = True # whether we may overshoot the target coords while x1 != x2 or y1 != y2: # while there are moves left to make.. direction = Direction.get_direction((x1, y1), (x2, y2)) # Get x and y component of distance between start and end dx = abs(x2 - x1) dy = abs(y2 - y1) if dx == 0: steps = dy # moving on y axis only elif dy == 0: steps = dx # moving on x axis only else: # determine max diagonal steps we can take # in this direction without going too far steps = min([dx, dy]) keycode = ['[' + direction.compass + ']']
def move_randomly(self, game): self.facing = Direction(random.randint(1, 4)) new_pos = game._move_in_direction(self.pos, self.facing) if self.can_move_to(game.world, new_pos): self.pos = new_pos
''' Created on Jun 5, 2020 @author: Gosha ''' from geometry import Point, Camera, Direction, Triangle from objects import DPoint, DCamera, DSurface from screen import Screen if(__name__ == '__main__'): cam = Camera(Point((0, 0, 0)), Direction((0, 0, 0))) dCam = DCamera(cam) screen = Screen() screen.linkCamera(dCam) sides = [] sides.append(DSurface([Triangle(Point((-10, 10, 10)), Point((10, 10, 10)), Point((10, 10, -10))), Triangle(Point((-10, 10, 10)), Point((-10, 10, -10)), Point((10, 10, -10)))], (1, 1, 0), (0, 0, 0))) sides.append(DSurface([Triangle(Point((-10, -10, 10)), Point((10, -10, 10)), Point((10, -10, -10))), Triangle(Point((-10, -10, 10)), Point((-10, -10, -10)), Point((10, -10, -10)))], (0.5, 0.5, 0.5), (0, 0, 0))) sides.append(DSurface([Triangle(Point((10, -10, 10)), Point((10, 10, 10)), Point((10, 10, -10))), Triangle(Point((10, -10, 10)), Point((10, -10, -10)), Point((10, 10, -10)))], (0, 1, 0), (0, 0, 0))) for side in sides: dCam.show(side) for x in [-10, 10]: for y in [-10, 10]: for z in [-10, 10]: dCam.show(DPoint(Point((x, y, z))))
async def parseMessage(message, username, ws): """Handle a message from a client.""" player = running_game.get_player(username) world = World.get_world_by_id(player.world_id) if message.startswith("move|") or message.startswith("fastmove|"): if running_game.player_in_battle(username) or player.talking_to: return multiplier = 1 if message.startswith("fastmove|"): multiplier = SPEED_MULTIPLIER parts = message.split("|") direction = parts[1] dir_vec = sum( [Vec.vec_from_direction_str(char) for char in set(direction)], Vec(0, 0)) if dir_vec: player.facing = Direction.str_to_direction(direction[-1]) start_pos = player.pos start_tiles = player.get_tiles_touched() now = time.monotonic() dt = min(now - player.time_of_last_move, MAX_MOVE_DT) player.time_of_last_move = now offset = dir_vec * (PLAYER_SPEED * dt * multiplier) player.pos += offset tile_coords_touching = player.get_tiles_touched() wall_tiles = [ tile_coord for tile_coord in tile_coords_touching if world.get_tile(tile_coord).blocks_movement ] if wall_tiles: wall_tiles = [tile_coord.to_pos() for tile_coord in wall_tiles] wall_tiles.sort( key=lambda tile_pos: tile_pos.dist_to(player.pos)) for wall_tile in wall_tiles: block_movement(Tile.get_bounding_box(wall_tile), start_pos, player) tile_coords_touching = player.get_tiles_touched() wall_entities = [ entity for entity in world.entities if entity.blocks_movement and player.is_touching(entity) ] if wall_entities: wall_entities.sort(key=lambda wall_entity: wall_entity.pos. dist_to(player.pos)) for wall_entity in wall_entities: block_movement(wall_entity.get_bounding_box(), start_pos, player) tile_coords_moved_on = [ tile_coord for tile_coord in tile_coords_touching if tile_coord not in start_tiles ] for tile_coord in tile_coords_moved_on: tile_moved_on = world.get_tile(tile_coord) await tile_moved_on.on_move_on( TileEventContext(game=running_game, ws=ws, username=username, world=world, player=player, tile_pos=tile_coord.to_pos()), start_pos) await Util.send_moved_to(ws, player.pos) elif message.startswith("interact"): if running_game.player_in_battle(username): return if player.talking_to: await player.talking_to.on_interact( EntityEventContext(game=running_game, ws=ws, username=username, world=world, player=player)) else: for tile_coord in player.get_tiles_touched(): tile_interacted = world.get_tile(tile_coord) await tile_interacted.on_interact( TileEventContext(game=running_game, ws=ws, username=username, world=world, player=player, tile_pos=tile_coord.to_pos())) for entity_interacted in player.get_entities_can_interact(world): await entity_interacted.on_interact( EntityEventContext(game=running_game, ws=ws, username=username, world=world, player=player)) for player_in_game in running_game.players: if (player_in_game.world_id == player.world_id and player_in_game.is_touching(player) and player_in_game.username != username): await Util.send_tag(running_game, username, player_in_game.username) elif message.startswith("getupdates"): if running_game.player_in_battle(username): return await Util.send_players(running_game, ws, username, player.world_id) await Util.send_entities(ws, world) elif message.startswith("dialoguechoose"): if running_game.player_in_battle(username): return parts = message.split("|") entity_uuid = uuid.UUID(hex=parts[1]) entity_speaking_to = world.get_entity(entity_uuid) try: await entity_speaking_to.on_dialogue_choose( EntityEventContext(game=running_game, ws=ws, username=username, world=world, player=player), int(parts[2])) except ValueError: pass elif message.startswith("battlemove"): if not running_game.player_in_battle(username): return parts = message.split("|") try: move_choice = player.moves[int(parts[1])] battle = running_game.get_battle_by_username(username) battle_state = battle.process_player_move(move_choice) if battle_state is BattleState.ONGOING: await Util.send_move_request(ws, player.moves) await Util.send_battle_status(ws, player.hp, battle.ai_combatant.hp) elif battle_state is BattleState.PLAYER_WIN: await Util.send_battle_end(ws) running_game.del_battle_by_username(username) elif battle_state is BattleState.AI_WIN: await Util.send_battle_end(ws) await Util.send_death(ws) running_game.del_battle_by_username(username) player.respawn() await Util.send_world(ws, World.get_world_by_id(player.world_id), player.pos) except ValueError: pass
def move_randomly(self): self.facing = Direction(random.randint(1, 4)) new_pos = self.game._move_in_direction(self.pos, self.facing) if self.can_move_to(new_pos): self.pos = new_pos