mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
|
||||
class Script(BaseScript):
|
||||
"""
|
||||
All scripts should inherit from this class and implement
|
||||
some or all of its hook functions and variables.
|
||||
A script type is customized by redefining some or all of its hook methods and variables.
|
||||
|
||||
* 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
|
||||
that one instead.
|
||||
|
||||
Arguments:
|
||||
new_typeclass (path/classobj) - type to switch to
|
||||
clean_attributes (bool/list) - will delete all attributes
|
||||
stored on this object (but not any
|
||||
|
|
@ -1079,6 +1080,9 @@ class TypedObject(SharedMemoryModel):
|
|||
swapping to a default typeclass in case the given
|
||||
one fails for some reason. Instead the old one
|
||||
will be preserved.
|
||||
Returns:
|
||||
boolean True/False depending on if the swap worked or not.
|
||||
|
||||
"""
|
||||
if callable(new_typeclass):
|
||||
# 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
|
||||
__all__ = ("object", "script", "help_entry", "message", "channel", "player")
|
||||
|
||||
GA = object.__getattribute__
|
||||
|
||||
#
|
||||
# Game Object creation
|
||||
#
|
||||
|
||||
|
||||
def create_object(typeclass, key=None, location=None,
|
||||
home=None, player=None, permissions=None, locks=None,
|
||||
aliases=None, destination=None):
|
||||
|
|
@ -81,7 +84,7 @@ def create_object(typeclass, key=None, location=None,
|
|||
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
|
||||
SharedMemoryModel.delete(new_db_object)
|
||||
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
|
||||
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
|
||||
print "failure:", new_db_script, typeclass
|
||||
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
|
||||
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
|
||||
SharedMemoryModel.delete(new_db_player)
|
||||
return None
|
||||
|
|
@ -494,7 +497,6 @@ def create_player(name, email, password,
|
|||
return new_player
|
||||
except Exception,e:
|
||||
# a failure in creating the character
|
||||
print e
|
||||
if not user:
|
||||
# in there was a failure we clean up everything we can
|
||||
logger.log_trace()
|
||||
|
|
@ -510,6 +512,7 @@ def create_player(name, email, password,
|
|||
del new_character
|
||||
except Exception:
|
||||
pass
|
||||
raise
|
||||
|
||||
# alias
|
||||
player = create_player
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue