Added new templates to gamesrc/*/examples. The old base* modules still in place. Some cleanup of the API.
This commit is contained in:
parent
3408f3ca3f
commit
4398d42360
12 changed files with 686 additions and 11 deletions
2
ev.py
2
ev.py
|
|
@ -6,7 +6,7 @@ This basically a set of shortcuts to the main modules in src/.
|
||||||
Import this from ./manage.py shell or set DJANGO_SETTINGS_MODULE manually for proper
|
Import this from ./manage.py shell or set DJANGO_SETTINGS_MODULE manually for proper
|
||||||
functionality.
|
functionality.
|
||||||
|
|
||||||
1) You should import things excplicitly from the root of this module - you can generally
|
1) You should import things explicitly from the root of this module - you can generally
|
||||||
not use dot-notation to import deeper. Hence, to access a default command, you can do
|
not use dot-notation to import deeper. Hence, to access a default command, you can do
|
||||||
the following:
|
the following:
|
||||||
|
|
||||||
|
|
|
||||||
116
game/gamesrc/commands/examples/cmdset.py
Normal file
116
game/gamesrc/commands/examples/cmdset.py
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
"""
|
||||||
|
Example command set template module.
|
||||||
|
|
||||||
|
To create new commands to populate the cmdset, see
|
||||||
|
examples/command.py.
|
||||||
|
|
||||||
|
To extend the default command set:
|
||||||
|
- copy this file up one level to gamesrc/commands and name it
|
||||||
|
something fitting.
|
||||||
|
- change settings.CMDSET_DEFAULT to point to the new module's
|
||||||
|
DefaultCmdSet
|
||||||
|
- import/add commands at the end of DefaultCmdSet's add() method.
|
||||||
|
|
||||||
|
To add a new command set
|
||||||
|
- copy this file up one level to gamesrc/commands and name it
|
||||||
|
something fitting.
|
||||||
|
- add a new cmdset class
|
||||||
|
- add it objects with obj.cmdset.add(path.to.the.module.and.class)
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from ev import CmdSet, Command
|
||||||
|
from ev import default_cmds
|
||||||
|
|
||||||
|
#from contrib import menusystem, lineeditor
|
||||||
|
#from contrib import misc_commands
|
||||||
|
#from contrib import chargen
|
||||||
|
|
||||||
|
class ExampleCmdSet(CmdSet):
|
||||||
|
"""
|
||||||
|
Implements an empty, example cmdset.
|
||||||
|
"""
|
||||||
|
|
||||||
|
key = "ExampleSet"
|
||||||
|
|
||||||
|
def at_cmdset_creation(self):
|
||||||
|
"""
|
||||||
|
This is the only method defined in a cmdset, called during
|
||||||
|
its creation. It should populate the set with command instances.
|
||||||
|
|
||||||
|
Here we just add the empty base Command object. It prints some info.
|
||||||
|
"""
|
||||||
|
self.add(Command())
|
||||||
|
|
||||||
|
|
||||||
|
class DefaultCmdSet(default_cmds.DefaultCmdSet):
|
||||||
|
"""
|
||||||
|
This is an example of how to overload the default command
|
||||||
|
set defined in src/commands/default/cmdset_default.py.
|
||||||
|
|
||||||
|
Here we copy everything by calling the parent, but you can
|
||||||
|
copy&paste any combination of the default command to customize
|
||||||
|
your default set. Next you change settings.CMDSET_DEFAULT to point
|
||||||
|
to this class.
|
||||||
|
"""
|
||||||
|
key = "DefaultMUX"
|
||||||
|
|
||||||
|
def at_cmdset_creation(self):
|
||||||
|
"""
|
||||||
|
Populates the cmdset
|
||||||
|
"""
|
||||||
|
# calling setup in src.commands.default.cmdset_default
|
||||||
|
super(DefaultCmdSet, self).at_cmdset_creation()
|
||||||
|
|
||||||
|
#
|
||||||
|
# any commands you add below will overload the default ones.
|
||||||
|
#
|
||||||
|
#self.add(menusystem.CmdMenuTest())
|
||||||
|
#self.add(lineeditor.CmdEditor())
|
||||||
|
#self.add(misc_commands.CmdQuell())
|
||||||
|
|
||||||
|
class UnloggedinCmdSet(default_cmds.UnloggedinCmdSet):
|
||||||
|
"""
|
||||||
|
This is an example of how to overload the command set of the
|
||||||
|
unloggedin commands, defined in
|
||||||
|
src/commands/default/cmdset_unloggedin.py.
|
||||||
|
|
||||||
|
Here we copy everything by calling the parent, but you can
|
||||||
|
copy&paste any combination of the default command to customize
|
||||||
|
your default set. Next you change settings.CMDSET_UNLOGGEDIN to
|
||||||
|
point to this class.
|
||||||
|
"""
|
||||||
|
key = "Unloggedin"
|
||||||
|
|
||||||
|
def at_cmdset_creation(self):
|
||||||
|
"""
|
||||||
|
Populates the cmdset
|
||||||
|
"""
|
||||||
|
# calling setup in src.commands.default.cmdset_unloggedin
|
||||||
|
super(UnloggedinCmdSet, self).at_cmdset_creation()
|
||||||
|
|
||||||
|
#
|
||||||
|
# any commands you add below will overload the default ones.
|
||||||
|
#
|
||||||
|
|
||||||
|
class OOCCmdSet(default_cmds.OOCCmdSet):
|
||||||
|
"""
|
||||||
|
This is set is available to the player when they have no
|
||||||
|
character connected to them (i.e. they are out-of-character, ooc).
|
||||||
|
"""
|
||||||
|
key = "OOC"
|
||||||
|
|
||||||
|
def at_cmdset_creation(self):
|
||||||
|
"""
|
||||||
|
Populates the cmdset
|
||||||
|
"""
|
||||||
|
# calling setup in src.commands.default.cmdset_ooc
|
||||||
|
super(OOCCmdSet, self).at_cmdset_creation()
|
||||||
|
#
|
||||||
|
# any commands you add below will overload the default ones.
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
132
game/gamesrc/commands/examples/command.py
Normal file
132
game/gamesrc/commands/examples/command.py
Normal file
|
|
@ -0,0 +1,132 @@
|
||||||
|
"""
|
||||||
|
Example command module template
|
||||||
|
|
||||||
|
Copy this module up one level to gamesrc/commands/ and name it as
|
||||||
|
befits your use. You can then use it as a template to define your new
|
||||||
|
commands. To use them you also need to group them in a CommandSet (see
|
||||||
|
examples/cmdset.py)
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from ev import Command as BaseCommand
|
||||||
|
from ev import default_cmd
|
||||||
|
from ev import utils
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
"""
|
||||||
|
Inherit from this if you want to create your own
|
||||||
|
command styles. Note that Evennia's default commands
|
||||||
|
use MuxCommand instead (next in this module)
|
||||||
|
|
||||||
|
Note that the class's __doc__ string (this text) is
|
||||||
|
used by Evennia to create the automatic help entry for
|
||||||
|
the command, so make sure to document consistently here.
|
||||||
|
|
||||||
|
"""
|
||||||
|
# these need to be specified
|
||||||
|
|
||||||
|
key = "MyCommand"
|
||||||
|
aliases = ["mycmd", "myc"]
|
||||||
|
locks = "cmd:all()"
|
||||||
|
help_category = "General"
|
||||||
|
|
||||||
|
# auto_help = False # uncomment to deactive auto-help for this command.
|
||||||
|
# arg_regex = r"\s.*?|$" # optional regex detailing how the part after
|
||||||
|
# the cmdname must look to match this command.
|
||||||
|
|
||||||
|
|
||||||
|
# (we don't implement hook method access() here, you don't need to
|
||||||
|
# modify that unless you want to change how the lock system works
|
||||||
|
# (in that case see src.commands.command.Command))
|
||||||
|
|
||||||
|
def at_pre_cmd(self):
|
||||||
|
"""
|
||||||
|
This hook is called before self.parse() on all commands
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def parse(self):
|
||||||
|
"""
|
||||||
|
This method is called by the cmdhandler once the command name
|
||||||
|
has been identified. It creates a new set of member variables
|
||||||
|
that can be later accessed from self.func() (see below)
|
||||||
|
|
||||||
|
The following variables are available to us:
|
||||||
|
# class variables:
|
||||||
|
|
||||||
|
self.key - the name of this command ('mycommand')
|
||||||
|
self.aliases - the aliases of this cmd ('mycmd','myc')
|
||||||
|
self.locks - lock string for this command ("cmd:all()")
|
||||||
|
self.help_category - overall category of command ("General")
|
||||||
|
|
||||||
|
# added at run-time by cmdhandler:
|
||||||
|
|
||||||
|
self.caller - the object calling this command
|
||||||
|
self.cmdstring - the actual command name used to call this
|
||||||
|
(this allows you to know which alias was used,
|
||||||
|
for example)
|
||||||
|
self.args - the raw input; everything following self.cmdstring.
|
||||||
|
self.cmdset - the cmdset from which this command was picked. Not
|
||||||
|
often used (useful for commands like 'help' or to
|
||||||
|
list all available commands etc)
|
||||||
|
self.obj - the object on which this command was defined. It is often
|
||||||
|
the same as self.caller.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def func(self):
|
||||||
|
"""
|
||||||
|
This is the hook function that actually does all the work. It is called
|
||||||
|
by the cmdhandler right after self.parser() finishes, and so has access
|
||||||
|
to all the variables defined therein.
|
||||||
|
"""
|
||||||
|
self.caller.msg("Command called!")
|
||||||
|
|
||||||
|
def at_post_cmd(self):
|
||||||
|
"""
|
||||||
|
This hook is called after self.func().
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class MuxCommand(default_cmd.MuxCommand):
|
||||||
|
"""
|
||||||
|
This sets up the basis for a Evennia's 'MUX-like' command
|
||||||
|
style. The idea is that most other Mux-related commands should
|
||||||
|
just inherit from this and don't have to implement parsing of
|
||||||
|
their own unless they do something particularly advanced.
|
||||||
|
|
||||||
|
A MUXCommand command understands the following possible syntax:
|
||||||
|
|
||||||
|
name[ with several words][/switch[/switch..]] arg1[,arg2,...] [[=|,] arg[,..]]
|
||||||
|
|
||||||
|
The 'name[ with several words]' part is already dealt with by the
|
||||||
|
cmdhandler at this point, and stored in self.cmdname. The rest is stored
|
||||||
|
in self.args.
|
||||||
|
|
||||||
|
The MuxCommand parser breaks self.args into its constituents and stores them in the
|
||||||
|
following variables:
|
||||||
|
self.switches = optional list of /switches (without the /)
|
||||||
|
self.raw = This is the raw argument input, including switches
|
||||||
|
self.args = This is re-defined to be everything *except* the switches
|
||||||
|
self.lhs = Everything to the left of = (lhs:'left-hand side'). If
|
||||||
|
no = is found, this is identical to self.args.
|
||||||
|
self.rhs: Everything to the right of = (rhs:'right-hand side').
|
||||||
|
If no '=' is found, this is None.
|
||||||
|
self.lhslist - self.lhs split into a list by comma
|
||||||
|
self.rhslist - list of self.rhs split into a list by comma
|
||||||
|
self.arglist = list of space-separated args (including '=' if it exists)
|
||||||
|
|
||||||
|
All args and list members are stripped of excess whitespace around the
|
||||||
|
strings, but case is preserved.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def func(self):
|
||||||
|
"""
|
||||||
|
This is the hook function that actually does all the work. It is called
|
||||||
|
by the cmdhandler right after self.parser() finishes, and so has access
|
||||||
|
to all the variables defined therein.
|
||||||
|
"""
|
||||||
|
# this can be removed in your child class, it's just
|
||||||
|
# printing the ingoing variables as a demo.
|
||||||
|
super(MuxCommand, self).func()
|
||||||
41
game/gamesrc/objects/examples/character.py
Normal file
41
game/gamesrc/objects/examples/character.py
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
"""
|
||||||
|
|
||||||
|
Template for Characters
|
||||||
|
|
||||||
|
Copy this module up one level and name it as you like, then
|
||||||
|
use it as a template to create your own Character class.
|
||||||
|
|
||||||
|
To make new logins default to creating characters
|
||||||
|
of your new type, change settings.BASE_CHARACTER_TYPECLASS to point to
|
||||||
|
your new class, e.g.
|
||||||
|
|
||||||
|
settings.BASE_CHARACTER_TYPECLASS = "game.gamesrc.objects.mychar.MyChar"
|
||||||
|
|
||||||
|
Note that objects already created in the database will not notice
|
||||||
|
this change, you have to convert them manually e.g. with the
|
||||||
|
@typeclass command.
|
||||||
|
|
||||||
|
"""
|
||||||
|
from ev import Character
|
||||||
|
|
||||||
|
class ExampleCharacter(Character):
|
||||||
|
"""
|
||||||
|
The Character is like any normal Object (see example/object.py for
|
||||||
|
a list of properties and methods), except it actually implements
|
||||||
|
some of its hook methods to do some work:
|
||||||
|
|
||||||
|
at_basetype_setup - always assigns the default_cmdset to this object type
|
||||||
|
(important!)sets locks so character cannot be picked up
|
||||||
|
and its commands only be called by itself, not anyone else.
|
||||||
|
(to change things, use at_object_creation() instead)
|
||||||
|
at_after_move - launches the "look" command
|
||||||
|
at_disconnect - stores the current location, so the "unconnected" character
|
||||||
|
object does not need to stay on grid but can be given a
|
||||||
|
None-location while offline.
|
||||||
|
at_post_login - retrieves the character's old location and puts it back
|
||||||
|
on the grid with a "charname has connected" message echoed
|
||||||
|
to the room
|
||||||
|
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
43
game/gamesrc/objects/examples/exit.py
Normal file
43
game/gamesrc/objects/examples/exit.py
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
"""
|
||||||
|
|
||||||
|
Template module for Exits
|
||||||
|
|
||||||
|
Copy this module up one level and name it as you like, then
|
||||||
|
use it as a template to create your own Exits.
|
||||||
|
|
||||||
|
To make the default commands (such as @dig/@open) default to creating exits
|
||||||
|
of your new type, change settings.BASE_EXIT_TYPECLASS to point to
|
||||||
|
your new class, e.g.
|
||||||
|
|
||||||
|
settings.BASE_EXIT_TYPECLASS = "game.gamesrc.objects.myexit.MyExit"
|
||||||
|
|
||||||
|
Note that objects already created in the database will not notice
|
||||||
|
this change, you have to convert them manually e.g. with the
|
||||||
|
@typeclass command.
|
||||||
|
|
||||||
|
"""
|
||||||
|
from ev import Exit
|
||||||
|
|
||||||
|
class ExampleExit(Exit):
|
||||||
|
"""
|
||||||
|
Exits are connectors between rooms. Exits are normal Objects except
|
||||||
|
they defines the 'destination' property. It also does work in the
|
||||||
|
following methods:
|
||||||
|
|
||||||
|
basetype_setup() - sets default exit locks (to change, use at_object_creation instead)
|
||||||
|
at_cmdset_get() - this auto-creates and caches a command and a command set on itself
|
||||||
|
with the same name as the Exit object. This
|
||||||
|
allows users to use the exit by only giving its
|
||||||
|
name alone on the command line.
|
||||||
|
at_failed_traverse() - gives a default error message ("You cannot
|
||||||
|
go there") if exit traversal fails and an
|
||||||
|
attribute err_traverse is not defined.
|
||||||
|
|
||||||
|
Relevant hooks to overload (compared to other types of Objects):
|
||||||
|
at_before_traverse(traveller) - called just before traversing
|
||||||
|
at_after_traverse(traveller, source_loc) - called just after traversing
|
||||||
|
at_failed_traverse(traveller) - called if traversal failed for some reason. Will
|
||||||
|
not be called if the attribute 'err_traverse' is
|
||||||
|
defined, in which case that will simply be echoed.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
123
game/gamesrc/objects/examples/object.py
Normal file
123
game/gamesrc/objects/examples/object.py
Normal file
|
|
@ -0,0 +1,123 @@
|
||||||
|
"""
|
||||||
|
|
||||||
|
Template for Objects
|
||||||
|
|
||||||
|
Copy this module up one level and name it as you like, then
|
||||||
|
use it as a template to create your own Objects.
|
||||||
|
|
||||||
|
To make the default commands default to creating objects of your new
|
||||||
|
type (and also change the "fallback" object used when typeclass
|
||||||
|
creation fails), change settings.BASE_OBJECT_TYPECLASS to point to
|
||||||
|
your new class, e.g.
|
||||||
|
|
||||||
|
settings.BASE_OBJECT_TYPECLASS = "game.gamesrc.objects.myobj.MyObj"
|
||||||
|
|
||||||
|
Note that objects already created in the database will not notice
|
||||||
|
this change, you have to convert them manually e.g. with the
|
||||||
|
@typeclass command.
|
||||||
|
|
||||||
|
"""
|
||||||
|
from ev import Object
|
||||||
|
|
||||||
|
class ExampleObject(Object):
|
||||||
|
"""
|
||||||
|
This is the root typeclass object, implementing an in-game Evennia
|
||||||
|
game object, such as having a location, being able to be
|
||||||
|
manipulated or looked at, etc. If you create a new typeclass, it
|
||||||
|
must always inherit from this object (or any of the other objects
|
||||||
|
in this file, since they all actually inherit from BaseObject, as
|
||||||
|
seen in src.object.objects).
|
||||||
|
|
||||||
|
The BaseObject class implements several hooks tying into the game
|
||||||
|
engine. By re-implementing these hooks you can control the
|
||||||
|
system. You should never need to re-implement special Python
|
||||||
|
methods, such as __init__ and especially never __getattribute__ and
|
||||||
|
__setattr__ since these are used heavily by the typeclass system
|
||||||
|
of Evennia and messing with them might well break things for you.
|
||||||
|
|
||||||
|
|
||||||
|
* Base properties defined/available on all Objects
|
||||||
|
|
||||||
|
key (string) - name of object
|
||||||
|
name (string)- same as key
|
||||||
|
aliases (list of strings) - aliases to the object. Will be saved to database as AliasDB entries but returned as strings.
|
||||||
|
dbref (int, read-only) - unique #id-number. Also "id" can be used.
|
||||||
|
dbobj (Object, read-only) - link to database model. dbobj.typeclass points back to this class
|
||||||
|
typeclass (Object, read-only) - this links back to this class as an identified only. Use self.swap_typeclass() to switch.
|
||||||
|
date_created (string) - time stamp of object creation
|
||||||
|
permissions (list of strings) - list of permission strings
|
||||||
|
|
||||||
|
player (Player) - controlling player (will also return offline player)
|
||||||
|
location (Object) - current location. Is None if this is a room
|
||||||
|
home (Object) - safety start-location
|
||||||
|
sessions (list of Sessions, read-only) - returns all sessions connected to this object
|
||||||
|
has_player (bool, read-only)- will only return *connected* players
|
||||||
|
contents (list of Objects, read-only) - returns all objects inside this object (including exits)
|
||||||
|
exits (list of Objects, read-only) - returns all exits from this object, if any
|
||||||
|
destination (Object) - only set if this object is an exit.
|
||||||
|
is_superuser (bool, read-only) - True/False if this user is a superuser
|
||||||
|
|
||||||
|
* Handlers available
|
||||||
|
|
||||||
|
locks - lock-handler: use locks.add() to add new lock strings
|
||||||
|
db - attribute-handler: store/retrieve database attributes on this self.db.myattr=val, val=self.db.myattr
|
||||||
|
ndb - non-persistent attribute handler: same as db but does not create a database entry when storing data
|
||||||
|
scripts - script-handler. Add new scripts to object with scripts.add()
|
||||||
|
cmdset - cmdset-handler. Use cmdset.add() to add new cmdsets to object
|
||||||
|
nicks - nick-handler. New nicks with nicks.add().
|
||||||
|
|
||||||
|
* Helper methods (see src.objects.objects.py for full headers)
|
||||||
|
|
||||||
|
search(ostring, global_search=False, attribute_name=None, use_nicks=False, location=None, ignore_errors=False, player=False)
|
||||||
|
execute_cmd(raw_string)
|
||||||
|
msg(message, from_obj=None, data=None)
|
||||||
|
msg_contents(message, exclude=None, from_obj=None, data=None)
|
||||||
|
move_to(destination, quiet=False, emit_to_obj=None, use_destination=True)
|
||||||
|
copy(new_key=None)
|
||||||
|
delete()
|
||||||
|
is_typeclass(typeclass, exact=False)
|
||||||
|
swap_typeclass(new_typeclass, clean_attributes=False, no_default=True)
|
||||||
|
access(accessing_obj, access_type='read', default=False)
|
||||||
|
check_permstring(permstring)
|
||||||
|
|
||||||
|
* Hooks (these are class methods, so their arguments should also start with self):
|
||||||
|
|
||||||
|
basetype_setup() - only called once, used for behind-the-scenes setup. Normally not modified.
|
||||||
|
basetype_posthook_setup() - customization in basetype, after the object has been created; Normally not modified.
|
||||||
|
|
||||||
|
at_object_creation() - only called once, when object is first created. Object customizations go here.
|
||||||
|
at_object_delete() - called just before deleting an object. If returning False, deletion is aborted. Note that all objects
|
||||||
|
inside a deleted object are automatically moved to their <home>, they don't need to be removed here.
|
||||||
|
|
||||||
|
at_init() - called whenever typeclass is cached from memory, at least once every server restart/reload
|
||||||
|
at_cmdset_get() - this is called just before the command handler requests a cmdset from this object
|
||||||
|
at_first_login() - (player-controlled objects only) called once, the very first time user logs in.
|
||||||
|
at_pre_login() - (player-controlled objects only) called every time the user connects, after they have identified, before other setup
|
||||||
|
at_post_login() - (player-controlled objects only) called at the end of login, just before setting the player loose in the world.
|
||||||
|
at_disconnect() - (player-controlled objects only) called just before the user disconnects (or goes linkless)
|
||||||
|
at_server_reload() - called before server is reloaded
|
||||||
|
at_server_shutdown() - called just before server is fully shut down
|
||||||
|
|
||||||
|
at_before_move(destination) - called just before moving object to the destination. If returns False, move is cancelled.
|
||||||
|
announce_move_from(destination) - called in old location, just before move, if obj.move_to() has quiet=False
|
||||||
|
announce_move_to(source_location) - called in new location, just after move, if obj.move_to() has quiet=False
|
||||||
|
at_after_move(source_location) - always called after a move has been successfully performed.
|
||||||
|
at_object_leave(obj, target_location) - called when an object leaves this object in any fashion
|
||||||
|
at_object_receive(obj, source_location) - called when this object receives another object
|
||||||
|
|
||||||
|
at_before_traverse(traversing_object) - (exit-objects only) called just before an object traverses this object
|
||||||
|
at_after_traverse(traversing_object, source_location) - (exit-objects only) called just after a traversal has happened.
|
||||||
|
at_failed_traverse(traversing_object) - (exit-objects only) called if traversal fails and property err_traverse is not defined.
|
||||||
|
|
||||||
|
at_msg_receive(self, msg, from_obj=None, data=None) - called when a message (via self.msg()) is sent to this obj.
|
||||||
|
If returns false, aborts send.
|
||||||
|
at_msg_send(self, msg, to_obj=None, data=None) - called when this objects sends a message to someone via self.msg().
|
||||||
|
|
||||||
|
return_appearance(looker) - describes this object. Used by "look" command by default
|
||||||
|
at_desc(looker=None) - called by 'look' whenever the appearance is requested.
|
||||||
|
at_get(getter) - called after object has been picked up. Does not stop pickup.
|
||||||
|
at_drop(dropper) - called when this object has been dropped.
|
||||||
|
at_say(speaker, message) - by default, called if an object inside this object speaks
|
||||||
|
|
||||||
|
"""
|
||||||
|
pass
|
||||||
90
game/gamesrc/objects/examples/player.py
Normal file
90
game/gamesrc/objects/examples/player.py
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
"""
|
||||||
|
|
||||||
|
Template module for Players
|
||||||
|
|
||||||
|
Copy this module up one level and name it as you like, then
|
||||||
|
use it as a template to create your own Player class.
|
||||||
|
|
||||||
|
To make the default account login default to using a Player
|
||||||
|
of your new type, change settings.BASE_PLAYER_TYPECLASS to point to
|
||||||
|
your new class, e.g.
|
||||||
|
|
||||||
|
settings.BASE_PLAYER_TYPECLASS = "game.gamesrc.objects.myplayer.MyPlayer"
|
||||||
|
|
||||||
|
Note that objects already created in the database will not notice
|
||||||
|
this change, you have to convert them manually e.g. with the
|
||||||
|
@typeclass command.
|
||||||
|
|
||||||
|
"""
|
||||||
|
from ev import Player
|
||||||
|
|
||||||
|
class ExamplePlayer(Player):
|
||||||
|
"""
|
||||||
|
This class describes the actual OOC player (i.e. the user connecting
|
||||||
|
to the MUD). It does NOT have visual appearance in the game world (that
|
||||||
|
is handled by the character which is connected to this). Comm channels
|
||||||
|
are attended/joined using this object.
|
||||||
|
|
||||||
|
It can be useful e.g. for storing configuration options for your game, but
|
||||||
|
should generally not hold any character-related info (that's best handled
|
||||||
|
on the character level).
|
||||||
|
|
||||||
|
Can be set using BASE_PLAYER_TYPECLASS.
|
||||||
|
|
||||||
|
|
||||||
|
* available properties
|
||||||
|
|
||||||
|
key (string) - name of player
|
||||||
|
name (string)- wrapper for user.username
|
||||||
|
aliases (list of strings) - aliases to the object. Will be saved to database as AliasDB entries but returned as strings.
|
||||||
|
dbref (int, read-only) - unique #id-number. Also "id" can be used.
|
||||||
|
dbobj (Player, read-only) - link to database model. dbobj.typeclass points back to this class
|
||||||
|
typeclass (Player, read-only) - this links back to this class as an identified only. Use self.swap_typeclass() to switch.
|
||||||
|
date_created (string) - time stamp of object creation
|
||||||
|
permissions (list of strings) - list of permission strings
|
||||||
|
|
||||||
|
user (User, read-only) - django User authorization object
|
||||||
|
obj (Object) - game object controlled by player. 'character' can also be used.
|
||||||
|
sessions (list of Sessions) - sessions connected to this player
|
||||||
|
is_superuser (bool, read-only) - if the connected user is a superuser
|
||||||
|
|
||||||
|
* Handlers
|
||||||
|
|
||||||
|
locks - lock-handler: use locks.add() to add new lock strings
|
||||||
|
db - attribute-handler: store/retrieve database attributes on this self.db.myattr=val, val=self.db.myattr
|
||||||
|
ndb - non-persistent attribute handler: same as db but does not create a database entry when storing data
|
||||||
|
scripts - script-handler. Add new scripts to object with scripts.add()
|
||||||
|
cmdset - cmdset-handler. Use cmdset.add() to add new cmdsets to object
|
||||||
|
nicks - nick-handler. New nicks with nicks.add().
|
||||||
|
|
||||||
|
* Helper methods
|
||||||
|
|
||||||
|
msg(outgoing_string, from_obj=None, data=None)
|
||||||
|
swap_character(new_character, delete_old_character=False)
|
||||||
|
execute_cmd(raw_string)
|
||||||
|
search(ostring, global_search=False, attribute_name=None, use_nicks=False, location=None, ignore_errors=False, player=False)
|
||||||
|
is_typeclass(typeclass, exact=False)
|
||||||
|
swap_typeclass(new_typeclass, clean_attributes=False, no_default=True)
|
||||||
|
access(accessing_obj, access_type='read', default=False)
|
||||||
|
check_permstring(permstring)
|
||||||
|
|
||||||
|
* Hook methods (when re-implementation, remember methods need to have self as first arg)
|
||||||
|
|
||||||
|
basetype_setup()
|
||||||
|
at_player_creation()
|
||||||
|
|
||||||
|
- note that the following hooks are also found on Objects and are
|
||||||
|
usually handled on the character level:
|
||||||
|
|
||||||
|
at_init()
|
||||||
|
at_cmdset_get()
|
||||||
|
at_first_login()
|
||||||
|
at_post_login()
|
||||||
|
at_disconnect()
|
||||||
|
at_message_receive()
|
||||||
|
at_message_send()
|
||||||
|
at_server_reload()
|
||||||
|
at_server_shutdown()
|
||||||
|
|
||||||
|
"""
|
||||||
|
pass
|
||||||
32
game/gamesrc/objects/examples/room.py
Normal file
32
game/gamesrc/objects/examples/room.py
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
"""
|
||||||
|
|
||||||
|
Template module for Rooms
|
||||||
|
|
||||||
|
Copy this module up one level and name it as you like, then
|
||||||
|
use it as a template to create your own Objects.
|
||||||
|
|
||||||
|
To make the default commands (such as @dig) default to creating rooms
|
||||||
|
of your new type, change settings.BASE_ROOM_TYPECLASS to point to
|
||||||
|
your new class, e.g.
|
||||||
|
|
||||||
|
settings.BASE_ROOM_TYPECLASS = "game.gamesrc.objects.myroom.MyRoom"
|
||||||
|
|
||||||
|
Note that objects already created in the database will not notice
|
||||||
|
this change, you have to convert them manually e.g. with the
|
||||||
|
@typeclass command.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from ev import Room
|
||||||
|
|
||||||
|
class ExampleRoom(Room):
|
||||||
|
"""
|
||||||
|
Rooms are like any Object, except their location is None
|
||||||
|
(which is default). They also use basetype_setup() to
|
||||||
|
add locks so they cannot be puppeted or picked up.
|
||||||
|
(to change that, use at_object_creation instead)
|
||||||
|
|
||||||
|
See examples/object.py for a list of
|
||||||
|
properties and methods available on all Objects.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
@ -1,5 +1,13 @@
|
||||||
"""
|
"""
|
||||||
The base object to inherit from when implementing new Scripts.
|
|
||||||
|
Template module for Scripts
|
||||||
|
|
||||||
|
Copy this module up one level to gamesrc/scripts and name it
|
||||||
|
appropriately, then use that as a template to create your own script.
|
||||||
|
|
||||||
|
Test scripts in-game e.g. with the @script command. In code you can
|
||||||
|
create new scripts of a given class with
|
||||||
|
script = ev.create.script("path.to.module.and.class")
|
||||||
|
|
||||||
Scripts are objects that handle everything in the game having
|
Scripts are objects that handle everything in the game having
|
||||||
a time-component (i.e. that may change with time, with or without
|
a time-component (i.e. that may change with time, with or without
|
||||||
|
|
@ -10,17 +18,13 @@ checking if its state changes, so as to update it. Evennia use several
|
||||||
in-built scripts to keep track of things like time, to clean out
|
in-built scripts to keep track of things like time, to clean out
|
||||||
dropped connections etc.
|
dropped connections etc.
|
||||||
|
|
||||||
New Script objects (from these classes) are created using the
|
|
||||||
src.utils.create.create_script(scriptclass, ...) where scriptclass
|
|
||||||
is the python path to the specific class of script you want to use.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from ev import Script as BaseScript
|
from ev import Script as BaseScript
|
||||||
|
|
||||||
class Script(BaseScript):
|
class Script(BaseScript):
|
||||||
"""
|
"""
|
||||||
All scripts should inherit from this class and implement
|
A script type is customized by redefining some or all of its hook methods and variables.
|
||||||
some or all of its hook functions and variables.
|
|
||||||
|
|
||||||
* available properties
|
* available properties
|
||||||
|
|
||||||
|
|
|
||||||
87
game/gamesrc/scripts/examples/script.py
Normal file
87
game/gamesrc/scripts/examples/script.py
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
"""
|
||||||
|
|
||||||
|
Template module for Scripts
|
||||||
|
|
||||||
|
Copy this module up one level to gamesrc/scripts and name it
|
||||||
|
appropriately, then use that as a template to create your own script.
|
||||||
|
|
||||||
|
Test scripts in-game e.g. with the @script command. In code you can
|
||||||
|
create new scripts of a given class with
|
||||||
|
script = ev.create.script("path.to.module.and.class")
|
||||||
|
|
||||||
|
Scripts are objects that handle everything in the game having
|
||||||
|
a time-component (i.e. that may change with time, with or without
|
||||||
|
a player being involved in the change). Scripts can work like "events",
|
||||||
|
in that they are triggered at regular intervals to do a certain script,
|
||||||
|
but an Script set on an object can also be responsible for silently
|
||||||
|
checking if its state changes, so as to update it. Evennia use several
|
||||||
|
in-built scripts to keep track of things like time, to clean out
|
||||||
|
dropped connections etc.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from ev import Script
|
||||||
|
|
||||||
|
class ExampleScript(BaseScript):
|
||||||
|
"""
|
||||||
|
A script type is customized by redefining some or all of its hook methods and variables.
|
||||||
|
|
||||||
|
* available properties
|
||||||
|
|
||||||
|
key (string) - name of object
|
||||||
|
name (string)- same as key
|
||||||
|
aliases (list of strings) - aliases to the object. Will be saved to database as AliasDB entries but returned as strings.
|
||||||
|
dbref (int, read-only) - unique #id-number. Also "id" can be used.
|
||||||
|
dbobj (Object, read-only) - link to database model. dbobj.typeclass points back to this class
|
||||||
|
typeclass (Object, read-only) - this links back to this class as an identified only. Use self.swap_typeclass() to switch.
|
||||||
|
date_created (string) - time stamp of object creation
|
||||||
|
permissions (list of strings) - list of permission strings
|
||||||
|
|
||||||
|
desc (string) - optional description of script, shown in listings
|
||||||
|
obj (Object) - optional object that this script is connected to and acts on (set automatically by obj.scripts.add())
|
||||||
|
interval (int) - how often script should run, in seconds. <0 turns off ticker
|
||||||
|
start_delay (bool) - if the script should start repeating right away or wait self.interval seconds
|
||||||
|
repeats (int) - how many times the script should repeat before stopping. 0 means infinite repeats
|
||||||
|
persistent (bool) - if script should survive a server shutdown or not
|
||||||
|
is_active (bool) - if script is currently running
|
||||||
|
|
||||||
|
* Handlers
|
||||||
|
|
||||||
|
locks - lock-handler: use locks.add() to add new lock strings
|
||||||
|
db - attribute-handler: store/retrieve database attributes on this self.db.myattr=val, val=self.db.myattr
|
||||||
|
ndb - non-persistent attribute handler: same as db but does not create a database entry when storing data
|
||||||
|
|
||||||
|
* Helper methods
|
||||||
|
|
||||||
|
start() - start script (this usually happens automatically at creation and obj.script.add() etc)
|
||||||
|
stop() - stop script, and delete it
|
||||||
|
pause() - put the script on hold, until unpause() is called. If script is persistent, the pause state will survive a shutdown.
|
||||||
|
unpause() - restart a previously paused script. The script will continue as if it was never paused.
|
||||||
|
time_until_next_repeat() - if a timed script (interval>0), returns time until next tick
|
||||||
|
|
||||||
|
* Hook methods (should also include self as the first argument):
|
||||||
|
|
||||||
|
at_script_creation() - called only once, when an object of this
|
||||||
|
class is first created.
|
||||||
|
is_valid() - is called to check if the script is valid to be running
|
||||||
|
at the current time. If is_valid() returns False, the running
|
||||||
|
script is stopped and removed from the game. You can use this
|
||||||
|
to check state changes (i.e. an script tracking some combat
|
||||||
|
stats at regular intervals is only valid to run while there is
|
||||||
|
actual combat going on).
|
||||||
|
at_start() - Called every time the script is started, which for persistent
|
||||||
|
scripts is at least once every server start. Note that this is
|
||||||
|
unaffected by self.delay_start, which only delays the first call
|
||||||
|
to at_repeat().
|
||||||
|
at_repeat() - Called every self.interval seconds. It will be called immediately
|
||||||
|
upon launch unless self.delay_start is True, which will delay
|
||||||
|
the first call of this method by self.interval seconds. If
|
||||||
|
self.interval==0, this method will never be called.
|
||||||
|
at_stop() - Called as the script object is stopped and is about to be removed from
|
||||||
|
the game, e.g. because is_valid() returned False.
|
||||||
|
at_server_reload() - Called when server reloads. Can be used to save temporary
|
||||||
|
variables you want should survive a reload.
|
||||||
|
at_server_shutdown() - called at a full server shutdown.
|
||||||
|
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
@ -1066,6 +1066,7 @@ class TypedObject(SharedMemoryModel):
|
||||||
to create a new object and just swap the player over to
|
to create a new object and just swap the player over to
|
||||||
that one instead.
|
that one instead.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
new_typeclass (path/classobj) - type to switch to
|
new_typeclass (path/classobj) - type to switch to
|
||||||
clean_attributes (bool/list) - will delete all attributes
|
clean_attributes (bool/list) - will delete all attributes
|
||||||
stored on this object (but not any
|
stored on this object (but not any
|
||||||
|
|
@ -1079,6 +1080,9 @@ class TypedObject(SharedMemoryModel):
|
||||||
swapping to a default typeclass in case the given
|
swapping to a default typeclass in case the given
|
||||||
one fails for some reason. Instead the old one
|
one fails for some reason. Instead the old one
|
||||||
will be preserved.
|
will be preserved.
|
||||||
|
Returns:
|
||||||
|
boolean True/False depending on if the swap worked or not.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if callable(new_typeclass):
|
if callable(new_typeclass):
|
||||||
# this is an actual class object - build the path
|
# this is an actual class object - build the path
|
||||||
|
|
|
||||||
|
|
@ -32,10 +32,13 @@ from src.utils.utils import is_iter, has_parent, inherits_from
|
||||||
# limit symbol import from API
|
# limit symbol import from API
|
||||||
__all__ = ("object", "script", "help_entry", "message", "channel", "player")
|
__all__ = ("object", "script", "help_entry", "message", "channel", "player")
|
||||||
|
|
||||||
|
GA = object.__getattribute__
|
||||||
|
|
||||||
#
|
#
|
||||||
# Game Object creation
|
# Game Object creation
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
def create_object(typeclass, key=None, location=None,
|
def create_object(typeclass, key=None, location=None,
|
||||||
home=None, player=None, permissions=None, locks=None,
|
home=None, player=None, permissions=None, locks=None,
|
||||||
aliases=None, destination=None):
|
aliases=None, destination=None):
|
||||||
|
|
@ -81,7 +84,7 @@ def create_object(typeclass, key=None, location=None,
|
||||||
new_object = new_db_object.typeclass
|
new_object = new_db_object.typeclass
|
||||||
|
|
||||||
|
|
||||||
if not object.__getattribute__(new_db_object, "is_typeclass")(typeclass, exact=True):
|
if not GA(new_db_object, "is_typeclass")(typeclass, exact=True):
|
||||||
# this will fail if we gave a typeclass as input and it still gave us a default
|
# this will fail if we gave a typeclass as input and it still gave us a default
|
||||||
SharedMemoryModel.delete(new_db_object)
|
SharedMemoryModel.delete(new_db_object)
|
||||||
return None
|
return None
|
||||||
|
|
@ -190,7 +193,7 @@ def create_script(typeclass, key=None, obj=None, locks=None,
|
||||||
# this will either load the typeclass or the default one
|
# this will either load the typeclass or the default one
|
||||||
new_script = new_db_script.typeclass
|
new_script = new_db_script.typeclass
|
||||||
|
|
||||||
if not object.__getattribute__(new_db_script, "is_typeclass")(typeclass, exact=True):
|
if not GA(new_db_script, "is_typeclass")(typeclass, exact=True):
|
||||||
# this will fail if we gave a typeclass as input and it still gave us a default
|
# this will fail if we gave a typeclass as input and it still gave us a default
|
||||||
print "failure:", new_db_script, typeclass
|
print "failure:", new_db_script, typeclass
|
||||||
SharedMemoryModel.delete(new_db_script)
|
SharedMemoryModel.delete(new_db_script)
|
||||||
|
|
@ -462,7 +465,7 @@ def create_player(name, email, password,
|
||||||
# this will either load the typeclass or the default one
|
# this will either load the typeclass or the default one
|
||||||
new_player = new_db_player.typeclass
|
new_player = new_db_player.typeclass
|
||||||
|
|
||||||
if not object.__getattribute__(new_db_player, "is_typeclass")(typeclass, exact=True):
|
if not GA(new_db_player, "is_typeclass")(typeclass, exact=True):
|
||||||
# this will fail if we gave a typeclass as input and it still gave us a default
|
# this will fail if we gave a typeclass as input and it still gave us a default
|
||||||
SharedMemoryModel.delete(new_db_player)
|
SharedMemoryModel.delete(new_db_player)
|
||||||
return None
|
return None
|
||||||
|
|
@ -494,7 +497,6 @@ def create_player(name, email, password,
|
||||||
return new_player
|
return new_player
|
||||||
except Exception,e:
|
except Exception,e:
|
||||||
# a failure in creating the character
|
# a failure in creating the character
|
||||||
print e
|
|
||||||
if not user:
|
if not user:
|
||||||
# in there was a failure we clean up everything we can
|
# in there was a failure we clean up everything we can
|
||||||
logger.log_trace()
|
logger.log_trace()
|
||||||
|
|
@ -510,6 +512,7 @@ def create_player(name, email, password,
|
||||||
del new_character
|
del new_character
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
raise
|
||||||
|
|
||||||
# alias
|
# alias
|
||||||
player = create_player
|
player = create_player
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue