예제 #1
0
    def reject(self, character):
        """
        Reject an honour combat.
        """
        character_id = character.id
        if character_id not in self.preparing:
            return

        # stop the call
        call_id = self.preparing[character_id]["call_id"]
        call_id.cancel()
        
        # remove characters from the preparing queue
        opponent_id = self.preparing[character_id]["opponent"]

        character = search_object("#%s" % character_id)
        if character:
            character[0].msg({"match_rejected": character_id})
            del self.preparing[character_id]

        opponent = search_object("#%s" % opponent_id)
        if opponent:
            opponent[0].msg({"match_rejected": character_id})
            del self.preparing[opponent_id]

        self.remove_by_id(character_id)
예제 #2
0
def at_initial_setup():
    """
    Build up the default world and set default locations.
    """

    try:
        # load world data
        import_local_data()
        print("Import local data.")

        # load game settings
        GAME_SETTINGS.reset()
        print("Reset game settings.")

        # build world
        builder.build_all()
        print("Builder build all.")

        # set limbo's desc
        limbo_obj = search.search_object("#2", exact=True)
        if limbo_obj:
            limbo_obj[0].db.desc = LIMBO_DESC
            limbo_obj[0].position = None
        print("Set limbo object.")

        # set default locations
        builder.reset_default_locations()
        print("Set default locations.")

        superuser = search.search_object("#1", exact=True)
        if superuser:
            superuser = superuser[0]

            # move the superuser to the start location
            start_location = search.search_object(settings.START_LOCATION, exact=True)
            if start_location:
                start_location = start_location[0]
                superuser.move_to(start_location, quiet=True)

            # set superuser's data
            superuser.set_data_key(GAME_SETTINGS.get("default_player_character_key"))
            superuser.set_level(1)
            superuser.set_nickname("superuser")
            print("Set supervisor.")

    except Exception, e:
        ostring = "Can't set initial data: %s" % e
        print(ostring)
        print(traceback.format_exc())
예제 #3
0
 def remove_by_id(self, character_id):
     """
     Remove a character from the queue.
     """
     character = search_object("#%s" % character_id)
     if character:
         self.remove(character[0])
예제 #4
0
 def MailTo(self, caller, prompt, user_input):
     target = search.search_object(user_input, typeclass="typeclasses.characters.Character")
     if len(target) == 0:
         caller.msg("SYSTEM: That didn't match a player. Confirm the player's name and try again.")
     elif len(target) > 1:
         caller.msg("SYSTEM: That matched several players. Maybe try an alias?")
     else:
         caller.ndb.mailtarget = target[0]
         get_input(self.caller, "SYSTEM: What is the subject of this mail?", self.MailSubject)
         return True
예제 #5
0
def at_initial_setup():
    """
    Build up the default world and set default locations.
    """

    try:
        # load world data
        importer.import_all()

        # reload skill modules
        MudderySkill.load_skill_modules()

        # build world
        builder.build_all()
        
        # set limbo's desc
        limbo_obj = search.search_object("#2", exact=True)
        if limbo_obj:
            limbo_obj[0].db.desc = LIMBO_DESC

        # set default locations
        builder.reset_default_locations()

        superuser = search.search_object("#1", exact=True)
        if superuser:
            superuser = superuser[0]

            # move the superuser to the start location
            start_location = search.search_object(settings.START_LOCATION, exact=True)
            if start_location:
                start_location = start_location[0]
                superuser.move_to(start_location, quiet=True)

            # set superuser's data
            superuser.set_data_key(settings.DEFAULT_PLAYER_CHARACTER_KEY)
            superuser.set_level(1)
            superuser.set_nickname("superuser")

    except Exception, e:
        ostring = "Can't build world: %s" % e
        print(ostring)
        print(traceback.format_exc())
예제 #6
0
    def fight(self, opponents):
        """
        Create a combat.
        """
        confirmed0 = opponents[0] in self.preparing and self.preparing[opponents[0]]["confirmed"]
        confirmed1 = opponents[1] in self.preparing and self.preparing[opponents[1]]["confirmed"]

        if not confirmed0 and not confirmed1:
            self.remove_by_id(opponents[0])
            self.remove_by_id(opponents[1])

            opponent0 = search_object("#%s" % opponents[0])
            opponent0[0].msg({"match_rejected": opponents[0],
                              "left_combat_queue": ""})
            opponent1 = search_object("#%s" % opponents[1])
            opponent1[0].msg({"match_rejected": opponents[1],
                              "left_combat_queue": ""})
        elif not confirmed0:
            # opponents 0 not confirmed
            self.remove_by_id(opponents[0])
            if opponents[1] in self.preparing:
                del self.preparing[opponents[1]]

            opponent0 = search_object("#%s" % opponents[0])
            opponent0[0].msg({"match_rejected": opponents[0],
                              "left_combat_queue": ""})

            opponent1 = search_object("#%s" % opponents[1])
            opponent1[0].msg({"match_rejected": opponents[0]})
        elif not confirmed1:
            # opponents 1 not confirmed
            self.remove_by_id(opponents[1])
            if opponents[0] in self.preparing:
                del self.preparing[opponents[0]]

            opponent1 = search_object("#%s" % opponents[1])
            opponent1[0].msg({"match_rejected": opponents[1],
                              "left_combat_queue": ""})

            opponent0 = search_object("#%s" % opponents[0])
            opponent0[0].msg({"match_rejected": opponents[1]})
        elif confirmed0 and confirmed1:
            # all confirmed
            opponent0 = search_object("#%s" % opponents[0])
            opponent1 = search_object("#%s" % opponents[1])
            # create a new combat handler
            chandler = create_script(settings.HONOUR_COMBAT_HANDLER)
            # set combat team and desc
            chandler.set_combat({1:[opponent0[0]], 2:[opponent1[0]]}, _("Fight of Honour"), settings.AUTO_COMBAT_TIMEOUT)

            self.remove_by_id(opponents[0])
            self.remove_by_id(opponents[1])
예제 #7
0
def delete_object(obj_dbref):
    # helper function for deleting a single object
    obj = search.search_object(obj_dbref)
    if not obj:
        ostring = "Can not find object %s." % obj_dbref
        print(ostring)

    # do the deletion
    okay = obj[0].delete()
    if not okay:
        ostring = "Can not delete %s." % obj_dbref
        print(ostring)
예제 #8
0
 def func(self):
     target = search.search_object(self.args.split('=')[0], typeclass="typeclasses.characters.Character")
     if len(target) == 1:
         prefix = "From {0} on {1}/{2}: ".format(self.caller.key,datetime.now().month,datetime.now().day)
         target[0].db.notifications.append(prefix + self.args.split('=',1)[1])
         self.caller.msg("SYSTEM: Added notification to " + target[0].key + "'s queue.")
         if target[0].has_player:
             target[0].msg("SYSTEM: You have pending notifications.")
     else:
         if len(target) > 1:
             self.caller.msg("SYSTEM: That matched more than one player.")
         else:
             self.caller.msg("SYSTEM: That did not match a player.")
예제 #9
0
파일: objects.py 프로젝트: Antraeus/evennia
 def open_wall(self):
     """
     This method is called by the push button command once the puzzle
     is solved. It opens the wall and sets a timer for it to reset
     itself.
     """
     # this will make it into a proper exit (this returns a list)
     eloc = search.search_object(self.db.destination)
     if not eloc:
         self.caller.msg("The exit leads nowhere, there's just more stone behind it ...")
     else:
         self.destination = eloc[0]
     self.exit_open = True
     # start a 45 second timer before closing again
     utils.delay(45, self.reset)
예제 #10
0
 def func(self):
     target = search.search_object(self.args, typeclass="typeclasses.characters.Character")
     if len(target) == 1:
         target[0].db.approved = 1
         self.caller.msg("SYSTEM: You have approved " + target[0].key + " for play.")
         if target[0].has_player:
             target[0].msg("SYSTEM: You have been approved for play by " + self.caller.key)
         else:
             now = datetime.now()
             target[0].db.notifications.append("{0}/{1}: Approved for play by {2}.".format(now.month, now.day, self.caller.key))
     else:
         if len(target) > 1:
             self.caller.msg("SYSTEM: " + self.args + " matched several Characters.")
         else:
             self.caller.msg("SYSTEM: " + self.args + " didn't match a Character.")
예제 #11
0
 def open_wall(self):
     """
     This method is called by the push button command once the puzzle
     is solved. It opens the wall and sets a timer for it to reset
     itself.
     """
     # this will make it into a proper exit (this returns a list)
     eloc = search.search_object(self.db.destination)
     if not eloc:
         self.caller.msg(
             "The exit leads nowhere, there's just more stone behind it ..."
         )
     else:
         self.destination = eloc[0]
     self.exit_open = True
     # start a 45 second timer before closing again
     utils.delay(45, self.reset)
예제 #12
0
 def func(self):
     if not self.args:
         get_input(self.caller, "SYSTEM: Who are you sending mail to?", self.MailTo)
     else:
         target = search.search_object(self.args.split('/')[0], typeclass="typeclasses.characters.Character")
         title = self.args.split('/')[1].split('=')[0]
         message = self.args.split('/')[1].split('=',1)[1]
         if len(target) == 0:
             caller.msg("SYSTEM: That didn't match a player. Confirm the player's name and try again.")
         elif len(target) > 1:
             caller.msg("SYSTEM: That matched several players. Maybe try an alias?")
         else: 
             target = target[0]
             temp = [ self.caller.key, title, message, datetime.now() ]
             target.db.mailsystem.append(temp)
             self.caller.msg("Sent your mail to {0}".format(target.key))
             msg = "{0}/{1}: New mail from {2} about {3}.".format(temp[3].month, temp[3].day, self.caller.key, temp[1])
             target.db.notifications.append(msg)
             if target.has_player:
                 target.msg("SYSTEM: You have pending notifications.")
예제 #13
0
 def func(self):
     target = search.search_object(self.args.split('=')[0], typeclass="typeclasses.characters.Character")
     if len(target) == 1:
         target = target[0]
         if self.args.split('=')[1].isdigit():
             if self.cmdstring == '@assets':
                 target.db.assets += int(self.args.split('=')[1])
             else:
                 target.db.firebirds += int(self.args.split('=')[1])
             self.caller.msg("SYSTEM: Added {0} to {1}'s {2}.".format(self.args.split('=')[1], target.key, str(self.cmdstring).strip('@')))
             if target.has_player:
                 target.msg("SYSTEM: {0} added {1} to your {2}.".format(self.caller.key, self.args.split('=')[1], str(self.cmdstring).strip('@')))
             else:
                 target.db.notifications.append("{0}/{1}: {2} added {3} to your {4}.".format(datetime.now().month, datetime.now().day, self.caller.key, self.args.split('=')[1], str(self.cmdstring).strip('@')))
         else:
             self.caller.msg("SYSTEM: Amount argument must be a digit.")
     else:
         if len(target) > 1:
             self.caller.msg("SYSTEM: That matched more than one character.")
         else:
             self.caller.msg("SYSTEM: That didn't match any characters.")
예제 #14
0
def character_death(victim, killer=None, weapon_name=None):
  # send an appropriate global death message
  if not killer:
    msg_global(f"{victim.name} has died of mysterious causes.")
  elif not weapon_name:
    msg_global(f"{victim.name} has been slain by {killer.name}.")
  else:
    msg_global(f"{victim.name} has been slain by {killer.name}'s {weapon_name}.")

  # award xp to the killer
  if killer is not None and killer.is_typeclass("typeclasses.characters.Character"):
    killer.msg(f"You killed {victim.name}!")
    xp = calculate_kill_xp(killer.db.xp, victim.db.xp)
    gain_xp(killer, xp)

  # victim drops everything it was holding before leaving room
  for obj in victim.contents:
    if obj.worth:
      # only drop things with value
      # TODO: possible destroy chance?
      victim.execute_cmd(f"drop {obj.key}")
    else:
      # nuke worthless objects
      obj.delete()

  # victim goes to the void
  the_void = search_object("Void")[0]
  if the_void:
    victim.location.msg_contents(
      f"{victim.name} disappears in a cloud of greasy black smoke.", exclude=[victim])
    victim.move_to(the_void, quiet=True)

  # reduce victim xp/level
  set_xp(victim, int(victim.db.xp / 2))

  # clear/reset various stats
  reset_victim_state(victim)

  # starting gold!
  give_starting_gold(victim)
예제 #15
0
def _obj_search(*args, **kwargs):
    "Helper function to search for an object"

    query = "".join(args)
    session = kwargs.get("session", None)
    return_list = kwargs.pop("return_list", False)
    account = None

    if session:
        account = session.account

    targets = search.search_object(query)

    if return_list:
        retlist = []
        if account:
            for target in targets:
                if target.access(account, target, 'control'):
                    retlist.append(target)
        else:
            retlist = targets
        return retlist
    else:
        # single-match
        if not targets:
            raise ValueError("$obj: Query '{}' gave no matches.".format(query))
        if len(targets) > 1:
            raise ValueError(
                "$obj: Query '{query}' gave {nmatches} matches. Limit your "
                "query or use $objlist instead.".format(query=query,
                                                        nmatches=len(targets)))
        target = targets[0]
        if account:
            if not target.access(account, target, 'control'):
                raise ValueError(
                    "$obj: Obj {target}(#{dbref} cannot be added - "
                    "Account {account} does not have 'control' access.".format(
                        target=target.key, dbref=target.id, account=account))
        return target
예제 #16
0
    def reborn(self):
        """
        Reborn after being killed.
        """
        # Reborn at its home.
        home = None
        if not home:
            home_key = self.system.location
            if home_key:
                rooms = utils.search_obj_data_key(home_key)
                if rooms:
                    home = rooms[0]

        if not home:
            rooms = search.search_object(settings.DEFAULT_HOME)
            if rooms:
                home = rooms[0]

        if home:
            self.move_to(home, quiet=True)

        # Recover properties.
        self.recover()
예제 #17
0
def _obj_search(*args, **kwargs):
    "Helper function to search for an object"

    query = "".join(args)
    session = kwargs.get("session", None)
    return_list = kwargs.pop("return_list", False)
    account = None

    if session:
        account = session.account

    targets = search.search_object(query)

    if return_list:
        retlist = []
        if account:
            for target in targets:
                if target.access(account, target, 'control'):
                    retlist.append(target)
        else:
            retlist = targets
        return retlist
    else:
        # single-match
        if not targets:
            raise ValueError("$obj: Query '{}' gave no matches.".format(query))
        if len(targets) > 1:
            raise ValueError("$obj: Query '{query}' gave {nmatches} matches. Limit your "
                             "query or use $objlist instead.".format(
                                 query=query, nmatches=len(targets)))
        target = targets[0]
        if account:
            if not target.access(account, target, 'control'):
                raise ValueError("$obj: Obj {target}(#{dbref} cannot be added - "
                                 "Account {account} does not have 'control' access.".format(
                                    target=target.key, dbref=target.id, account=account))
        return target
예제 #18
0
def at_initial_setup():
    # Search by dbref to find the #1 superuser
    char1 = search_object('#1', use_dbref=True)[0]

    room = search_object('#2', use_dbref=True)[0]
    room.key = 'default_home'
    room.db.desc = (
        "This is the room where objects travel to when their home location isn\'t "
        "explicity set in the source code or by a builder, "
        "and the object\'s current location is destroyed. "
        "Character typeclasses are not allowed to enter this room in a move_to check."
    )

    # Black Hole
    black_hole = create_object(typeclass='rooms.rooms.Room', key='black_hole')
    black_hole.db.desc = (
        "The room where all objects go to die. It is the default home for "
        "objects that are considered worthless. Any object entering this room is "
        "automatically deleted via the at_object_receive method.")
    black_hole.tags.add('black_hole', category='rooms')

    # Statis Chamber
    statis_chamber = create_object(typeclass='rooms.rooms.Room',
                                   key='statis_chamber')
    statis_chamber.db.desc = (
        "This room holds objects indefinitely. It is the default home for "
        "objects that are of significant value, unique, or otherwise should "
        "not be destroyed for any reason.")
    statis_chamber.tags.add('statis_chamber', category='rooms')

    # Trash Bin
    trash_bin = create_object(typeclass='rooms.rooms.Room', key='trash_bin')
    trash_bin.db.desc = (
        "This room holds objects for 90 days, before being sent to black_hole. "
        "It is the default home for objects of some value and the destination "
        "of said objects when discarded by players.")
    trash_bin.tags.add('trash_bin', category='rooms')

    # Superuser's equipment generation must take place after the item rooms are generated.
    # The inventory container requires trash_bin to exist.
    char1.equip.generate_equipment()

    # Create the superuser's home room.
    rm3 = create_object(typeclass='rooms.rooms.Room', key='Main Office')
    char1.home = rm3
    rm3.tags.add('main_office', category='ooc_room')
    char1.move_to(rm3, quiet=True, move_hooks=False)

    # Create the Common Room. This is where all portals will lead when entering public OOC areas.
    rm4 = create_object(typeclass='rooms.rooms.Room', key='Common Room')
    rm4.tags.add('common_room', category='ooc_room')
    rm4.tags.add(category='public_ooc')

    # Connect the main office and common room with exits.
    exit_rm3_rm4 = create_object(typeclass='travel.exits.Exit',
                                 key='a mahogany door',
                                 aliases=[
                                     'door',
                                 ],
                                 location=rm3,
                                 destination=rm4,
                                 tags=[
                                     ('door', 'exits'),
                                 ])
    exit_rm3_rm4.attributes.add('card_dir', 'n')
    exit_rm3_rm4.tags.add(category='ooc_exit')

    exit_rm4_rm3 = create_object(typeclass='travel.exits.Exit',
                                 key='a mahogany door',
                                 aliases=[
                                     'door',
                                 ],
                                 location=rm4,
                                 destination=rm3,
                                 tags=[
                                     ('door', 'exits'),
                                 ])
    exit_rm4_rm3.attributes.add('card_dir', 's')
    exit_rm4_rm3.tags.add(category='ooc_exit')
예제 #19
0
def create_character(new_player,
                     nickname,
                     permissions=None,
                     character_key=None,
                     level=1,
                     typeclass=None,
                     location=None,
                     home=None):
    """
    Helper function, creates a character based on a player's name.
    """
    if not character_key:
        character_key = GAME_SETTINGS.get("default_player_character_key")

    if not typeclass:
        typeclass = settings.BASE_PLAYER_CHARACTER_TYPECLASS

    if not permissions:
        permissions = settings.PERMISSION_ACCOUNT_DEFAULT

    if not home:
        default_home_key = GAME_SETTINGS.get("default_player_home_key")
        if default_home_key:
            rooms = utils.search_obj_data_key(default_home_key)
            if rooms:
                home = rooms[0]

    if not home:
        rooms = search.search_object(settings.DEFAULT_HOME)
        if rooms:
            home = rooms[0]

    if not location:
        location = home
        try:
            start_location_key = GAME_SETTINGS.get("start_location_key")
            if start_location_key:
                rooms = utils.search_obj_data_key(start_location_key)
                location = rooms[0]
        except:
            pass

    new_character = create.create_object(typeclass,
                                         key=new_player.key,
                                         location=location,
                                         home=home,
                                         permissions=permissions)

    # set character info
    new_character.set_data_key(character_key, level)
    new_character.after_creation()

    # set playable character list
    new_player.db._playable_characters.append(new_character)

    # allow only the character itself and the player to puppet this character (and Immortals).
    new_character.locks.add(
        "puppet:id(%i) or pid(%i) or perm(Immortals) or pperm(Immortals)" %
        (new_character.id, new_player.id))

    # If no description is set, set a default description
    if not new_character.db.desc:
        new_character.db.desc = "This is a Player."

    # Add nickname
    if not nickname:
        nickname = character_key
    new_character.set_nickname(nickname)

    # We need to set this to have @ic auto-connect to this character
    new_player.db._last_puppet = new_character

    return new_character
예제 #20
0
    def match(self):
        """
        Match opponents according to character's scores.
        The longer a character in the queue, the score is higher.
        The nearer of two character's rank, the score is higher.
        """
        if len(self.queue) < 2:
            return

        time_now = time.time()
        candidates = []
        count = 0
        max = self.max_candidates
        for id in self.queue:
            if count >= max:
                break
                
            if id in self.preparing:
                continue
                
            characters = search_object("#%s" % id)
            if not characters or characters[0].is_in_combat():
                continue

            candidates.append(id)
            count += 1

        max_score = 0
        opponents = ()
        for i in xrange(len(candidates) - 1):
            for j in xrange(i + 1, len(candidates)):
                score_A = time_now - self.waiting_time[candidates[i]]
                score_B = time_now - self.waiting_time[candidates[j]]
                honour_A = HONOURS_MAPPER.get_honour_by_id(candidates[i], 0)
                honour_B = HONOURS_MAPPER.get_honour_by_id(candidates[j], 0)
                score_C = self.max_honour_diff - math.fabs(honour_A - honour_B)

                if score_A <= self.min_waiting_time or score_B <= self.min_waiting_time or score_C <= 0:
                    break

                score = score_A + score_B + score_C
                if score > max_score:
                    max_score = score
                opponents = candidates[i], candidates[j]
        
        if opponents:
            self.preparing[opponents[0]] = {"time": time.time(),
                                            "opponent": opponents[1],
                                            "confirmed": False}
            self.preparing[opponents[1]] = {"time": time.time(),
                                            "opponent": opponents[0],
                                            "confirmed": False}
            character_A = search_object("#%s" % opponents[0])
            character_B = search_object("#%s" % opponents[1])
            if character_A:
                character_A[0].msg({"prepare_match": self.preparing_time})
            if character_B:
                character_B[0].msg({"prepare_match": self.preparing_time})
            
            call_id = reactor.callLater(self.preparing_time, self.fight, opponents)
            self.preparing[opponents[0]]["call_id"] = call_id
            self.preparing[opponents[1]]["call_id"] = call_id

            self.ave_samples.append(time_now - self.waiting_time[opponents[0]])
            self.ave_samples.append(time_now - self.waiting_time[opponents[1]])

            while len(self.ave_samples) > self.ave_samples_number:
                self.ave_samples.popleft()

            self.ave_waiting = float(sum(self.ave_samples)) / len(self.ave_samples)
예제 #21
0
    def fight(self, opponents):
        """
        Create a combat.
        """
        confirmed0 = opponents[0] in self.preparing and self.preparing[
            opponents[0]]["confirmed"]
        confirmed1 = opponents[1] in self.preparing and self.preparing[
            opponents[1]]["confirmed"]

        if not confirmed0 and not confirmed1:
            self.remove_by_id(opponents[0])
            self.remove_by_id(opponents[1])

            opponent0 = search_object("#%s" % opponents[0])
            opponent0[0].msg({
                "match_rejected": opponents[0],
                "left_combat_queue": ""
            })
            opponent1 = search_object("#%s" % opponents[1])
            opponent1[0].msg({
                "match_rejected": opponents[1],
                "left_combat_queue": ""
            })
        elif not confirmed0:
            # opponents 0 not confirmed
            self.remove_by_id(opponents[0])
            if opponents[1] in self.preparing:
                del self.preparing[opponents[1]]

            opponent0 = search_object("#%s" % opponents[0])
            opponent0[0].msg({
                "match_rejected": opponents[0],
                "left_combat_queue": ""
            })

            opponent1 = search_object("#%s" % opponents[1])
            opponent1[0].msg({"match_rejected": opponents[0]})
        elif not confirmed1:
            # opponents 1 not confirmed
            self.remove_by_id(opponents[1])
            if opponents[0] in self.preparing:
                del self.preparing[opponents[0]]

            opponent1 = search_object("#%s" % opponents[1])
            opponent1[0].msg({
                "match_rejected": opponents[1],
                "left_combat_queue": ""
            })

            opponent0 = search_object("#%s" % opponents[0])
            opponent0[0].msg({"match_rejected": opponents[1]})
        elif confirmed0 and confirmed1:
            # all confirmed
            opponent0 = search_object("#%s" % opponents[0])
            opponent1 = search_object("#%s" % opponents[1])
            # create a new combat handler
            chandler = create_script(settings.HONOUR_COMBAT_HANDLER)
            # set combat team and desc
            chandler.set_combat(combat_type=CombatType.HONOUR,
                                teams={
                                    1: [opponent0[0]],
                                    2: [opponent1[0]]
                                },
                                desc=_("Fight of Honour"),
                                timeout=0)

            self.remove_by_id(opponents[0])
            self.remove_by_id(opponents[1])