1 """Miscellaneous objects for the MUFF Engine"""
3 # Copyright (c) 2005 mudpy, Jeremy Stanley <fungi@yuggoth.org>, all rights reserved.
4 # Licensed per terms in the LICENSE file distributed with this software.
6 # used by several functions for random calls
9 # random_name uses string.strip
12 # the log function uses time.asctime for creating timestamps
15 # hack to load all modules in the muff package
17 for module in muff.__all__:
18 exec("import " + module)
20 def broadcast(message):
21 """Send a message to all connected users."""
22 for each_user in muffvars.userlist: each_user.send(message)
27 # the time in posix log timestamp format
28 timestamp = time.asctime()[4:19]
30 # send the timestamp and message to standard output
31 print(timestamp + " " + message)
33 def wrap_ansi_text(text, width):
34 """Wrap text with arbitrary width while ignoring ANSI colors."""
36 # the current position in the entire text string, including all
37 # characters, printable or otherwise
40 # the current text position relative to the begining of the line,
41 # ignoring color escape sequences
44 # whether the current character is part of a color escape sequence
47 # iterate over each character from the begining of the text
48 for each_character in text:
50 # the current character is the escape character
51 if each_character == chr(27):
54 # the current character is within an escape sequence
57 # the current character is m, which terminates the
58 # current escape sequence
59 if each_character == "m":
62 # the current character is a newline, so reset the relative
63 # position (start a new line)
64 elif each_character == "\n":
67 # the current character meets the requested maximum line width,
68 # so we need to backtrack and find a space at which to wrap
69 elif relative_position == width:
71 # distance of the current character examined from the
75 # count backwards until we find a space
76 while text[absolute_position - wrap_offset] != " ":
79 # insert an eol in place of the space
80 text = text[:absolute_position - wrap_offset] + "\r\n" + text[absolute_position - wrap_offset + 1:]
82 # increase the absolute position because an eol is two
83 # characters but the space it replaced was only one
84 absolute_position += 1
86 # now we're at the begining of a new line, plus the
87 # number of characters wrapped from the previous line
88 relative_position = wrap_offset
90 # as long as the character is not a carriage return and the
91 # other above conditions haven't been met, count it as a
93 elif each_character != "\r":
94 relative_position += 1
96 # increase the absolute position for every character
97 absolute_position += 1
99 # return the newly-wrapped text
102 def weighted_choice(data):
103 """Takes a dict weighted by value and returns a random key."""
105 # this will hold our expanded list of keys from the data
108 # create thee expanded list of keys
109 for key in data.keys():
110 for count in range(data[key]):
113 # return one at random
114 return random.choice(expanded)
117 """Returns a random character name."""
119 # the vowels and consonants needed to create romaji syllables
120 vowels = [ "a", "i", "u", "e", "o" ]
121 consonants = ["'", "k", "z", "s", "sh", "z", "j", "t", "ch", "ts", "d", "n", "h", "f", "m", "y", "r", "w" ]
123 # this dict will hold our weighted list of syllables
126 # generate the list with an even weighting
127 for consonant in consonants:
129 syllables[consonant + vowel] = 1
131 # we'll build the name into this string
134 # create a name of random length from the syllables
135 for syllable in range(random.randrange(2, 6)):
136 name += weighted_choice(syllables)
138 # strip any leading quotemark, capitalize and return the name
139 return string.strip(name, "'").capitalize()