def func(self): """Execute the command.""" room = self.caller.location if not inherits_from(room, "typeclasses.rooms.VehicleRoom"): self.msg("|rIt seems you are not in a vehicle.|n") return vehicle = room.location # A VehicleRoom should be contained in a vehicle... but let's check if not inherits_from(vehicle, "typeclasses.vehicles.Vehicle"): self.msg("|rAre you, or are you not, in a vehicle? Hard to say.|n..") return # Make sure we are currently driving if vehicle.db.driver is not self.caller: self.msg("|gYou aren't driving {}.|n".format(vehicle.key)) return # Proceed to turn name = self.raw_string.strip().lower() if name.startswith("turn "): name = name[5:] direction = vehicle.db.direction infos = get_direction(name) if infos is None or infos["direction"] in (8, 9): self.msg("|gThe direction you specified is unknown.|n") return vehicle.db.expected_direction = infos["direction"] self.msg("You prepare to turn {} on the next open crossroad.".format(infos["name"]))
def pre_turn(self, driver, vehicle): """Before turning.""" destinations = self.db["destinations"] if destinations: location = driver.location direction = vehicle.db.direction previous, abs_direction, next = destinations[0] name = get_direction(abs_direction)["name"] log.debug("#{}-{}: turn {} {}-{}".format(vehicle.id, self.character, name, previous, next)) driver.execute_cmd("turn {}".format(name)) # Find the final coordinates if necessary final = destinations[-1][2] if isinstance(final, (tuple, list)): final = tuple(final) else: final = (final.x, final.y, final.z) distance = distance_between(destinations[-1][0].x, destinations[-1][0].y, 0, final[0], final[1], 0) # Last turn, get ready to park if len(destinations) <= 2: if "expected" not in self.db: expected = coords_in(destinations[-1][0].x, destinations[-1][0].y, final[2], direction=destinations[-1][1], distance=distance) side = get_direction( direction_between(expected[0], expected[1], 0, final[0], final[1], 0))["name"] log.debug("#{}-{}: expected {} to {}, side={}".format( vehicle.id, self.character, expected, final, side)) self.db["expected"] = expected self.db["side"] = side vehicle.start_monitoring() del destinations[0]
def display_turns(self, vehicle, crossroad): """Called to display the list of available exits.""" if vehicle.has_message("turns"): return vehicle.add_message("turns") direction = vehicle.db.direction exits = crossroad.db.exits sessions = self.sessions.get() if sessions: if any(session.protocol_flags.get( "SCREENREADER", False) for session in sessions): # One session on the driver has SCREENREADER turned on msg = "" for dir, exit in exits.items(): if msg: msg += "\n" name = get_direction(dir)["name"].capitalize() msg += " {:<10} - {}".format(name, exit["name"]) else: # Create the diagram to represent the crossroad msg = MAP.format( fl="|" if 6 in exits else " ", fn="N - " + exits[6]["name"] if 6 in exits else "", erl="/" if 7 in exits else " ", ern="NE - " + exits[7]["name"] if 7 in exits else "", ell="\\" if 5 in exits else " ", eln="NW - " + exits[5]["name"] if 5 in exits else "", rl="-" if 0 in exits else " ", rn="E - " + exits[0]["name"] if 0 in exits else "", ll="-" if 4 in exits else " ", ln="W - " + exits[4]["name"] if 4 in exits else "", hrl="\\" if 1 in exits else " ", hrn="SE - " + exits[1]["name"] if 1 in exits else "", hll="/" if 3 in exits else " ", hln="SW - " + exits[3]["name"] if 3 in exits else "", bl="|" if 2 in exits else " ", bn="S - " + exits[2]["name"] if 2 in exits else "", ) self.msg(msg)
def func(self): """Execute the command.""" room = self.caller.location if not inherits_from(room, "typeclasses.rooms.VehicleRoom"): self.msg("|rIt seems you are not in a vehicle.|n") return vehicle = room.location # A VehicleRoom should be contained in a vehicle... but let's check if not inherits_from(vehicle, "typeclasses.vehicles.Vehicle"): self.msg("|rAre you, or are you not, in a vehicle? Hard to say...|n") return # Make sure we are currently driving if vehicle.db.driver is not self.caller: self.msg("|gYou aren't driving {}.|n".format(vehicle.key)) return # Check the speed if vehicle.db.speed > 10: self.msg("|gYou are still driving too fast.|n") return # Get both sides of the current coordinate x, y, z = vehicle.db.coords # The Z coordinate could be invalid at this point, if there's a slope. previous = vehicle.db.previous_crossroad direction = vehicle.db.direction distance = distance_between(int(round(x)), int(round(y)), 0, previous.x, previous.y, 0) if (x, y) != (previous.x, previous.y): street = previous.db.exits[direction] try: assert distance > 0 x, y, z = street["coordinates"][distance - 1] except AssertionError: x, y, z = previous.x, previous.y, previous.z except IndexError: log.warning("Cannot find the Z coordinate for vehicle " \ "#{}, trying to park at {} {}.".format( vehicle.id, x, y)) self.msg("|gIt seems you can't park here.|n") return else: self.msg("|gNow, you cannot park in the middle of a crossroad.|n") return # Get the matching street log.debug("Parking #{} on {} {} {}".format(vehicle.id, x, y, z)) closest, name, streets = Crossroad.get_street(x, y, z) if not streets: self.msg("|gYou don't find any free spot to park.|n") return # Park left of right, according to the specified direction args = self.args if self.args.strip() else get_direction((direction + 2) % 8)["name"] infos = get_direction(args) if infos is None or infos["direction"] in (8, 9): self.msg("|rYou have specified an unknown direction: {}.|n".format(self.args)) return side_direction = infos["direction"] if (side_direction + 2) % 8 != direction and (side_direction - 2) % 8 != direction: self.msg("|r{} isn't a valid direction in which to park.|n\n|gCheck the street direction.|n".format(infos["name"])) return spot = streets.get(side_direction) log.debug(" Parking #{} in {}, found {}".format(vehicle.id, infos["name"], spot)) # If there's no room there if spot and spot["room"] is None: self.msg("|gYou don't find any free spot to park.|n") return room = spot["room"] vehicle.location = room vehicle.stop() numbers = "-".join(str(n) for n in spot["numbers"]) self.caller.msg("You park {} on the {sidewalk} sidewalk.".format( vehicle.key, sidewalk=infos["name"])) self.caller.location.msg_contents("{driver} parks {vehicle} on the {sidewalk} sidewalk.", exclude=[self.caller], mapping=dict(driver=self.caller, vehicle=vehicle, sidewalk=infos["name"])) vehicle.msg_contents("{vehicle} pulls up in front of {numbers} {street}", mapping=dict(vehicle=vehicle, numbers=numbers, street=name))
def create_room(self, args): """ Create a room with given exit or coordinates. When using the |w@new room|n command, you have to specify the coordinates of the room to create. This is usually done by providing an exit name as parameter: the room where you are, or the position you are in (if in road building mode) will be used to infer coordinates. You can also set the |w-c|n option, spcifying coordinates for the new room. The |w-r|n or |w--road|n option can be used to change the road that the newly-created room will be connected to. By default, this option is set to |wAUTO,|n meaning the proper address will be determined based on the name of the street you currently are. You can set this to |wNONE|n to disable automatic road lookup, or give it a full road name, like |wfirst street|n. Examples: |w@new room e|n |w@new room sw|n |w@new room -c 5,10,-15|n |w@new room west -r NONE|n |w@new room n -r gray street|n """ # Default parameters are set to None and modified by the context of the caller exit = direction = x = y = z = n_x = n_y = n_z = origin = road = None road_name = " ".join(args.road) prototype = None if args.prototype: prototype = " ".join(args.prototype) # Try to find the prototype try: prototype = PRoom.objects.get(db_key=prototype) except PRoom.DesNotExist: self.msg("The prototype {} doesn't exist.".format(prototype)) return # Do some common checks info = {} if args.exit: if args.exit not in NAME_DIRECTIONS: self.msg("Invalid direction name: {}.".format(args.exit)) return direction = NAME_DIRECTIONS[args.exit] info = get_direction(direction) exit = info["name"] # If caller is in road building mode, use its location building = self.caller.db._road_building if building: x = building["x"] y = building["y"] z = building["z"] room = Room.get_room_at(x, y, z) closest, street, exits = Crossroad.get_street(x, y, z) # If in a room in road building mode, take this room as the origin if room: origin = room elif closest and args.exit: if direction in exits: entry = exits[direction] if entry["room"]: self.msg("There's already a room {} from here: {}.".format( args.exit, entry["room"].key)) return n_x, n_y, n_z = entry["coordinates"] entry["name"] = street road = entry else: self.msg("This direction ({}) isn't a side of this road: {}.".format( exit, street)) return elif closest: self.msg("You are in road building mode on {}, you must provide " \ "an exit name.".format(street)) return else: self.msg("You are in road building mode, but not on a valid road.") return elif inherits_from(self.caller.location, "typeclasses.rooms.Room"): # The caller is in a room origin = self.caller.location x, y, z = origin.x, origin.y, origin.z if any(c is None for c in (x, y, z)): self.msg("You are in a room without valid coordinates.") return # Try to identify whether the new room would be a road if direction is not None: n_x, n_y, n_z = coords_in(x, y, z, direction) elif args.coordinates: n_x, n_y, n_z = args.coordinates if road_name == "AUTO": roads = origin.tags.get(category="road") roads = roads or [] roads = [roads] if isinstance(roads, basestring) else roads for name in roads: # Get all coordinates for this road coordinates = Crossroad.get_road_coordinates(name, include_road=False, include_crossroads=False) if (n_x, n_y, n_z) in coordinates: road = { "name": name, "numbers": coordinates[(n_x, n_y, n_z)], } break elif road_name != "NONE": # Look for the road name coordinates = Crossroad.get_road_coordinates(road_name, include_road=False, include_crossroads=False) if (n_x, n_y, n_z) in coordinates: road = { "name": road_name, "numbers": coordinates[(n_x, n_y, n_z)], } else: self.msg("Cannot find the road named '{}'.".format( road_name)) # Check that the new coordinates are not already used already = Room.get_room_at(n_x, n_y, n_z) if already is not None: self.msg("A room ({}) already exists here, X+{} Y={} Z={}.".format( already.key, n_x, n_y, n_z)) return # Create the new room if prototype: room = prototype.create() else: room = create_object("typeclasses.rooms.Room", "Nowhere") room.x = n_x room.y = n_y room.z = n_z self.msg("Creating a new room: {}(#{}) (X={}, Y={}, Z={}).".format( room.key, room.id, n_x, n_y, n_z)) if road: name = road["name"] numbers = road["numbers"] self.msg("Adding addresses {} {} to the new room.".format( "-".join(str(n) for n in numbers), name)) room.add_address(numbers, name) # Create the exits if needed if exit and origin: if any(e.name == exit for e in origin.exits): self.msg("There already is an exit {} in the room {}.".format( exit, origin.key)) else: aliases = info["aliases"] create_object("typeclasses.exits.Exit", exit, origin, aliases=aliases, destination=room) self.msg("Created {} exit from {} to {}.".format( exit, origin.key, room.key)) # Creating the back exit if info and origin: back = info["opposite_name"] if any(e.name == back for e in room.exits): self.msg("There already is an exit {} in the room {}.".format( back, room.key)) else: aliases = info["opposite_aliases"] create_object("typeclasses.exits.Exit", back, room, aliases=aliases, destination=origin) self.msg("Created {} exit from {} to {}.".format(back, room.key, origin.key))