Example #1
0
    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"]))
Example #2
0
    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]
Example #3
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)
Example #4
0
    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))
Example #5
0
    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))