issue #2243 -- prefer f-strings over %-interpolation
edited docs to prefer f-strings, then str.format(), and remove %-interpolation additional ad-hoc documentation fixes, as opportunities seen: - replace Built-In Function (BIF) "min" variable with "mins" - prefer BIF str(var) over "%s" % var - reformat some code examples to clarify multiple args passed to functions - change some single-quote strings to double-quotes for consistency - fix mismatched parens misc edits: - add .vscode/ to gitignore
This commit is contained in:
parent
f45051050e
commit
851ca30be5
30 changed files with 207 additions and 193 deletions
|
|
@ -91,13 +91,12 @@ Below is a version of the example file found in `evennia/contrib/tutorial_exampl
|
||||||
table = create_object(Object, key="Blue Table", location=limbo)
|
table = create_object(Object, key="Blue Table", location=limbo)
|
||||||
chair = create_object(Object, key="Blue Chair", location=limbo)
|
chair = create_object(Object, key="Blue Chair", location=limbo)
|
||||||
|
|
||||||
string = "A %s and %s were created."
|
string = f"A {table} and {chair} were created."
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
table.delete()
|
table.delete()
|
||||||
chair.delete()
|
chair.delete()
|
||||||
string += " Since debug was active, " \
|
string += " Since debug was active, they were deleted again."
|
||||||
"they were deleted again."
|
caller.msg(string)
|
||||||
caller.msg(string % (table, chair))
|
|
||||||
```
|
```
|
||||||
|
|
||||||
This uses Evennia's Python API to create three objects in sequence.
|
This uses Evennia's Python API to create three objects in sequence.
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ Here is a minimalistic command with no custom parsing:
|
||||||
|
|
||||||
def func(self):
|
def func(self):
|
||||||
# echo the caller's input back to the caller
|
# echo the caller's input back to the caller
|
||||||
self.caller.msg("Echo: {}".format(self.args)
|
self.caller.msg(f"Echo: {self.args}")
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -548,7 +548,7 @@ class CmdTestID(Command):
|
||||||
self.xval = 0
|
self.xval = 0
|
||||||
self.xval += 1
|
self.xval += 1
|
||||||
|
|
||||||
self.caller.msg("Command memory ID: {} (xval={})".format(id(self), self.xval))
|
self.caller.msg(f"Command memory ID: {id(self)} (xval={self.xval})")
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -651,7 +651,7 @@ thus do so asynchronously, using callbacks.
|
||||||
```python
|
```python
|
||||||
# in command class func()
|
# in command class func()
|
||||||
def callback(ret, caller):
|
def callback(ret, caller):
|
||||||
caller.msg("Returned is %s" % ret)
|
caller.msg(f"Returned is {ret}")
|
||||||
deferred = self.execute_command("longrunning")
|
deferred = self.execute_command("longrunning")
|
||||||
deferred.addCallback(callback, self.caller)
|
deferred.addCallback(callback, self.caller)
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ class CmdSetTestAttr(Command):
|
||||||
def quit(caller):
|
def quit(caller):
|
||||||
"Since we define it, we must handle messages"
|
"Since we define it, we must handle messages"
|
||||||
caller.msg("Editor exited")
|
caller.msg("Editor exited")
|
||||||
key = "%s/test" % self.caller
|
key = f"{self.caller}/test"
|
||||||
# launch the editor
|
# launch the editor
|
||||||
eveditor.EvEditor(self.caller,
|
eveditor.EvEditor(self.caller,
|
||||||
loadfunc=load, savefunc=save, quitfunc=quit,
|
loadfunc=load, savefunc=save, quitfunc=quit,
|
||||||
|
|
@ -100,7 +100,7 @@ class CmdSetTestAttr(Command):
|
||||||
key = "settestattr"
|
key = "settestattr"
|
||||||
def func(self):
|
def func(self):
|
||||||
"Set up the callbacks and launch the editor"
|
"Set up the callbacks and launch the editor"
|
||||||
key = "%s/test" % self.caller
|
key = f"{self.caller}/test"
|
||||||
# launch the editor
|
# launch the editor
|
||||||
eveditor.EvEditor(self.caller,
|
eveditor.EvEditor(self.caller,
|
||||||
loadfunc=load, savefunc=save, quitfunc=quit,
|
loadfunc=load, savefunc=save, quitfunc=quit,
|
||||||
|
|
|
||||||
|
|
@ -531,10 +531,10 @@ def _set_attribute(caller, raw_string, **kwargs):
|
||||||
|
|
||||||
def node_background(caller):
|
def node_background(caller):
|
||||||
text = \
|
text = \
|
||||||
"""
|
f"""
|
||||||
{} experienced a traumatic event
|
{caller.key} experienced a traumatic event
|
||||||
in their childhood. What was it?
|
in their childhood. What was it?
|
||||||
""".format(caller.key}
|
"""
|
||||||
|
|
||||||
options = ({"key": "death",
|
options = ({"key": "death",
|
||||||
"desc": "A violent death in the family",
|
"desc": "A violent death in the family",
|
||||||
|
|
@ -580,7 +580,7 @@ def _set_name(caller, raw_string, **kwargs):
|
||||||
# a blank input either means OK or Abort
|
# a blank input either means OK or Abort
|
||||||
if prev_entry:
|
if prev_entry:
|
||||||
caller.key = prev_entry
|
caller.key = prev_entry
|
||||||
caller.msg("Set name to {}.".format(prev_entry))
|
caller.msg(f"Set name to {prev_entry}.")
|
||||||
return "node_background"
|
return "node_background"
|
||||||
else:
|
else:
|
||||||
caller.msg("Aborted.")
|
caller.msg("Aborted.")
|
||||||
|
|
@ -644,7 +644,7 @@ def _set_name(caller, raw_string, **kwargs):
|
||||||
|
|
||||||
caller.ndb._menutree.charactersheet = {}
|
caller.ndb._menutree.charactersheet = {}
|
||||||
caller.ndb._menutree.charactersheet['name'] = raw_string
|
caller.ndb._menutree.charactersheet['name'] = raw_string
|
||||||
caller.msg("You set your name to {}".format(raw_string)
|
caller.msg(f"You set your name to {raw_string}")
|
||||||
return "background"
|
return "background"
|
||||||
|
|
||||||
def node_set_name(caller):
|
def node_set_name(caller):
|
||||||
|
|
@ -658,7 +658,7 @@ def node_set_name(caller):
|
||||||
|
|
||||||
|
|
||||||
def node_view_sheet(caller):
|
def node_view_sheet(caller):
|
||||||
text = "Character sheet:\n {}".format(self.ndb._menutree.charactersheet)
|
text = f"Character sheet:\n {self.ndb._menutree.charactersheet}"
|
||||||
|
|
||||||
options = ({"key": "Accept",
|
options = ({"key": "Accept",
|
||||||
"goto": "finish_chargen"},
|
"goto": "finish_chargen"},
|
||||||
|
|
|
||||||
|
|
@ -190,7 +190,7 @@ The above could for example be used in a lock function like this:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# we have `obj` and `owner_object` from before
|
# we have `obj` and `owner_object` from before
|
||||||
obj.locks.add("edit: id(%i)" % owner_object.id)
|
obj.locks.add(f"edit: id({owner_object.id})")
|
||||||
```
|
```
|
||||||
|
|
||||||
We could check if the "edit" lock is passed with something like this:
|
We could check if the "edit" lock is passed with something like this:
|
||||||
|
|
|
||||||
|
|
@ -50,9 +50,7 @@ def _monitor_callback(fieldname="", obj=None, **kwargs):
|
||||||
new_value = getattr(obj, fieldname)
|
new_value = getattr(obj, fieldname)
|
||||||
else: # an attribute
|
else: # an attribute
|
||||||
new_value = obj.attributes.get(fieldname)
|
new_value = obj.attributes.get(fieldname)
|
||||||
|
obj.msg(f"{obj.key}.{fieldname} changed to '{new_value}'.")
|
||||||
obj.msg("%s.%s changed to '%s'." % \
|
|
||||||
(obj.key, fieldname, new_value))
|
|
||||||
|
|
||||||
# (we could add _some_other_monitor_callback here too)
|
# (we could add _some_other_monitor_callback here too)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -176,7 +176,7 @@ def red(*args, **kwargs):
|
||||||
"""
|
"""
|
||||||
if not args or len(args) > 1:
|
if not args or len(args) > 1:
|
||||||
raise ValueError("Must have one argument, the text to color red!")
|
raise ValueError("Must have one argument, the text to color red!")
|
||||||
return "|r{}|n".format(args[0])
|
return f"|r{args[0]}|n"
|
||||||
```
|
```
|
||||||
|
|
||||||
> Note that we must make sure to validate input and raise `ValueError` if that fails. Also, it is
|
> Note that we must make sure to validate input and raise `ValueError` if that fails. Also, it is
|
||||||
|
|
|
||||||
|
|
@ -106,10 +106,10 @@ An example of making an asynchronous call from inside a [Command](../Components/
|
||||||
return final_value
|
return final_value
|
||||||
|
|
||||||
def at_return_function(r):
|
def at_return_function(r):
|
||||||
self.caller.msg("The final value is %s" % r)
|
self.caller.msg(f"The final value is {r}")
|
||||||
|
|
||||||
def at_err_function(e):
|
def at_err_function(e):
|
||||||
self.caller.msg("There was an error: %s" % e)
|
self.caller.msg(f"There was an error: {e}")
|
||||||
|
|
||||||
# do the async call, setting all callbacks
|
# do the async call, setting all callbacks
|
||||||
utils.run_async(long_running_function, at_return=at_return_function,
|
utils.run_async(long_running_function, at_return=at_return_function,
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ This is how it looks:
|
||||||
if not MYPROC_ENABLED:
|
if not MYPROC_ENABLED:
|
||||||
return
|
return
|
||||||
# output to list this with the other services at startup
|
# output to list this with the other services at startup
|
||||||
print(" myproc: %s" % MY_PORT)
|
print(f" myproc: {MY_PORT}")
|
||||||
|
|
||||||
# some setup (simple example)
|
# some setup (simple example)
|
||||||
factory = MyOwnFactory()
|
factory = MyOwnFactory()
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,7 @@ Here are some examples
|
||||||
|
|
||||||
```python
|
```python
|
||||||
msg("Hello!") # using the 'text' outputfunc
|
msg("Hello!") # using the 'text' outputfunc
|
||||||
msg(prompt="HP:%i, SP: %i, MP: %i" % (HP, SP, MP))
|
msg(prompt=f"HP: {HP}, SP: {SP}, MP: {MP}")
|
||||||
msg(mycommand=((1,2,3,4), {"foo": "bar"})
|
msg(mycommand=((1,2,3,4), {"foo": "bar"})
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,7 @@ This is important, in order to know what variables we can use in our callback ou
|
||||||
write a single line to be sure our callback is called when we expect it to:
|
write a single line to be sure our callback is called when we expect it to:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
character.msg("You just said {}.".format(message))
|
character.msg(f"You just said {message}.")
|
||||||
```
|
```
|
||||||
|
|
||||||
You can paste this line in-game, then type the `:wq` command to exit the editor and save your
|
You can paste this line in-game, then type the `:wq` command to exit the editor and save your
|
||||||
|
|
|
||||||
|
|
@ -73,8 +73,8 @@ class EditCmd(Command):
|
||||||
if obj.typename == "Room":
|
if obj.typename == "Room":
|
||||||
Menu = RoomBuildingMenu
|
Menu = RoomBuildingMenu
|
||||||
else:
|
else:
|
||||||
self.msg("|rThe object {} cannot be
|
obj_name = obj.get_display_name(self.caller)
|
||||||
edited.|n".format(obj.get_display_name(self.caller)))
|
self.msg(f"|rThe object {obj_name} cannot be edited.|n")
|
||||||
return
|
return
|
||||||
|
|
||||||
menu = Menu(self.caller, obj)
|
menu = Menu(self.caller, obj)
|
||||||
|
|
@ -475,8 +475,7 @@ Excessive spaces will be removed from the left for each line automatically. We
|
||||||
information between braces... sometimes using double braces. What might be a bit odd:
|
information between braces... sometimes using double braces. What might be a bit odd:
|
||||||
|
|
||||||
- `{back}` is a direct format argument we'll use (see the `.format` specifiers).
|
- `{back}` is a direct format argument we'll use (see the `.format` specifiers).
|
||||||
- `{{obj...}} refers to the object being edited. We use two braces, because `.format` will remove
|
- `{{obj...}}` refers to the object being edited. We use two braces, because `.format` will remove them.
|
||||||
them.
|
|
||||||
|
|
||||||
In `glance`, we also use `{obj.key}` to indicate we want to show the room's key.
|
In `glance`, we also use `{obj.key}` to indicate we want to show the room's key.
|
||||||
|
|
||||||
|
|
@ -549,7 +548,7 @@ def glance_exits(room):
|
||||||
if room.exits:
|
if room.exits:
|
||||||
glance = ""
|
glance = ""
|
||||||
for exit in room.exits:
|
for exit in room.exits:
|
||||||
glance += "\n |y{exit}|n".format(exit=exit.key)
|
glance += f"\n |y{exit.key}|n"
|
||||||
|
|
||||||
return glance
|
return glance
|
||||||
|
|
||||||
|
|
@ -648,7 +647,7 @@ def glance_exits(room):
|
||||||
if room.exits:
|
if room.exits:
|
||||||
glance = ""
|
glance = ""
|
||||||
for exit in room.exits:
|
for exit in room.exits:
|
||||||
glance += "\n |y{exit}|n".format(exit=exit.key)
|
glance += f"\n |y{exit.key}|n"
|
||||||
|
|
||||||
return glance
|
return glance
|
||||||
|
|
||||||
|
|
@ -662,12 +661,13 @@ def text_exits(caller, room):
|
||||||
text += "\n\nExisting exits:"
|
text += "\n\nExisting exits:"
|
||||||
if room.exits:
|
if room.exits:
|
||||||
for exit in room.exits:
|
for exit in room.exits:
|
||||||
text += "\n |y@e {exit}|n".format(exit=exit.key)
|
text += f"\n |y@e {exit.key}|n"
|
||||||
if exit.aliases.all():
|
if exit.aliases.all():
|
||||||
text += " (|y{aliases}|n)".format(aliases="|n, |y".join(
|
text += " (|y{aliases}|n)".format(aliases="|n, |y".join(
|
||||||
alias for alias in exit.aliases.all()))
|
alias for alias in exit.aliases.all()
|
||||||
|
))
|
||||||
if exit.destination:
|
if exit.destination:
|
||||||
text += " toward {destination}".format(destination=exit.get_display_name(caller))
|
text += f" toward {exit.get_display_name(caller)}"
|
||||||
else:
|
else:
|
||||||
text += "\n\n |gNo exit has yet been defined.|n"
|
text += "\n\n |gNo exit has yet been defined.|n"
|
||||||
|
|
||||||
|
|
@ -856,21 +856,19 @@ class RoomBuildingMenu(BuildingMenu):
|
||||||
Current title: |c{{obj.key}}|n
|
Current title: |c{{obj.key}}|n
|
||||||
""".format(back="|n or |y".join(self.keys_go_back)))
|
""".format(back="|n or |y".join(self.keys_go_back)))
|
||||||
self.add_choice_edit("description", "d")
|
self.add_choice_edit("description", "d")
|
||||||
self.add_choice("exits", "e", glance=glance_exits, text=text_exits,
|
self.add_choice("exits", "e", glance=glance_exits, text=text_exits, on_nomatch=nomatch_exits)
|
||||||
on_nomatch=nomatch_exits)
|
|
||||||
|
|
||||||
# Exit sub-menu
|
# Exit sub-menu
|
||||||
self.add_choice("exit", "e.*", text=text_single_exit, on_nomatch=nomatch_single_exit)
|
self.add_choice("exit", "e.*", text=text_single_exit, on_nomatch=nomatch_single_exit)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Menu functions
|
# Menu functions
|
||||||
def glance_exits(room):
|
def glance_exits(room):
|
||||||
"""Show the room exits."""
|
"""Show the room exits."""
|
||||||
if room.exits:
|
if room.exits:
|
||||||
glance = ""
|
glance = ""
|
||||||
for exit in room.exits:
|
for exit in room.exits:
|
||||||
glance += "\n |y{exit}|n".format(exit=exit.key)
|
glance += f"\n |y{exit.key}|n"
|
||||||
|
|
||||||
return glance
|
return glance
|
||||||
|
|
||||||
|
|
@ -884,12 +882,13 @@ def text_exits(caller, room):
|
||||||
text += "\n\nExisting exits:"
|
text += "\n\nExisting exits:"
|
||||||
if room.exits:
|
if room.exits:
|
||||||
for exit in room.exits:
|
for exit in room.exits:
|
||||||
text += "\n |y@e {exit}|n".format(exit=exit.key)
|
text += f"\n |y@e {exit.key}|n"
|
||||||
if exit.aliases.all():
|
if exit.aliases.all():
|
||||||
text += " (|y{aliases}|n)".format(aliases="|n, |y".join(
|
text += " (|y{aliases}|n)".format(aliases="|n, |y".join(
|
||||||
alias for alias in exit.aliases.all()))
|
alias for alias in exit.aliases.all()
|
||||||
|
))
|
||||||
if exit.destination:
|
if exit.destination:
|
||||||
text += " toward {destination}".format(destination=exit.get_display_name(caller))
|
text += f" toward {exit.get_display_name(caller)}"
|
||||||
else:
|
else:
|
||||||
text += "\n\n |gNo exit has yet been defined.|n"
|
text += "\n\n |gNo exit has yet been defined.|n"
|
||||||
|
|
||||||
|
|
@ -905,7 +904,7 @@ def nomatch_exits(menu, caller, room, string):
|
||||||
return
|
return
|
||||||
|
|
||||||
# Open a sub-menu, using nested keys
|
# Open a sub-menu, using nested keys
|
||||||
caller.msg("Editing: {}".format(exit.key))
|
caller.msg(f"Editing: {exit.key}")
|
||||||
menu.move(exit)
|
menu.move(exit)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
@ -916,13 +915,13 @@ def text_single_exit(menu, caller):
|
||||||
if exit is None:
|
if exit is None:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
return """
|
return f"""
|
||||||
Exit {exit}:
|
Exit {exit.key}:
|
||||||
|
|
||||||
Enter the exit key to change it, or |y@|n to go back.
|
Enter the exit key to change it, or |y@|n to go back.
|
||||||
|
|
||||||
New exit key:
|
New exit key:
|
||||||
""".format(exit=exit.key)
|
"""
|
||||||
|
|
||||||
def nomatch_single_exit(menu, caller, room, string):
|
def nomatch_single_exit(menu, caller, room, string):
|
||||||
"""The user entered something in the exit sub-menu. Replace the exit key."""
|
"""The user entered something in the exit sub-menu. Replace the exit key."""
|
||||||
|
|
@ -1012,7 +1011,7 @@ def glance_exits(room):
|
||||||
if room.exits:
|
if room.exits:
|
||||||
glance = ""
|
glance = ""
|
||||||
for exit in room.exits:
|
for exit in room.exits:
|
||||||
glance += "\n |y{exit}|n".format(exit=exit.key)
|
glance += f"\n |y{exit.key}|n"
|
||||||
|
|
||||||
return glance
|
return glance
|
||||||
|
|
||||||
|
|
@ -1026,12 +1025,13 @@ def text_exits(caller, room):
|
||||||
text += "\n\nExisting exits:"
|
text += "\n\nExisting exits:"
|
||||||
if room.exits:
|
if room.exits:
|
||||||
for exit in room.exits:
|
for exit in room.exits:
|
||||||
text += "\n |y@e {exit}|n".format(exit=exit.key)
|
text += f"\n |y@e {exit.key}|n"
|
||||||
if exit.aliases.all():
|
if exit.aliases.all():
|
||||||
text += " (|y{aliases}|n)".format(aliases="|n, |y".join(
|
text += " (|y{aliases}|n)".format(aliases="|n, |y".join(
|
||||||
alias for alias in exit.aliases.all()))
|
alias for alias in exit.aliases.all()
|
||||||
|
))
|
||||||
if exit.destination:
|
if exit.destination:
|
||||||
text += " toward {destination}".format(destination=exit.get_display_name(caller))
|
text += f" toward {exit.get_display_name(caller)}"
|
||||||
else:
|
else:
|
||||||
text += "\n\n |gNo exit has yet been defined.|n"
|
text += "\n\n |gNo exit has yet been defined.|n"
|
||||||
|
|
||||||
|
|
@ -1047,7 +1047,7 @@ def nomatch_exits(menu, caller, room, string):
|
||||||
return
|
return
|
||||||
|
|
||||||
# Open a sub-menu, using nested keys
|
# Open a sub-menu, using nested keys
|
||||||
caller.msg("Editing: {}".format(exit.key))
|
caller.msg(f"Editing: {exit.key}")
|
||||||
menu.open_submenu("commands.building.ExitBuildingMenu", exit, parent_keys=["e"])
|
menu.open_submenu("commands.building.ExitBuildingMenu", exit, parent_keys=["e"])
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -346,7 +346,7 @@ class Room(DefaultRoom):
|
||||||
|
|
||||||
def return_appearance(self, looker):
|
def return_appearance(self, looker):
|
||||||
# [...]
|
# [...]
|
||||||
string = "%s\n" % Map(looker).show_map()
|
string = f"{Map(looker).show_map()}\n"
|
||||||
# Add all the normal stuff like room description,
|
# Add all the normal stuff like room description,
|
||||||
# contents, exits etc.
|
# contents, exits etc.
|
||||||
string += "\n" + super().return_appearance(looker)
|
string += "\n" + super().return_appearance(looker)
|
||||||
|
|
|
||||||
|
|
@ -99,8 +99,9 @@ class CmdShoot(Command):
|
||||||
# we have an argument, search for target
|
# we have an argument, search for target
|
||||||
target = caller.search(self.args.strip())
|
target = caller.search(self.args.strip())
|
||||||
if target:
|
if target:
|
||||||
message = "BOOM! The mech fires its gun at %s" % target.key
|
location.msg_contents(
|
||||||
location.msg_contents(message)
|
f"BOOM! The mech fires its gun at {target.key}"
|
||||||
|
)
|
||||||
|
|
||||||
class CmdLaunch(Command):
|
class CmdLaunch(Command):
|
||||||
# make your own 'launch'-command here as an exercise!
|
# make your own 'launch'-command here as an exercise!
|
||||||
|
|
|
||||||
|
|
@ -78,19 +78,18 @@ channel send. Edit `mygame/typeclasses/channels.py` (and then `@reload`):
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# define our custom color names
|
# define our custom color names
|
||||||
CHANNEL_COLORS = {'public': '|015Public|n',
|
CHANNEL_COLORS = {"public": "|015Public|n",
|
||||||
'newbie': '|550N|n|551e|n|552w|n|553b|n|554i|n|555e|n',
|
"newbie": "|550N|n|551e|n|552w|n|553b|n|554i|n|555e|n",
|
||||||
'staff': '|010S|n|020t|n|030a|n|040f|n|050f|n'}
|
"staff": "|010S|n|020t|n|030a|n|040f|n|050f|n"}
|
||||||
|
|
||||||
# Add to the Channel class
|
# Add to the Channel class
|
||||||
# ...
|
# ...
|
||||||
def channel_prefix(self, msg, emit=False):
|
def channel_prefix(self, msg, emit=False):
|
||||||
prefix_string = ""
|
|
||||||
if self.key in COLORS:
|
if self.key in COLORS:
|
||||||
prefix_string = "[%s] " % CHANNEL_COLORS.get(self.key.lower())
|
p_str = CHANNEL_COLORS.get(self.key.lower())
|
||||||
else:
|
else:
|
||||||
prefix_string = "[%s] " % self.key.capitalize()
|
p_str = self.key.capitalize()
|
||||||
return prefix_string
|
return f"[{p_str}] "
|
||||||
```
|
```
|
||||||
Additional hint: To make colors easier to change from one place you could instead put the
|
Additional hint: To make colors easier to change from one place you could instead put the
|
||||||
`CHANNEL_COLORS` dict in your settings file and import it as `from django.conf.settings import
|
`CHANNEL_COLORS` dict in your settings file and import it as `from django.conf.settings import
|
||||||
|
|
|
||||||
|
|
@ -82,16 +82,16 @@ class CmdEcho(default_cmds.MuxCommand):
|
||||||
"""
|
"""
|
||||||
This is called at the initial shout.
|
This is called at the initial shout.
|
||||||
"""
|
"""
|
||||||
self.caller.msg("You shout '%s' and wait for an echo ..." % self.args)
|
self.caller.msg(f"You shout '{self.args}' and wait for an echo ...")
|
||||||
# this waits non-blocking for 10 seconds, then calls self.echo
|
# this waits non-blocking for 10 seconds, then calls self.echo
|
||||||
utils.delay(10, self.echo) # call echo after 10 seconds
|
utils.delay(10, self.echo) # call echo after 10 seconds
|
||||||
|
|
||||||
def echo(self):
|
def echo(self):
|
||||||
"Called after 10 seconds."
|
"Called after 10 seconds."
|
||||||
shout = self.args
|
shout = self.args
|
||||||
string = "You hear an echo: %s ... %s ... %s"
|
self.caller.msg(
|
||||||
string = string % (shout.upper(), shout.capitalize(), shout.lower())
|
f"You hear an echo: {shout.upper()} ... {shout.capitalize()} ... {shout.lower()}"
|
||||||
self.caller.msg(string)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
Import this new echo command into the default command set and reload the server. You will find that
|
Import this new echo command into the default command set and reload the server. You will find that
|
||||||
|
|
@ -146,7 +146,7 @@ class CmdEcho(default_cmds.MuxCommand):
|
||||||
|
|
||||||
def func(self):
|
def func(self):
|
||||||
"This sets off a chain of delayed calls"
|
"This sets off a chain of delayed calls"
|
||||||
self.caller.msg("You shout '%s', waiting for an echo ..." % self.args)
|
self.caller.msg(f"You shout '{self.args}', waiting for an echo ...")
|
||||||
|
|
||||||
# wait 2 seconds before calling self.echo1
|
# wait 2 seconds before calling self.echo1
|
||||||
utils.delay(2, self.echo1)
|
utils.delay(2, self.echo1)
|
||||||
|
|
@ -154,19 +154,19 @@ class CmdEcho(default_cmds.MuxCommand):
|
||||||
# callback chain, started above
|
# callback chain, started above
|
||||||
def echo1(self):
|
def echo1(self):
|
||||||
"First echo"
|
"First echo"
|
||||||
self.caller.msg("... %s" % self.args.upper())
|
self.caller.msg(f"... {self.args.upper()}")
|
||||||
# wait 2 seconds for the next one
|
# wait 2 seconds for the next one
|
||||||
utils.delay(2, self.echo2)
|
utils.delay(2, self.echo2)
|
||||||
|
|
||||||
def echo2(self):
|
def echo2(self):
|
||||||
"Second echo"
|
"Second echo"
|
||||||
self.caller.msg("... %s" % self.args.capitalize())
|
self.caller.msg(f"... {self.args.capitalize()}")
|
||||||
# wait another 2 seconds
|
# wait another 2 seconds
|
||||||
utils.delay(2, callback=self.echo3)
|
utils.delay(2, callback=self.echo3)
|
||||||
|
|
||||||
def echo3(self):
|
def echo3(self):
|
||||||
"Last echo"
|
"Last echo"
|
||||||
self.caller.msg("... %s ..." % self.args.lower())
|
self.caller.msg(f"... {self.args.lower()} ...")
|
||||||
```
|
```
|
||||||
|
|
||||||
The above version will have the echoes arrive one after another, each separated by a two second
|
The above version will have the echoes arrive one after another, each separated by a two second
|
||||||
|
|
@ -364,9 +364,9 @@ from evennia import default_cmds, utils
|
||||||
def echo(caller, args):
|
def echo(caller, args):
|
||||||
"Called after 10 seconds."
|
"Called after 10 seconds."
|
||||||
shout = args
|
shout = args
|
||||||
string = "You hear an echo: %s ... %s ... %s"
|
caller.msg(
|
||||||
string = string % (shout.upper(), shout.capitalize(), shout.lower())
|
f"You hear an echo: {shout.upper()} ... {shout.capitalize()} ... {shout.lower()}"
|
||||||
caller.msg(string)
|
)
|
||||||
|
|
||||||
class CmdEcho(default_cmds.MuxCommand):
|
class CmdEcho(default_cmds.MuxCommand):
|
||||||
"""
|
"""
|
||||||
|
|
@ -384,7 +384,7 @@ class CmdEcho(default_cmds.MuxCommand):
|
||||||
"""
|
"""
|
||||||
This is called at the initial shout.
|
This is called at the initial shout.
|
||||||
"""
|
"""
|
||||||
self.caller.msg("You shout '%s' and wait for an echo ..." % self.args)
|
self.caller.msg(f"You shout '{self.args}' and wait for an echo ...")
|
||||||
# this waits non-blocking for 10 seconds, then calls echo(self.caller, self.args)
|
# this waits non-blocking for 10 seconds, then calls echo(self.caller, self.args)
|
||||||
utils.delay(10, echo, self.caller, self.args, persistent=True) # changes!
|
utils.delay(10, echo, self.caller, self.args, persistent=True) # changes!
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,10 +59,8 @@ Here is a simple example of the prompt sent/updated from a command class:
|
||||||
self.caller.msg("Not a valid target!")
|
self.caller.msg("Not a valid target!")
|
||||||
return
|
return
|
||||||
|
|
||||||
text = "You diagnose %s as having " \
|
text = f"You diagnose {target} as having {hp} health, {mp} mana and {sp} stamina."
|
||||||
"%i health, %i mana and %i stamina." \
|
prompt = f"{hp} HP, {mp} MP, {sp} SP"
|
||||||
% (hp, mp, sp)
|
|
||||||
prompt = "%i HP, %i MP, %i SP" % (hp, mp, sp)
|
|
||||||
self.caller.msg(text, prompt=prompt)
|
self.caller.msg(text, prompt=prompt)
|
||||||
```
|
```
|
||||||
## A prompt sent with every command
|
## A prompt sent with every command
|
||||||
|
|
@ -86,9 +84,7 @@ class MuxCommand(default_cmds.MuxCommand):
|
||||||
def at_post_cmd(self):
|
def at_post_cmd(self):
|
||||||
"called after self.func()."
|
"called after self.func()."
|
||||||
caller = self.caller
|
caller = self.caller
|
||||||
prompt = "%i HP, %i MP, %i SP" % (caller.db.hp,
|
prompt = f"{caller.db.hp} HP, {caller.db.mp} MP, {caller.db.sp} SP"
|
||||||
caller.db.mp,
|
|
||||||
caller.db.sp)
|
|
||||||
caller.msg(prompt=prompt)
|
caller.msg(prompt=prompt)
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ class CmdExitError(default_cmds.MuxCommand):
|
||||||
auto_help = False
|
auto_help = False
|
||||||
def func(self):
|
def func(self):
|
||||||
"returns the error"
|
"returns the error"
|
||||||
self.caller.msg("You cannot move %s." % self.key)
|
self.caller.msg(f"You cannot move {self.key}.")
|
||||||
|
|
||||||
class CmdExitErrorNorth(CmdExitError):
|
class CmdExitErrorNorth(CmdExitError):
|
||||||
key = "north"
|
key = "north"
|
||||||
|
|
|
||||||
|
|
@ -127,15 +127,14 @@ class Character(DefaultCharacter):
|
||||||
|
|
||||||
if selfaccount and selfaccount.db.is_gm:
|
if selfaccount and selfaccount.db.is_gm:
|
||||||
# A GM. Show name as name(GM)
|
# A GM. Show name as name(GM)
|
||||||
name = "%s(GM)" % name
|
name = f"{name}(GM)"
|
||||||
|
|
||||||
if lookaccount and \
|
if lookaccount and \
|
||||||
(lookaccount.permissions.get("Developers") or lookaccount.db.is_gm):
|
(lookaccount.permissions.get("Developers") or lookaccount.db.is_gm):
|
||||||
# Developers/GMs see name(#dbref) or name(GM)(#dbref)
|
# Developers/GMs see name(#dbref) or name(GM)(#dbref)
|
||||||
return "%s(#%s)" % (name, self.id)
|
name = f"{name}(#{self.id})"
|
||||||
else:
|
|
||||||
return name
|
|
||||||
|
|
||||||
|
return name
|
||||||
```
|
```
|
||||||
|
|
||||||
Above, we change how the Character's name is displayed: If the account controlling this Character is
|
Above, we change how the Character's name is displayed: If the account controlling this Character is
|
||||||
|
|
@ -192,10 +191,10 @@ class CmdMakeGM(default_cmds.MuxCommand):
|
||||||
|
|
||||||
accountlist = evennia.search_account(self.args) # returns a list
|
accountlist = evennia.search_account(self.args) # returns a list
|
||||||
if not accountlist:
|
if not accountlist:
|
||||||
caller.msg("Could not find account '%s'" % self.args)
|
caller.msg(f"Could not find account '{self.args}'")
|
||||||
return
|
return
|
||||||
elif len(accountlist) > 1:
|
elif len(accountlist) > 1:
|
||||||
caller.msg("Multiple matches for '%s': %s" % (self.args, accountlist))
|
caller.msg(f"Multiple matches for '{self.args}': {accountlist}")
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
account = accountlist[0]
|
account = accountlist[0]
|
||||||
|
|
@ -203,20 +202,20 @@ class CmdMakeGM(default_cmds.MuxCommand):
|
||||||
if self.cmdstring == "gm":
|
if self.cmdstring == "gm":
|
||||||
# turn someone into a GM
|
# turn someone into a GM
|
||||||
if account.permissions.get("Admins"):
|
if account.permissions.get("Admins"):
|
||||||
caller.msg("Account %s is already a GM." % account)
|
caller.msg(f"Account {account} is already a GM.")
|
||||||
else:
|
else:
|
||||||
account.permissions.add("Admins")
|
account.permissions.add("Admins")
|
||||||
caller.msg("Account %s is now a GM." % account)
|
caller.msg(f"Account {account} is now a GM.")
|
||||||
account.msg("You are now a GM (changed by %s)." % caller)
|
account.msg(f"You are now a GM (changed by {caller}).")
|
||||||
account.character.db.is_gm = True
|
account.character.db.is_gm = True
|
||||||
else:
|
else:
|
||||||
# @ungm was entered - revoke GM status from someone
|
# @ungm was entered - revoke GM status from someone
|
||||||
if not account.permissions.get("Admins"):
|
if not account.permissions.get("Admins"):
|
||||||
caller.msg("Account %s is not a GM." % account)
|
caller.msg(f"Account {account} is not a GM.")
|
||||||
else:
|
else:
|
||||||
account.permissions.remove("Admins")
|
account.permissions.remove("Admins")
|
||||||
caller.msg("Account %s is no longer a GM." % account)
|
caller.msg(f"Account {account} is no longer a GM.")
|
||||||
account.msg("You are no longer a GM (changed by %s)." % caller)
|
account.msg(f"You are no longer a GM (changed by {caller}).")
|
||||||
del account.character.db.is_gm
|
del account.character.db.is_gm
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
@ -511,11 +510,12 @@ ALLOWED_FIELDNAMES = ALLOWED_ATTRS + \
|
||||||
def _validate_fieldname(caller, fieldname):
|
def _validate_fieldname(caller, fieldname):
|
||||||
"Helper function to validate field names."
|
"Helper function to validate field names."
|
||||||
if fieldname not in ALLOWED_FIELDNAMES:
|
if fieldname not in ALLOWED_FIELDNAMES:
|
||||||
err = "Allowed field names: %s" % (", ".join(ALLOWED_FIELDNAMES))
|
list_of_fieldnames = ", ".join(ALLOWED_FIELDNAMES)
|
||||||
|
err = f"Allowed field names: {list_of_fieldnames}"
|
||||||
caller.msg(err)
|
caller.msg(err)
|
||||||
return False
|
return False
|
||||||
if fieldname in ALLOWED_ATTRS and not value.isdigit():
|
if fieldname in ALLOWED_ATTRS and not value.isdigit():
|
||||||
caller.msg("%s must receive a number." % fieldname)
|
caller.msg(f"{fieldname} must receive a number.")
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
@ -570,7 +570,7 @@ class CmdSheet(MuxCommand):
|
||||||
else:
|
else:
|
||||||
caller.chardata[fieldname] = value
|
caller.chardata[fieldname] = value
|
||||||
caller.update_charsheet()
|
caller.update_charsheet()
|
||||||
caller.msg("%s was set to %s." % (fieldname, value))
|
caller.msg(f"{fieldname} was set to {value}.")
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -641,13 +641,13 @@ class CmdGMsheet(MuxCommand):
|
||||||
caller.msg("The character sheet is already locked.")
|
caller.msg("The character sheet is already locked.")
|
||||||
else:
|
else:
|
||||||
character.db.sheet_locked = True
|
character.db.sheet_locked = True
|
||||||
caller.msg("%s can no longer edit their character sheet." % character.key)
|
caller.msg(f"{character.key} can no longer edit their character sheet.")
|
||||||
elif "unlock" in self.switches:
|
elif "unlock" in self.switches:
|
||||||
if not character.db.sheet_locked:
|
if not character.db.sheet_locked:
|
||||||
caller.msg("The character sheet is already unlocked.")
|
caller.msg("The character sheet is already unlocked.")
|
||||||
else:
|
else:
|
||||||
character.db.sheet_locked = False
|
character.db.sheet_locked = False
|
||||||
caller.msg("%s can now edit their character sheet." % character.key)
|
caller.msg(f"{character.key} can now edit their character sheet.")
|
||||||
|
|
||||||
if fieldname:
|
if fieldname:
|
||||||
if fieldname == "name":
|
if fieldname == "name":
|
||||||
|
|
@ -655,7 +655,7 @@ class CmdGMsheet(MuxCommand):
|
||||||
else:
|
else:
|
||||||
character.db.chardata[fieldname] = value
|
character.db.chardata[fieldname] = value
|
||||||
character.update_charsheet()
|
character.update_charsheet()
|
||||||
caller.msg("You set %s's %s to %s." % (character.key, fieldname, value)
|
caller.msg(f"You set {character.key}'s {fieldname} to {value}.")
|
||||||
else:
|
else:
|
||||||
# just display
|
# just display
|
||||||
caller.msg(character.db.charsheet)
|
caller.msg(character.db.charsheet)
|
||||||
|
|
|
||||||
|
|
@ -252,11 +252,10 @@ class CmdTime(Command):
|
||||||
def func(self):
|
def func(self):
|
||||||
"""Execute the time command."""
|
"""Execute the time command."""
|
||||||
# Get the absolute game time
|
# Get the absolute game time
|
||||||
year, month, day, hour, min, sec = custom_gametime.custom_gametime(absolute=True)
|
year, month, day, hour, mins, secs = custom_gametime.custom_gametime(absolute=True)
|
||||||
string = "We are in year {year}, day {day}, month {month}."
|
time_string = f"We are in year {year}, day {day}, month {month}."
|
||||||
string += "\nIt's {hour:02}:{min:02}:{sec:02}."
|
time_string += f"\nIt's {hour:02}:{mins:02}:{secs:02}."
|
||||||
self.msg(string.format(year=year, month=month, day=day,
|
self.msg(time_string)
|
||||||
hour=hour, min=min, sec=sec))
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Don't forget to add it in your CharacterCmdSet to see this command:
|
Don't forget to add it in your CharacterCmdSet to see this command:
|
||||||
|
|
|
||||||
|
|
@ -87,10 +87,12 @@ class CmdInventory(MuxCommand):
|
||||||
table.border = False
|
table.border = False
|
||||||
for item in items:
|
for item in items:
|
||||||
second = item.get_mass() \
|
second = item.get_mass() \
|
||||||
if 'weight' in self.switches else item.db.desc
|
if "weight" in self.switches else item.db.desc
|
||||||
table.add_row(["%s" % item.get_display_name(self.caller.sessions),
|
table.add_row([
|
||||||
second and second or ""])
|
str(item.get_display_name(self.caller.sessions)),
|
||||||
string = "|wYou are carrying:\n%s" % table
|
second and second or "",
|
||||||
|
])
|
||||||
|
string = f"|wYou are carrying:\n{table}"
|
||||||
self.caller.msg(string)
|
self.caller.msg(string)
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
@ -86,18 +86,17 @@ def menunode_shopfront(caller):
|
||||||
# door! Let's remove that from our for sale list.
|
# door! Let's remove that from our for sale list.
|
||||||
wares = [ware for ware in wares if ware.key.lower() != "door"]
|
wares = [ware for ware in wares if ware.key.lower() != "door"]
|
||||||
|
|
||||||
text = "*** Welcome to %s! ***\n" % shopname
|
text = f"*** Welcome to {shopname}! ***\n"
|
||||||
if wares:
|
if wares:
|
||||||
text += " Things for sale (choose 1-%i to inspect);" \
|
text += f" Things for sale (choose 1-{len(wares)} to inspect); quit to exit:"
|
||||||
" quit to exit:" % len(wares)
|
|
||||||
else:
|
else:
|
||||||
text += " There is nothing for sale; quit to exit."
|
text += " There is nothing for sale; quit to exit."
|
||||||
|
|
||||||
options = []
|
options = []
|
||||||
for ware in wares:
|
for ware in wares:
|
||||||
# add an option for every ware in store
|
# add an option for every ware in store
|
||||||
options.append({"desc": "%s (%s gold)" %
|
gold_val = ware.db.gold_value or 1
|
||||||
(ware.key, ware.db.gold_value or 1),
|
options.append({"desc": f"{ware.key} ({gold_val} gold)",
|
||||||
"goto": "menunode_inspect_and_buy"})
|
"goto": "menunode_inspect_and_buy"})
|
||||||
return text, options
|
return text, options
|
||||||
```
|
```
|
||||||
|
|
@ -124,26 +123,27 @@ def menunode_inspect_and_buy(caller, raw_string):
|
||||||
ware = wares[iware]
|
ware = wares[iware]
|
||||||
value = ware.db.gold_value or 1
|
value = ware.db.gold_value or 1
|
||||||
wealth = caller.db.gold or 0
|
wealth = caller.db.gold or 0
|
||||||
text = "You inspect %s:\n\n%s" % (ware.key, ware.db.desc)
|
text = f"You inspect {ware.key}:\n\n{ware.db.desc}"
|
||||||
|
|
||||||
def buy_ware_result(caller):
|
def buy_ware_result(caller):
|
||||||
"This will be executed first when choosing to buy."
|
"This will be executed first when choosing to buy."
|
||||||
if wealth >= value:
|
if wealth >= value:
|
||||||
rtext = "You pay %i gold and purchase %s!" % \
|
rtext = f"You pay {value} gold and purchase {ware.key}!"
|
||||||
(value, ware.key)
|
|
||||||
caller.db.gold -= value
|
caller.db.gold -= value
|
||||||
ware.move_to(caller, quiet=True)
|
ware.move_to(caller, quiet=True)
|
||||||
else:
|
else:
|
||||||
rtext = "You cannot afford %i gold for %s!" % \
|
rtext = f"You cannot afford {value} gold for {ware.key}!"
|
||||||
(value, ware.key)
|
|
||||||
caller.msg(rtext)
|
caller.msg(rtext)
|
||||||
|
|
||||||
options = ({"desc": "Buy %s for %s gold" % \
|
gold_val = ware.db.gold_value or 1
|
||||||
(ware.key, ware.db.gold_value or 1),
|
options = ({
|
||||||
"goto": "menunode_shopfront",
|
"desc": f"Buy {ware.key} for {gold_val} gold",
|
||||||
"exec": buy_ware_result},
|
"goto": "menunode_shopfront",
|
||||||
{"desc": "Look for something else",
|
"exec": buy_ware_result,
|
||||||
"goto": "menunode_shopfront"})
|
}, {
|
||||||
|
"desc": "Look for something else",
|
||||||
|
"goto": "menunode_shopfront",
|
||||||
|
})
|
||||||
|
|
||||||
return text, options
|
return text, options
|
||||||
```
|
```
|
||||||
|
|
@ -267,7 +267,7 @@ class CmdBuildShop(Command):
|
||||||
key=shopname,
|
key=shopname,
|
||||||
location=None)
|
location=None)
|
||||||
storeroom = create_object(DefaultRoom,
|
storeroom = create_object(DefaultRoom,
|
||||||
key="%s-storage" % shopname,
|
key=f"{shopname}-storage",
|
||||||
location=None)
|
location=None)
|
||||||
shop.db.storeroom = storeroom
|
shop.db.storeroom = storeroom
|
||||||
# create a door between the two
|
# create a door between the two
|
||||||
|
|
@ -281,15 +281,15 @@ class CmdBuildShop(Command):
|
||||||
location=storeroom,
|
location=storeroom,
|
||||||
destination=shop)
|
destination=shop)
|
||||||
# make a key for accessing the store room
|
# make a key for accessing the store room
|
||||||
storeroom_key_name = "%s-storekey" % shopname
|
storeroom_key_name = f"{shopname}-storekey"
|
||||||
storeroom_key = create_object(DefaultObject,
|
storeroom_key = create_object(DefaultObject,
|
||||||
key=storeroom_key_name,
|
key=storeroom_key_name,
|
||||||
location=shop)
|
location=shop)
|
||||||
# only allow chars with this key to enter the store room
|
# only allow chars with this key to enter the store room
|
||||||
shop_exit.locks.add("traverse:holds(%s)" % storeroom_key_name)
|
shop_exit.locks.add(f"traverse:holds({storeroom_key_name})")
|
||||||
|
|
||||||
# inform the builder about progress
|
# inform the builder about progress
|
||||||
self.caller.msg("The shop %s was created!" % shop)
|
self.caller.msg(f"The shop {shop} was created!")
|
||||||
```
|
```
|
||||||
|
|
||||||
Our typeclass is simple and so is our `buildshop` command. The command (which is for Builders only)
|
Our typeclass is simple and so is our `buildshop` command. The command (which is for Builders only)
|
||||||
|
|
|
||||||
|
|
@ -172,7 +172,7 @@ def add_XP(character, amount):
|
||||||
character.db.level += 1
|
character.db.level += 1
|
||||||
character.db.STR += 1
|
character.db.STR += 1
|
||||||
character.db.combat += 2
|
character.db.combat += 2
|
||||||
character.msg("You are now level %i!" % character.db.level)
|
character.msg(f"You are now level {character.db.level}!")
|
||||||
|
|
||||||
def skill_combat(*args):
|
def skill_combat(*args):
|
||||||
"""
|
"""
|
||||||
|
|
@ -182,24 +182,24 @@ def skill_combat(*args):
|
||||||
"""
|
"""
|
||||||
char1, char2 = args
|
char1, char2 = args
|
||||||
roll1, roll2 = roll_hit(), roll_hit()
|
roll1, roll2 = roll_hit(), roll_hit()
|
||||||
failtext = "You are hit by %s for %i damage!"
|
failtext_template = "You are hit by {attacker} for {dmg} damage!"
|
||||||
wintext = "You hit %s for %i damage!"
|
wintext_template = "You hit {target} for {dmg} damage!"
|
||||||
xp_gain = randint(1, 3)
|
xp_gain = randint(1, 3)
|
||||||
if char1.db.combat >= roll1 > roll2:
|
if char1.db.combat >= roll1 > roll2:
|
||||||
# char 1 hits
|
# char 1 hits
|
||||||
dmg = roll_dmg() + char1.db.STR
|
dmg = roll_dmg() + char1.db.STR
|
||||||
char1.msg(wintext % (char2, dmg))
|
char1.msg(wintext_template.format(target=char2, dmg=dmg))
|
||||||
add_XP(char1, xp_gain)
|
add_XP(char1, xp_gain)
|
||||||
char2.msg(failtext % (char1, dmg))
|
char2.msg(failtext_template.format(attacker=char1, dmg=dmg))
|
||||||
char2.db.HP -= dmg
|
char2.db.HP -= dmg
|
||||||
check_defeat(char2)
|
check_defeat(char2)
|
||||||
elif char2.db.combat >= roll2 > roll1:
|
elif char2.db.combat >= roll2 > roll1:
|
||||||
# char 2 hits
|
# char 2 hits
|
||||||
dmg = roll_dmg() + char2.db.STR
|
dmg = roll_dmg() + char2.db.STR
|
||||||
char1.msg(failtext % (char2, dmg))
|
char1.msg(failtext_template.format(attacker=char2, dmg=dmg))
|
||||||
char1.db.HP -= dmg
|
char1.db.HP -= dmg
|
||||||
check_defeat(char1)
|
check_defeat(char1)
|
||||||
char2.msg(wintext % (char1, dmg))
|
char2.msg(wintext_template.format(target=char1, dmg=dmg))
|
||||||
add_XP(char2, xp_gain)
|
add_XP(char2, xp_gain)
|
||||||
else:
|
else:
|
||||||
# a draw
|
# a draw
|
||||||
|
|
@ -217,7 +217,7 @@ def roll_challenge(character1, character2, skillname):
|
||||||
if skillname in SKILLS:
|
if skillname in SKILLS:
|
||||||
SKILLS[skillname](character1, character2)
|
SKILLS[skillname](character1, character2)
|
||||||
else:
|
else:
|
||||||
raise RunTimeError("Skillname %s not found." % skillname)
|
raise RunTimeError(f"Skillname {skillname} not found.")
|
||||||
```
|
```
|
||||||
|
|
||||||
These few functions implement the entirety of our simple rule system. We have a function to check
|
These few functions implement the entirety of our simple rule system. We have a function to check
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,7 @@ class CombatHandler(DefaultScript):
|
||||||
def at_script_creation(self):
|
def at_script_creation(self):
|
||||||
"Called when script is first created"
|
"Called when script is first created"
|
||||||
|
|
||||||
self.key = "combat_handler_%i" % random.randint(1, 1000)
|
self.key = f"combat_handler_{random.randint(1, 1000)}"
|
||||||
self.desc = "handles combat"
|
self.desc = "handles combat"
|
||||||
self.interval = 60 * 2 # two minute timeout
|
self.interval = 60 * 2 # two minute timeout
|
||||||
self.start_delay = True
|
self.start_delay = True
|
||||||
|
|
@ -400,57 +400,58 @@ def resolve_combat(combat_handler, actiondict):
|
||||||
taction, tchar, ttarget = actiondict[target.id][isub]
|
taction, tchar, ttarget = actiondict[target.id][isub]
|
||||||
if action == "hit":
|
if action == "hit":
|
||||||
if taction == "parry" and ttarget == char:
|
if taction == "parry" and ttarget == char:
|
||||||
msg = "%s tries to hit %s, but %s parries the attack!"
|
messages.append(
|
||||||
messages.append(msg % (char, tchar, tchar))
|
f"{char} tries to hit {tchar}, but {tchar} parries the attack!"
|
||||||
|
)
|
||||||
elif taction == "defend" and random.random() < 0.5:
|
elif taction == "defend" and random.random() < 0.5:
|
||||||
msg = "%s defends against the attack by %s."
|
messages.append(
|
||||||
messages.append(msg % (tchar, char))
|
f"{tchar} defends against the attack by {char}."
|
||||||
|
)
|
||||||
elif taction == "flee":
|
elif taction == "flee":
|
||||||
msg = "%s stops %s from disengaging, with a hit!"
|
|
||||||
flee[tchar] = -2
|
flee[tchar] = -2
|
||||||
messages.append(msg % (char, tchar))
|
messages.append(
|
||||||
|
f"{char} stops {tchar} from disengaging, with a hit!"
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
msg = "%s hits %s, bypassing their %s!"
|
messages.append(
|
||||||
messages.append(msg % (char, tchar, taction))
|
f"{char} hits {tchar}, bypassing their {taction}!"
|
||||||
|
)
|
||||||
elif action == "parry":
|
elif action == "parry":
|
||||||
if taction == "hit":
|
if taction == "hit":
|
||||||
msg = "%s parries the attack by %s."
|
messages.append(f"{char} parries the attack by {tchar}.")
|
||||||
messages.append(msg % (char, tchar))
|
|
||||||
elif taction == "feint":
|
elif taction == "feint":
|
||||||
msg = "%s tries to parry, but %s feints and hits!"
|
messages.append(
|
||||||
messages.append(msg % (char, tchar))
|
f"{char} tries to parry, but {tchar} feints and hits!"
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
msg = "%s parries to no avail."
|
messages.append(f"{char} parries to no avail.")
|
||||||
messages.append(msg % char)
|
|
||||||
elif action == "feint":
|
elif action == "feint":
|
||||||
if taction == "parry":
|
if taction == "parry":
|
||||||
msg = "%s feints past %s's parry, landing a hit!"
|
messages.append(
|
||||||
messages.append(msg % (char, tchar))
|
f"{char} feints past {tchar}'s parry, landing a hit!"
|
||||||
|
)
|
||||||
elif taction == "hit":
|
elif taction == "hit":
|
||||||
msg = "%s feints but is defeated by %s hit!"
|
messages.append(f"{char} feints but is defeated by {tchar}'s hit!")
|
||||||
messages.append(msg % (char, tchar))
|
|
||||||
else:
|
else:
|
||||||
msg = "%s feints to no avail."
|
messages.append(f"{char} feints to no avail.")
|
||||||
messages.append(msg % char)
|
|
||||||
elif action == "defend":
|
elif action == "defend":
|
||||||
msg = "%s defends."
|
messages.append(f"{char} defends.")
|
||||||
messages.append(msg % char)
|
|
||||||
elif action == "flee":
|
elif action == "flee":
|
||||||
if char in flee:
|
if char in flee:
|
||||||
flee[char] += 1
|
flee[char] += 1
|
||||||
else:
|
else:
|
||||||
flee[char] = 1
|
flee[char] = 1
|
||||||
msg = "%s tries to disengage (two subsequent turns needed)"
|
messages.append(
|
||||||
messages.append(msg % char)
|
f"{char} tries to disengage (two subsequent turns needed)"
|
||||||
|
)
|
||||||
|
|
||||||
# echo results of each subturn
|
# echo results of each subturn
|
||||||
combat_handler.msg_all("\n".join(messages))
|
combat_handler.msg_all("\n".join(messages))
|
||||||
|
|
||||||
# at the end of both sub-turns, test if anyone fled
|
# at the end of both sub-turns, test if anyone fled
|
||||||
msg = "%s withdraws from combat."
|
|
||||||
for (char, fleevalue) in flee.items():
|
for (char, fleevalue) in flee.items():
|
||||||
if fleevalue == 2:
|
if fleevalue == 2:
|
||||||
combat_handler.msg_all(msg % char)
|
combat_handler.msg_all(f"{char} withdraws from combat.")
|
||||||
combat_handler.remove_character(char)
|
combat_handler.remove_character(char)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -495,14 +496,14 @@ class CmdAttack(Command):
|
||||||
if target.ndb.combat_handler:
|
if target.ndb.combat_handler:
|
||||||
# target is already in combat - join it
|
# target is already in combat - join it
|
||||||
target.ndb.combat_handler.add_character(self.caller)
|
target.ndb.combat_handler.add_character(self.caller)
|
||||||
target.ndb.combat_handler.msg_all("%s joins combat!" % self.caller)
|
target.ndb.combat_handler.msg_all(f"{self.caller} joins combat!")
|
||||||
else:
|
else:
|
||||||
# create a new combat handler
|
# create a new combat handler
|
||||||
chandler = create_script("combat_handler.CombatHandler")
|
chandler = create_script("combat_handler.CombatHandler")
|
||||||
chandler.add_character(self.caller)
|
chandler.add_character(self.caller)
|
||||||
chandler.add_character(target)
|
chandler.add_character(target)
|
||||||
self.caller.msg("You attack %s! You are in combat." % target)
|
self.caller.msg(f"You attack {target}! You are in combat.")
|
||||||
target.msg("%s attacks you! You are in combat." % self.caller)
|
target.msg(f"{self.caller} attacks you! You are in combat.")
|
||||||
```
|
```
|
||||||
|
|
||||||
The `attack` command will not go into the combat cmdset but rather into the default cmdset. See e.g.
|
The `attack` command will not go into the combat cmdset but rather into the default cmdset. See e.g.
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,7 @@ class CmdSetPower(Command):
|
||||||
return
|
return
|
||||||
# at this point the argument is tested as valid. Let's set it.
|
# at this point the argument is tested as valid. Let's set it.
|
||||||
self.caller.db.power = power
|
self.caller.db.power = power
|
||||||
self.caller.msg("Your Power was set to %i." % power)
|
self.caller.msg(f"Your Power was set to {power}.")
|
||||||
```
|
```
|
||||||
This is a pretty straightforward command. We do some error checking, then set the power on ourself.
|
This is a pretty straightforward command. We do some error checking, then set the power on ourself.
|
||||||
We use a `help_category` of "mush" for all our commands, just so they are easy to find and separate
|
We use a `help_category` of "mush" for all our commands, just so they are easy to find and separate
|
||||||
|
|
@ -295,11 +295,17 @@ class CmdAttack(Command):
|
||||||
caller.db.combat_score = combat_score
|
caller.db.combat_score = combat_score
|
||||||
|
|
||||||
# announce
|
# announce
|
||||||
message = "%s +attack%s with a combat score of %s!"
|
message_template = "{attacker} +attack{s} with a combat score of {c_score}!"
|
||||||
caller.msg(message % ("You", "", combat_score))
|
caller.msg(message_template.format(
|
||||||
caller.location.msg_contents(message %
|
attacker="You",
|
||||||
(caller.key, "s", combat_score),
|
s="",
|
||||||
exclude=caller)
|
c_score=combat_score,
|
||||||
|
))
|
||||||
|
caller.location.msg_contents(message_template.format(
|
||||||
|
attacker=caller.key,
|
||||||
|
s="s",
|
||||||
|
c_score=combat_score,
|
||||||
|
), exclude=caller)
|
||||||
```
|
```
|
||||||
|
|
||||||
What we do here is simply to generate a "combat score" using Python's inbuilt `random.randint()`
|
What we do here is simply to generate a "combat score" using Python's inbuilt `random.randint()`
|
||||||
|
|
@ -359,7 +365,7 @@ class Character(DefaultCharacter):
|
||||||
looker sees when looking at this object.
|
looker sees when looking at this object.
|
||||||
"""
|
"""
|
||||||
text = super().return_appearance(looker)
|
text = super().return_appearance(looker)
|
||||||
cscore = " (combat score: %s)" % self.db.combat_score
|
cscore = f" (combat score: {self.db.combat_score})"
|
||||||
if "\n" in text:
|
if "\n" in text:
|
||||||
# text is multi-line, add score after first line
|
# text is multi-line, add score after first line
|
||||||
first_line, rest = text.split("\n", 1)
|
first_line, rest = text.split("\n", 1)
|
||||||
|
|
@ -435,12 +441,17 @@ class CmdCreateNPC(Command):
|
||||||
npc = create_object("characters.Character",
|
npc = create_object("characters.Character",
|
||||||
key=name,
|
key=name,
|
||||||
location=caller.location,
|
location=caller.location,
|
||||||
locks="edit:id(%i) and perm(Builders);call:false()" % caller.id)
|
locks=f"edit:id({caller.id}) and perm(Builders);call:false()")
|
||||||
# announce
|
# announce
|
||||||
message = "%s created the NPC '%s'."
|
message_template = "{creator} created the NPC '{npc}'."
|
||||||
caller.msg(message % ("You", name))
|
caller.msg(message_template.format(
|
||||||
caller.location.msg_contents(message % (caller.key, name),
|
creator="You",
|
||||||
exclude=caller)
|
npc=name,
|
||||||
|
))
|
||||||
|
caller.location.msg_contents(message_template.format(
|
||||||
|
creator=caller.key,
|
||||||
|
npt=name,
|
||||||
|
), exclude=caller)
|
||||||
```
|
```
|
||||||
Here we define a `+createnpc` (`+createNPC` works too) that is callable by everyone *not* having the
|
Here we define a `+createnpc` (`+createNPC` works too) that is callable by everyone *not* having the
|
||||||
`nonpcs` "[permission](../../../Components/Locks#Permissions)" (in Evennia, a "permission" can just as well be used to
|
`nonpcs` "[permission](../../../Components/Locks#Permissions)" (in Evennia, a "permission" can just as well be used to
|
||||||
|
|
@ -532,10 +543,10 @@ class CmdEditNPC(Command):
|
||||||
return
|
return
|
||||||
if not self.propname:
|
if not self.propname:
|
||||||
# this means we just list the values
|
# this means we just list the values
|
||||||
output = "Properties of %s:" % npc.key
|
output = f"Properties of {npc.key}:"
|
||||||
for propname in allowed_propnames:
|
for propname in allowed_propnames:
|
||||||
propvalue = npc.attributes.get(propname, default="N/A")
|
propvalue = npc.attributes.get(propname, default="N/A")
|
||||||
output += "\n %s = %s" % (propname, propvalue)
|
output += f"\n {propname} = {propvalue}"
|
||||||
caller.msg(output)
|
caller.msg(output)
|
||||||
elif self.propname not in allowed_propnames:
|
elif self.propname not in allowed_propnames:
|
||||||
caller.msg("You may only change %s." %
|
caller.msg("You may only change %s." %
|
||||||
|
|
@ -619,7 +630,7 @@ class CmdNPC(Command):
|
||||||
return
|
return
|
||||||
# send the command order
|
# send the command order
|
||||||
npc.execute_cmd(self.cmdname)
|
npc.execute_cmd(self.cmdname)
|
||||||
caller.msg("You told %s to do '%s'." % (npc.key, self.cmdname))
|
caller.msg(f"You told {npc.key} to do '{self.cmdname}'.")
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that if you give an erroneous command, you will not see any error message, since that error
|
Note that if you give an erroneous command, you will not see any error message, since that error
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ class Npc(Character):
|
||||||
message = message.split('says, ')[1].strip(' "')
|
message = message.split('says, ')[1].strip(' "')
|
||||||
|
|
||||||
# we'll make use of this in .msg() below
|
# we'll make use of this in .msg() below
|
||||||
return "%s said: '%s'" % (from_obj, message)
|
return f"{from_obj} said: '{message}'"
|
||||||
```
|
```
|
||||||
|
|
||||||
When someone in the room speaks to this NPC, its `msg` method will be called. We will modify the
|
When someone in the room speaks to this NPC, its `msg` method will be called. We will modify the
|
||||||
|
|
@ -60,7 +60,7 @@ class Npc(Character):
|
||||||
# If there is a response
|
# If there is a response
|
||||||
if response != None:
|
if response != None:
|
||||||
# speak ourselves, using the return
|
# speak ourselves, using the return
|
||||||
self.execute_cmd("say %s" % response)
|
self.execute_cmd(f"say {response}")
|
||||||
|
|
||||||
# this is needed if anyone ever puppets this NPC - without it you would never
|
# this is needed if anyone ever puppets this NPC - without it you would never
|
||||||
# get any feedback from the server (not even the results of look)
|
# get any feedback from the server (not even the results of look)
|
||||||
|
|
|
||||||
|
|
@ -66,16 +66,16 @@ command
|
||||||
|
|
||||||
keys = prototypes.keys()
|
keys = prototypes.keys()
|
||||||
nprots = len(prototypes)
|
nprots = len(prototypes)
|
||||||
tweet = "Prototype Count: %s Random Keys: " % nprots
|
tweet = f"Prototype Count: {nprots} Random Keys: "
|
||||||
|
|
||||||
tweet += " %s" % keys[randint(0,len(keys)-1)]
|
tweet += f" {keys[randint(0,len(keys)-1)]}"
|
||||||
for x in range(0,2): ##tweet 3
|
for x in range(0,2): ##tweet 3
|
||||||
tweet += ", %s" % keys[randint(0,len(keys)-1)]
|
tweet += f", {keys[randint(0,len(keys)-1)]}"
|
||||||
# post the tweet
|
# post the tweet
|
||||||
try:
|
try:
|
||||||
response = api.PostUpdate(tweet)
|
response = api.PostUpdate(tweet)
|
||||||
except:
|
except:
|
||||||
logger.log_trace("Tweet Error: When attempting to tweet %s" % tweet)
|
logger.log_trace(f"Tweet Error: When attempting to tweet {tweet}")
|
||||||
```
|
```
|
||||||
|
|
||||||
In the `at_script_creation` method, we configure the script to fire immediately (useful for testing)
|
In the `at_script_creation` method, we configure the script to fire immediately (useful for testing)
|
||||||
|
|
|
||||||
|
|
@ -293,7 +293,7 @@ class TrainObject(DefaultObject):
|
||||||
roomref = self.db.rooms[idx]
|
roomref = self.db.rooms[idx]
|
||||||
room = search_object(roomref)[0]
|
room = search_object(roomref)[0]
|
||||||
self.move_to(room)
|
self.move_to(room)
|
||||||
self.msg_contents("The train is moving forward to %s." % (room.name, ))
|
self.msg_contents(f"The train is moving forward to {room.name}.")
|
||||||
```
|
```
|
||||||
|
|
||||||
We added a lot of code here. Since we changed the `at_object_creation` to add in variables we will
|
We added a lot of code here. Since we changed the `at_object_creation` to add in variables we will
|
||||||
|
|
|
||||||
|
|
@ -246,8 +246,12 @@ def creating(request):
|
||||||
user.db._playable_characters.append(char)
|
user.db._playable_characters.append(char)
|
||||||
# add the right locks for the character so the account can
|
# add the right locks for the character so the account can
|
||||||
# puppet it
|
# puppet it
|
||||||
char.locks.add("puppet:id(%i) or pid(%i) or perm(Developers) "
|
char.locks.add(" or ".join([
|
||||||
"or pperm(Developers)" % (char.id, user.id))
|
f"puppet:id({char.id})",
|
||||||
|
f"pid({user.id})",
|
||||||
|
"perm(Developers)",
|
||||||
|
"pperm(Developers)",
|
||||||
|
]))
|
||||||
char.db.background = background # set the character background
|
char.db.background = background # set the character background
|
||||||
return HttpResponseRedirect('/chargen')
|
return HttpResponseRedirect('/chargen')
|
||||||
else:
|
else:
|
||||||
|
|
@ -332,8 +336,12 @@ def creating(request):
|
||||||
user.db._playable_characters.append(char)
|
user.db._playable_characters.append(char)
|
||||||
# add the right locks for the character so the account can
|
# add the right locks for the character so the account can
|
||||||
# puppet it
|
# puppet it
|
||||||
char.locks.add("puppet:id(%i) or pid(%i) or perm(Developers) "
|
char.locks.add(" or ".join([
|
||||||
"or pperm(Developers)" % (char.id, user.id))
|
f"puppet:id({char.id})",
|
||||||
|
f"pid({user.id})",
|
||||||
|
"perm(Developers)",
|
||||||
|
"pperm(Developers)",
|
||||||
|
]))
|
||||||
char.db.background = background # set the character background
|
char.db.background = background # set the character background
|
||||||
return HttpResponseRedirect('/chargen')
|
return HttpResponseRedirect('/chargen')
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -76,13 +76,13 @@ class CmdTweet(Command):
|
||||||
|
|
||||||
tlen = len(tweet)
|
tlen = len(tweet)
|
||||||
if tlen > 280:
|
if tlen > 280:
|
||||||
caller.msg("Your tweet was %i chars long (max 280)." % tlen)
|
caller.msg(f"Your tweet was {tlen} chars long (max 280).")
|
||||||
return
|
return
|
||||||
|
|
||||||
# post the tweet
|
# post the tweet
|
||||||
TWITTER_API.PostUpdate(tweet)
|
TWITTER_API.PostUpdate(tweet)
|
||||||
|
|
||||||
caller.msg("You tweeted:\n%s" % tweet)
|
caller.msg(f"You tweeted:\n{tweet}")
|
||||||
```
|
```
|
||||||
|
|
||||||
Be sure to substitute your own actual API/Access keys and secrets in the appropriate places.
|
Be sure to substitute your own actual API/Access keys and secrets in the appropriate places.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue