mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
Added the ability to give multiple typeclass search-paths to config file. This way you can add a path to your custom directory and don't have to write so much when creating typeclassed objects using e.g. @create.
This commit is contained in:
parent
b9c1921a0b
commit
d2400a8a6b
11 changed files with 112 additions and 173 deletions
70
README
70
README
|
|
@ -5,6 +5,7 @@ Evennia README http://evennia.com
|
||||||
- < 2010 (earlier revisions)
|
- < 2010 (earlier revisions)
|
||||||
- May 2010 - merged ABOUT and README. Added Current status /Griatch
|
- May 2010 - merged ABOUT and README. Added Current status /Griatch
|
||||||
- Aug 2010 - evennia devel merged into trunk /Griatch
|
- Aug 2010 - evennia devel merged into trunk /Griatch
|
||||||
|
- May 2011 - all commands implemented, web client, contribs /Griatch
|
||||||
|
|
||||||
Contents:
|
Contents:
|
||||||
---------
|
---------
|
||||||
|
|
@ -23,21 +24,17 @@ Evennia Alpha SVN version
|
||||||
|
|
||||||
About Evennia
|
About Evennia
|
||||||
-------------
|
-------------
|
||||||
Evennia is a proof-of-concept MU* server that aims to provide a functional
|
|
||||||
bare-bones base for developers. While there are quite a few codebases that do the same
|
|
||||||
(and very well in many cases), we are taking a unique spin on the problem.
|
|
||||||
Some of our flagship features include (or will one day include):
|
|
||||||
|
|
||||||
* Coded fully in Python using Django and Twisted
|
Evennia is a MUD/MUX/MU* server that aims to provide a functional
|
||||||
* Extensive web integration.
|
bare-bones base for developers. Some of our main features are:
|
||||||
* The ability to build/administer through a web browser.
|
|
||||||
* Shared accounts between the website and the game.
|
* Coded and extended using normal Python modules.
|
||||||
* Optional web-based character creation.
|
* Extensive web integration due to our use of Django.
|
||||||
|
* Runs its own Twisted webserver. Comes with game website and ajax web-browser mud client.
|
||||||
|
* Extensive current and potential connectivity and protocol-support through Twisted.
|
||||||
* Extremely easy-to-manipulate SQL database back-end via Django
|
* Extremely easy-to-manipulate SQL database back-end via Django
|
||||||
(djangoproject.com)
|
(djangoproject.com)
|
||||||
* Simple and easily extensible design.
|
* Powerful an extremely extendable bare-bones base system
|
||||||
* Very granular permissions. Individual and group based.
|
|
||||||
* Powerful an extremely extendable base system
|
|
||||||
|
|
||||||
The essential points here are the web integration and the SQL backing via
|
The essential points here are the web integration and the SQL backing via
|
||||||
Django. The Django framework has database abstraction abilities that give us
|
Django. The Django framework has database abstraction abilities that give us
|
||||||
|
|
@ -60,6 +57,14 @@ See the INSTALL file for help on setting up and running Evennia.
|
||||||
|
|
||||||
Current Status
|
Current Status
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
May 2011:
|
||||||
|
The new version of Evennia, originally hitting trunk in Aug2010, is
|
||||||
|
maturing. All commands from the pre-Aug version, including IRC/IMC2
|
||||||
|
support works again. An ajax web-client was added earlier in the year,
|
||||||
|
including moving Evennia to be its own webserver (no more need for
|
||||||
|
Apache or django-testserver). Contrib-folder added.
|
||||||
|
|
||||||
Aug 2010:
|
Aug 2010:
|
||||||
Evennia-griatch-branch is ready for merging with trunk. This marks
|
Evennia-griatch-branch is ready for merging with trunk. This marks
|
||||||
a rather big change in the inner workings of the server, but should
|
a rather big change in the inner workings of the server, but should
|
||||||
|
|
@ -77,17 +82,16 @@ to Events, Commands and Permissions.
|
||||||
|
|
||||||
Contact, Support and Development
|
Contact, Support and Development
|
||||||
-----------------------
|
-----------------------
|
||||||
We are early in development, but we try to give support best we can
|
This is still alpha software, but we try to give support best we can
|
||||||
if you feel daring enough to play with the codebase. Make a post to
|
if you have questions. Make a post to the mailing list or chat us up
|
||||||
the mailing list or chat us up on IRC if you have questions. We also
|
on IRC. We also have a bug tracker if you want to report
|
||||||
have a bug tracker if you want to report bugs. Finally, if
|
bugs. Finally, if you are willing to help with the code work, we much
|
||||||
you are willing to help with the code work, we much appreciate all help!
|
appreciate all help! Visit either of the following resources:
|
||||||
Visit either of the following resources:
|
|
||||||
|
|
||||||
* Evennia Webpage
|
* Evennia Webpage
|
||||||
http://evennia.com
|
http://evennia.com
|
||||||
|
|
||||||
* Evennia wiki (documentation)
|
* Evennia manual (wiki)
|
||||||
http://code.google.com/p/evennia/wiki/Index
|
http://code.google.com/p/evennia/wiki/Index
|
||||||
|
|
||||||
* Evennia Code Page (See INSTALL text for installation)
|
* Evennia Code Page (See INSTALL text for installation)
|
||||||
|
|
@ -107,8 +111,10 @@ evennia
|
||||||
| |___(engine-related dirs)
|
| |___(engine-related dirs)
|
||||||
|
|
|
|
||||||
|_______game (start the server)
|
|_______game (start the server)
|
||||||
|___gamesrc
|
| |___gamesrc
|
||||||
|___(game-related dirs)
|
| |___(game-related dirs)
|
||||||
|
|
|
||||||
|
|_______contrib
|
||||||
|
|
||||||
The two main directories you will spend most of your time in
|
The two main directories you will spend most of your time in
|
||||||
are src/ and game/ (probably mostly game/).
|
are src/ and game/ (probably mostly game/).
|
||||||
|
|
@ -129,6 +135,11 @@ to make your dream game. game/ contains the main server settings
|
||||||
and the actual evennia executable to start things. game/gamesrc/
|
and the actual evennia executable to start things. game/gamesrc/
|
||||||
holds all the templates for creating objects in your virtual world.
|
holds all the templates for creating objects in your virtual world.
|
||||||
|
|
||||||
|
contrib/ contains optional code snippets. These are potentially useful
|
||||||
|
but deemed to be too game-specific to be part of the server itself.
|
||||||
|
Modules in contrib are not used unless you yourself decide to import
|
||||||
|
and use them.
|
||||||
|
|
||||||
With this little first orientation, you should head into the online
|
With this little first orientation, you should head into the online
|
||||||
Evennia wiki documentation to get going with the codebase.
|
Evennia wiki documentation to get going with the codebase.
|
||||||
|
|
||||||
|
|
@ -140,18 +151,15 @@ for capable admins to craft their own respective games. It is not the
|
||||||
intention to provide a full-fledged, ready-to-run base, rather Evennia
|
intention to provide a full-fledged, ready-to-run base, rather Evennia
|
||||||
is offering the means to make such games.
|
is offering the means to make such games.
|
||||||
|
|
||||||
2) Development of games on Evennia must be easy for anyone with some degree
|
2) Development of games on Evennia must be easy for anyone with some
|
||||||
of Python experience. Building needs to be easy, and per-room, per-object,
|
degree of Python experience. Building needs to be easy, and per-room,
|
||||||
and environmental customizations need to be simple to do.
|
per-object, and environmental customizations need to be simple to
|
||||||
|
do. This is handled by use of normal Python classes transparently
|
||||||
|
abstracting and wrapping the SQL backend. The user should not need to
|
||||||
|
use SQL or even know Django to any greater extent.
|
||||||
|
|
||||||
3) The server must utilize SQL as a storage back-end to allow for web->game
|
3) The server must utilize SQL as a storage back-end to allow for web->game
|
||||||
integration. See the details on Django later on in the document for more
|
integration through Django.
|
||||||
details.
|
|
||||||
|
|
||||||
4) Any and all game-specific configuration must reside in SQL, not
|
|
||||||
external configuration files. The only exception is the settings.py file
|
|
||||||
containing the SQL information.
|
|
||||||
|
|
||||||
|
|
||||||
The Components
|
The Components
|
||||||
--------------
|
--------------
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ or you won't see any messages!
|
||||||
import random
|
import random
|
||||||
from game.gamesrc.scripts.basescript import Script
|
from game.gamesrc.scripts.basescript import Script
|
||||||
|
|
||||||
|
|
||||||
class BodyFunctions(Script):
|
class BodyFunctions(Script):
|
||||||
"""
|
"""
|
||||||
This class defines the script itself
|
This class defines the script itself
|
||||||
|
|
@ -24,7 +23,7 @@ class BodyFunctions(Script):
|
||||||
self.key = "bodyfunction"
|
self.key = "bodyfunction"
|
||||||
self.desc = "Adds various timed events to a character."
|
self.desc = "Adds various timed events to a character."
|
||||||
self.interval = 20 # seconds
|
self.interval = 20 # seconds
|
||||||
self.start_delay # wait self.interval until first call
|
self.start_delay = True # wait self.interval until first call
|
||||||
self.persistent = False
|
self.persistent = False
|
||||||
|
|
||||||
def at_repeat(self):
|
def at_repeat(self):
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ if not os.path.exists('settings.py'):
|
||||||
# this file. Try to *only* copy over things you really need to customize
|
# this file. Try to *only* copy over things you really need to customize
|
||||||
# and do *not* make any changes to src/settings_default.py directly.
|
# and do *not* make any changes to src/settings_default.py directly.
|
||||||
# This way you'll always have a sane default to fall back on
|
# This way you'll always have a sane default to fall back on
|
||||||
# (also, the master file may change with server updates).
|
# (also, the master config file may change with server updates).
|
||||||
#
|
#
|
||||||
|
|
||||||
from src.settings_default import *
|
from src.settings_default import *
|
||||||
|
|
@ -62,7 +62,7 @@ from src.settings_default import *
|
||||||
###################################################
|
###################################################
|
||||||
|
|
||||||
###################################################
|
###################################################
|
||||||
# Default Object typeclasses
|
# Typeclasses
|
||||||
###################################################
|
###################################################
|
||||||
|
|
||||||
###################################################
|
###################################################
|
||||||
|
|
@ -90,7 +90,7 @@ from src.settings_default import *
|
||||||
###################################################
|
###################################################
|
||||||
|
|
||||||
###################################################
|
###################################################
|
||||||
# Evennia components (django apps)
|
# Evennia components
|
||||||
###################################################
|
###################################################
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -386,19 +386,8 @@ class CmdCreate(ObjManipCommand):
|
||||||
aliases = objdef['aliases']
|
aliases = objdef['aliases']
|
||||||
typeclass = objdef['option']
|
typeclass = objdef['option']
|
||||||
|
|
||||||
# analyze typeclass. If it starts at the evennia basedir,
|
|
||||||
# (i.e. starts with game or src) we let it be, otherwise we
|
|
||||||
# add a base path as defined in settings
|
|
||||||
if typeclass and not (typeclass.startswith('src.') or
|
|
||||||
typeclass.startswith('game.') or
|
|
||||||
typeclass.startswith('contrib')):
|
|
||||||
|
|
||||||
typeclass = "%s.%s" % (settings.BASE_TYPECLASS_PATH,
|
|
||||||
typeclass)
|
|
||||||
|
|
||||||
# create object (if not a valid typeclass, the default
|
# create object (if not a valid typeclass, the default
|
||||||
# object typeclass will automatically be used)
|
# object typeclass will automatically be used)
|
||||||
|
|
||||||
lockstring = "control:id(%s);examine:perm(Builders);delete:id(%s) or perm(Wizards);get:all()" % (caller.id, caller.id)
|
lockstring = "control:id(%s);examine:perm(Builders);delete:id(%s) or perm(Wizards);get:all()" % (caller.id, caller.id)
|
||||||
obj = create.create_object(typeclass, name, caller,
|
obj = create.create_object(typeclass, name, caller,
|
||||||
home=caller, aliases=aliases, locks=lockstring)
|
home=caller, aliases=aliases, locks=lockstring)
|
||||||
|
|
@ -420,7 +409,6 @@ class CmdCreate(ObjManipCommand):
|
||||||
caller.msg(string)
|
caller.msg(string)
|
||||||
|
|
||||||
|
|
||||||
#TODO: make @debug more clever with arbitrary hooks?
|
|
||||||
class CmdDebug(MuxCommand):
|
class CmdDebug(MuxCommand):
|
||||||
"""
|
"""
|
||||||
Debug game entities
|
Debug game entities
|
||||||
|
|
@ -438,11 +426,7 @@ class CmdDebug(MuxCommand):
|
||||||
@debug/obj examples.red_button.RedButton
|
@debug/obj examples.red_button.RedButton
|
||||||
|
|
||||||
This command helps when debugging the codes of objects and scripts.
|
This command helps when debugging the codes of objects and scripts.
|
||||||
It creates the given object and runs tests on its hooks. You can
|
It creates the given object and runs tests on its hooks.
|
||||||
supply both full paths (starting from the evennia base directory),
|
|
||||||
otherwise the system will start from the defined root directory
|
|
||||||
for scripts and objects respectively (defined in settings file).
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
key = "@debug"
|
key = "@debug"
|
||||||
|
|
@ -459,27 +443,11 @@ class CmdDebug(MuxCommand):
|
||||||
path = self.args
|
path = self.args
|
||||||
|
|
||||||
if 'obj' in self.switches or 'object' in self.switches:
|
if 'obj' in self.switches or 'object' in self.switches:
|
||||||
# analyze path. If it starts at the evennia basedir,
|
|
||||||
# (i.e. starts with game or src) we let it be, otherwise we
|
|
||||||
# add a base path as defined in settings
|
|
||||||
if path and not (path.startswith('src.') or
|
|
||||||
path.startswith('game.')):
|
|
||||||
path = "%s.%s" % (settings.BASE_TYPECLASS_PATH,
|
|
||||||
path)
|
|
||||||
|
|
||||||
# create and debug the object
|
# create and debug the object
|
||||||
self.caller.msg(debug.debug_object(path, self.caller))
|
self.caller.msg(debug.debug_object(path, self.caller))
|
||||||
self.caller.msg(debug.debug_object_scripts(path, self.caller))
|
self.caller.msg(debug.debug_object_scripts(path, self.caller))
|
||||||
|
|
||||||
elif 'script' in self.switches:
|
elif 'script' in self.switches:
|
||||||
# analyze path. If it starts at the evennia basedir,
|
|
||||||
# (i.e. starts with game or src) we let it be, otherwise we
|
|
||||||
# add a base path as defined in settings
|
|
||||||
if path and not (path.startswith('src.') or
|
|
||||||
path.startswith('game.')):
|
|
||||||
path = "%s.%s" % (settings.BASE_SCRIPT_PATH,
|
|
||||||
path)
|
|
||||||
|
|
||||||
self.caller.msg(debug.debug_syntax_script(path))
|
self.caller.msg(debug.debug_syntax_script(path))
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -629,16 +597,7 @@ class CmdDig(ObjManipCommand):
|
||||||
if not typeclass:
|
if not typeclass:
|
||||||
typeclass = settings.BASE_ROOM_TYPECLASS
|
typeclass = settings.BASE_ROOM_TYPECLASS
|
||||||
|
|
||||||
# analyze typeclass path. If it starts at the evennia basedir,
|
|
||||||
# (i.e. starts with game or src) we let it be, otherwise we
|
|
||||||
# add a base path as defined in settings
|
|
||||||
if typeclass and not (typeclass.startswith('src.') or
|
|
||||||
typeclass.startswith('game.')):
|
|
||||||
typeclass = "%s.%s" % (settings.BASE_TYPECLASS_PATH,
|
|
||||||
typeclass)
|
|
||||||
|
|
||||||
# create room
|
# create room
|
||||||
|
|
||||||
lockstring = "control:id(%s) or perm(Immortal); delete:id(%s) or perm(Wizard); edit:id(%s) or perm(Wizard)"
|
lockstring = "control:id(%s) or perm(Immortal); delete:id(%s) or perm(Wizard); edit:id(%s) or perm(Wizard)"
|
||||||
lockstring = lockstring % (caller.dbref, caller.dbref, caller.dbref)
|
lockstring = lockstring % (caller.dbref, caller.dbref, caller.dbref)
|
||||||
|
|
||||||
|
|
@ -669,13 +628,7 @@ class CmdDig(ObjManipCommand):
|
||||||
typeclass = to_exit["option"]
|
typeclass = to_exit["option"]
|
||||||
if not typeclass:
|
if not typeclass:
|
||||||
typeclass = settings.BASE_EXIT_TYPECLASS
|
typeclass = settings.BASE_EXIT_TYPECLASS
|
||||||
# analyze typeclass. If it starts at the evennia basedir,
|
|
||||||
# (i.e. starts with game or src) we let it be, otherwise we
|
|
||||||
# add a base path as defined in settings
|
|
||||||
if typeclass and not (typeclass.startswith('src.') or
|
|
||||||
typeclass.startswith('game.')):
|
|
||||||
typeclass = "%s.%s" % (settings.BASE_TYPECLASS_PATH,
|
|
||||||
typeclass)
|
|
||||||
new_to_exit = create.create_object(typeclass, to_exit["name"], location,
|
new_to_exit = create.create_object(typeclass, to_exit["name"], location,
|
||||||
aliases=to_exit["aliases"],
|
aliases=to_exit["aliases"],
|
||||||
locks=lockstring, destination=new_room)
|
locks=lockstring, destination=new_room)
|
||||||
|
|
@ -701,13 +654,6 @@ class CmdDig(ObjManipCommand):
|
||||||
typeclass = back_exit["option"]
|
typeclass = back_exit["option"]
|
||||||
if not typeclass:
|
if not typeclass:
|
||||||
typeclass = settings.BASE_EXIT_TYPECLASS
|
typeclass = settings.BASE_EXIT_TYPECLASS
|
||||||
# analyze typeclass. If it starts at the evennia basedir,
|
|
||||||
# (i.e. starts with game or src) we let it be, otherwise we
|
|
||||||
# add a base path as defined in settings
|
|
||||||
if typeclass and not (typeclass.startswith('src.') or
|
|
||||||
typeclass.startswith('game.')):
|
|
||||||
typeclass = "%s.%s" % (settings.BASE_TYPECLASS_PATH,
|
|
||||||
typeclass)
|
|
||||||
new_back_exit = create.create_object(typeclass, back_exit["name"],
|
new_back_exit = create.create_object(typeclass, back_exit["name"],
|
||||||
new_room, aliases=back_exit["aliases"],
|
new_room, aliases=back_exit["aliases"],
|
||||||
locks=lockstring, destination=location)
|
locks=lockstring, destination=location)
|
||||||
|
|
@ -1068,14 +1014,6 @@ class CmdOpen(ObjManipCommand):
|
||||||
exit_aliases = self.lhs_objs[0]['aliases']
|
exit_aliases = self.lhs_objs[0]['aliases']
|
||||||
exit_typeclass = self.lhs_objs[0]['option']
|
exit_typeclass = self.lhs_objs[0]['option']
|
||||||
|
|
||||||
# analyze typeclass. If it starts at the evennia basedir,
|
|
||||||
# (i.e. starts with game or src) we let it be, otherwise we
|
|
||||||
# add a base path as defined in settings
|
|
||||||
if exit_typeclass and not (exit_typeclass.startswith('src.') or
|
|
||||||
exit_typeclass.startswith('game.')):
|
|
||||||
exit_typeclass = "%s.%s" % (settings.BASE_TYPECLASS_PATH,
|
|
||||||
exit_typeclass)
|
|
||||||
|
|
||||||
dest_name = self.rhs_objs[0]['name']
|
dest_name = self.rhs_objs[0]['name']
|
||||||
|
|
||||||
# first, check so the destination exists.
|
# first, check so the destination exists.
|
||||||
|
|
@ -1097,13 +1035,6 @@ class CmdOpen(ObjManipCommand):
|
||||||
back_exit_aliases = self.rhs_objs[1]['name']
|
back_exit_aliases = self.rhs_objs[1]['name']
|
||||||
back_exit_typeclass = self.rhs_objs[1]['option']
|
back_exit_typeclass = self.rhs_objs[1]['option']
|
||||||
|
|
||||||
# analyze typeclass. If it starts at the evennia basedir,
|
|
||||||
# (i.e. starts with game or src) we let it be, otherwise we
|
|
||||||
# add a base path as defined in settings
|
|
||||||
if back_exit_typeclass and not (back_exit_typeclass.startswith('src.') or
|
|
||||||
back_exit_typeclass.startswith('game.')):
|
|
||||||
back_exit_typeclass = "%s.%s" % (settings.BASE_TYPECLASS_PATH,
|
|
||||||
back_exit_typeclass)
|
|
||||||
# Create the back-exit
|
# Create the back-exit
|
||||||
self.create_exit(back_exit_name, destination, location,
|
self.create_exit(back_exit_name, destination, location,
|
||||||
back_exit_aliases, back_exit_typeclass)
|
back_exit_aliases, back_exit_typeclass)
|
||||||
|
|
@ -1250,14 +1181,6 @@ class CmdTypeclass(MuxCommand):
|
||||||
# we have an =, a typeclass was supplied.
|
# we have an =, a typeclass was supplied.
|
||||||
typeclass = self.rhs
|
typeclass = self.rhs
|
||||||
|
|
||||||
# analyze typeclass. If it starts at the evennia basedir,
|
|
||||||
# (i.e. starts with game or src) we let it be, otherwise we
|
|
||||||
# add a base path as defined in settings
|
|
||||||
if typeclass and not (typeclass.startswith('src.') or
|
|
||||||
typeclass.startswith('game.')):
|
|
||||||
typeclass = "%s.%s" % (settings.BASE_TYPECLASS_PATH,
|
|
||||||
typeclass)
|
|
||||||
|
|
||||||
if not obj.access(caller, 'edit'):
|
if not obj.access(caller, 'edit'):
|
||||||
caller.msg("You are not allowed to do that.")
|
caller.msg("You are not allowed to do that.")
|
||||||
return
|
return
|
||||||
|
|
@ -1827,34 +1750,38 @@ class CmdScript(MuxCommand):
|
||||||
caller.msg(string)
|
caller.msg(string)
|
||||||
return
|
return
|
||||||
|
|
||||||
inp = self.rhs
|
|
||||||
if not inp.startswith('src.') and not inp.startswith('game.'):
|
|
||||||
# append the default path.
|
|
||||||
inp = "%s.%s" % (settings.BASE_SCRIPT_PATH, inp)
|
|
||||||
|
|
||||||
obj = caller.search(self.lhs)
|
obj = caller.search(self.lhs)
|
||||||
if not obj:
|
if not obj:
|
||||||
return
|
return
|
||||||
|
|
||||||
string = ""
|
string = ""
|
||||||
if "stop" in self.switches:
|
|
||||||
# we are stopping an already existing script
|
|
||||||
ok = obj.scripts.stop(inp)
|
|
||||||
if not ok:
|
|
||||||
string = "Script %s could not be stopped. Does it exist?" % inp
|
|
||||||
else:
|
|
||||||
string = "Script stopped and removed from object."
|
|
||||||
if "start" in self.switches:
|
|
||||||
# we are starting an already existing script
|
|
||||||
ok = obj.scripts.start(inp)
|
|
||||||
if not ok:
|
|
||||||
string = "Script %s could not be (re)started." % inp
|
|
||||||
else:
|
|
||||||
string = "Script started successfully."
|
|
||||||
if not self.switches:
|
if not self.switches:
|
||||||
# adding a new script, and starting it
|
# adding a new script, and starting it
|
||||||
ok = obj.scripts.add(inp, autostart=True)
|
ok = obj.scripts.add(self.rhs, autostart=True)
|
||||||
if not ok:
|
if not ok:
|
||||||
string = "Script %s could not be added." % inp
|
string += "\nScript %s could not be added." % self.rhs
|
||||||
else:
|
else:
|
||||||
string = "Script successfully added and started."
|
string = "Script successfully added and started."
|
||||||
caller.msg(string)
|
|
||||||
|
else:
|
||||||
|
paths = [self.rhs] + ["%s.%s" % (prefix, self.rhs)
|
||||||
|
for prefix in settings.SCRIPT_TYPECLASS_PATHS]
|
||||||
|
if "stop" in self.switches:
|
||||||
|
# we are stopping an already existing script
|
||||||
|
for path in paths:
|
||||||
|
ok = obj.scripts.stop(path)
|
||||||
|
if not ok:
|
||||||
|
string += "\nScript %s could not be stopped. Does it exist?" % path
|
||||||
|
else:
|
||||||
|
string = "Script stopped and removed from object."
|
||||||
|
break
|
||||||
|
if "start" in self.switches:
|
||||||
|
# we are starting an already existing script
|
||||||
|
for path in paths:
|
||||||
|
ok = obj.scripts.start(path)
|
||||||
|
if not ok:
|
||||||
|
string += "\nScript %s could not be (re)started." % path
|
||||||
|
else:
|
||||||
|
string = "Script started successfully."
|
||||||
|
break
|
||||||
|
caller.msg(string.strip())
|
||||||
|
|
|
||||||
|
|
@ -420,7 +420,7 @@ def serversetting(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
serversetting(IRC_ENABLED)
|
serversetting(IRC_ENABLED)
|
||||||
serversetting(BASE_SCRIPT_PATH, game.gamesrc.scripts)
|
serversetting(BASE_SCRIPT_PATH, [game.gamesrc.scripts])
|
||||||
|
|
||||||
A given True/False or integers will be converted properly.
|
A given True/False or integers will be converted properly.
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -418,9 +418,10 @@ class ObjectDB(TypedObject):
|
||||||
# ObjectDB class access methods/properties
|
# ObjectDB class access methods/properties
|
||||||
#
|
#
|
||||||
|
|
||||||
# this is required to properly handle attributes
|
# this is required to properly handle attributes and typeclass loading.
|
||||||
attribute_model_path = "src.objects.models"
|
attribute_model_path = "src.objects.models"
|
||||||
attribute_model_name = "ObjAttribute"
|
attribute_model_name = "ObjAttribute"
|
||||||
|
typeclass_paths = settings.OBJECT_TYPECLASS_PATHS
|
||||||
|
|
||||||
# this is used by all typedobjects as a fallback
|
# this is used by all typedobjects as a fallback
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -261,9 +261,10 @@ class PlayerDB(TypedObject):
|
||||||
except Exception:
|
except Exception:
|
||||||
default_typeclass_path = "src.players.player.Player"
|
default_typeclass_path = "src.players.player.Player"
|
||||||
|
|
||||||
# this is required to properly handle attributes
|
# this is required to properly handle attributes and typeclass loading
|
||||||
attribute_model_path = "src.players.models"
|
attribute_model_path = "src.players.models"
|
||||||
attribute_model_name = "PlayerAttribute"
|
attribute_model_name = "PlayerAttribute"
|
||||||
|
typeclass_paths = settings.PLAYER_TYPECLASS_PATHS
|
||||||
|
|
||||||
# name property (wraps self.user.username)
|
# name property (wraps self.user.username)
|
||||||
#@property
|
#@property
|
||||||
|
|
|
||||||
|
|
@ -243,9 +243,10 @@ class ScriptDB(TypedObject):
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
# this is required to properly handle typeclass-dependent attributes
|
# this is required to properly handle attrubutes and typeclass loading
|
||||||
attribute_model_path = "src.scripts.models"
|
attribute_model_path = "src.scripts.models"
|
||||||
attribute_model_name = "ScriptAttribute"
|
attribute_model_name = "ScriptAttribute"
|
||||||
|
typeclass_paths = settings.SCRIPT_TYPECLASS_PATHS
|
||||||
|
|
||||||
# this is used by all typedobjects as a fallback
|
# this is used by all typedobjects as a fallback
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -161,20 +161,19 @@ CMDSET_DEFAULT = "game.gamesrc.commands.basecmdset.DefaultCmdSet"
|
||||||
CMDSET_OOC = "game.gamesrc.commands.basecmdset.OOCCmdSet"
|
CMDSET_OOC = "game.gamesrc.commands.basecmdset.OOCCmdSet"
|
||||||
|
|
||||||
###################################################
|
###################################################
|
||||||
# Default Object typeclasses
|
# Typeclasses
|
||||||
###################################################
|
###################################################
|
||||||
|
|
||||||
# Note that all typeclasses must originally
|
# Base paths for typeclassed object classes. These paths must be
|
||||||
# inherit from src.objects.objects.Object somewhere in
|
# defined relative evennia's root directory. They will be searched in
|
||||||
# their path.
|
# order to find relative typeclass paths.
|
||||||
|
OBJECT_TYPECLASS_PATHS = ["game.gamesrc.objects", "game.gamesrc.objects.examples"]
|
||||||
|
SCRIPT_TYPECLASS_PATHS = ["game.gamesrc.scripts", "game.gamesrc.scripts.examples"]
|
||||||
|
PLAYER_TYPECLASS_PATHS = ["game.gamesrc.objects"]
|
||||||
|
|
||||||
# This sets the default base dir to search when importing
|
|
||||||
# things, so one doesn't have to write the entire
|
|
||||||
# path in-game.
|
|
||||||
BASE_TYPECLASS_PATH = "game.gamesrc.objects"
|
|
||||||
# Typeclass for player objects (linked to a character) (fallback)
|
# Typeclass for player objects (linked to a character) (fallback)
|
||||||
BASE_PLAYER_TYPECLASS = "game.gamesrc.objects.baseobjects.Player"
|
BASE_PLAYER_TYPECLASS = "game.gamesrc.objects.baseobjects.Player"
|
||||||
# Typeclass and base for all following objects (fallback)
|
# Typeclass and base for all objects (fallback)
|
||||||
BASE_OBJECT_TYPECLASS = "game.gamesrc.objects.baseobjects.Object"
|
BASE_OBJECT_TYPECLASS = "game.gamesrc.objects.baseobjects.Object"
|
||||||
# Typeclass for character objects linked to a player (fallback)
|
# Typeclass for character objects linked to a player (fallback)
|
||||||
BASE_CHARACTER_TYPECLASS = "game.gamesrc.objects.baseobjects.Character"
|
BASE_CHARACTER_TYPECLASS = "game.gamesrc.objects.baseobjects.Character"
|
||||||
|
|
@ -183,14 +182,6 @@ BASE_ROOM_TYPECLASS = "game.gamesrc.objects.baseobjects.Room"
|
||||||
# Typeclass for Exit objects (fallback)
|
# Typeclass for Exit objects (fallback)
|
||||||
BASE_EXIT_TYPECLASS = "game.gamesrc.objects.baseobjects.Exit"
|
BASE_EXIT_TYPECLASS = "game.gamesrc.objects.baseobjects.Exit"
|
||||||
|
|
||||||
###################################################
|
|
||||||
# Scripts
|
|
||||||
###################################################
|
|
||||||
|
|
||||||
# Python path to a directory to start searching
|
|
||||||
# for scripts.
|
|
||||||
BASE_SCRIPT_PATH = "game.gamesrc.scripts"
|
|
||||||
|
|
||||||
###################################################
|
###################################################
|
||||||
# Batch processors
|
# Batch processors
|
||||||
###################################################
|
###################################################
|
||||||
|
|
|
||||||
|
|
@ -561,6 +561,7 @@ class TypedObject(SharedMemoryModel):
|
||||||
# attribute model (ObjAttribute, PlayerAttribute etc).
|
# attribute model (ObjAttribute, PlayerAttribute etc).
|
||||||
attribute_model_path = "src.typeclasses.models"
|
attribute_model_path = "src.typeclasses.models"
|
||||||
attribute_model_name = "Attribute"
|
attribute_model_name = "Attribute"
|
||||||
|
typeclass_paths = settings.OBJECT_TYPECLASS_PATHS
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return other and hasattr(other, 'id') and self.id == other.id
|
return other and hasattr(other, 'id') and self.id == other.id
|
||||||
|
|
@ -647,20 +648,31 @@ class TypedObject(SharedMemoryModel):
|
||||||
defpath = object.__getattribute__(self, 'default_typeclass_path')
|
defpath = object.__getattribute__(self, 'default_typeclass_path')
|
||||||
typeclass = object.__getattribute__(self, '_path_import')(defpath)
|
typeclass = object.__getattribute__(self, '_path_import')(defpath)
|
||||||
#typeclass = self._path_import(defpath)
|
#typeclass = self._path_import(defpath)
|
||||||
else:
|
else:
|
||||||
typeclass = TYPECLASS_CACHE.get(path, None)
|
# handle loading/importing of typeclasses, searching all paths.
|
||||||
if typeclass:
|
# (self.typeclss_paths is a shortcut to settings.TYPECLASS_*_PATH
|
||||||
# we've imported this before. We're done.
|
# where '*' is either OBJECT, SCRIPT or PLAYER depending on the typed
|
||||||
return typeclass
|
# object).
|
||||||
# not in cache. Import anew.
|
typeclass_paths = [path] + ["%s.%s" % (prefix, path) for prefix in self.typeclass_paths]
|
||||||
typeclass = object.__getattribute__(self, "_path_import")(path)
|
for tpath in typeclass_paths:
|
||||||
if not callable(typeclass):
|
# try to find any matches to the typeclass path, in all possible permutations..
|
||||||
# given path failed to import, fallback to default.
|
typeclass = TYPECLASS_CACHE.get(tpath, None)
|
||||||
errstring = " %s" % typeclass # this is an error message
|
if typeclass:
|
||||||
if hasattr(typeclass, '__file__'):
|
# we've imported this before. We're done.
|
||||||
errstring += "\nThis seems to be just the path to a module. You need"
|
return typeclass
|
||||||
|
# not in cache. Try to import anew.
|
||||||
|
typeclass = object.__getattribute__(self, "_path_import")(tpath)
|
||||||
|
if callable(typeclass):
|
||||||
|
# don't return yet, we must cache this further down.
|
||||||
|
break
|
||||||
|
elif hasattr(typeclass, '__file__'):
|
||||||
|
errstring += "\n%s seems to be just the path to a module. You need" % tpath
|
||||||
errstring += " to specify the actual typeclass name inside the module too."
|
errstring += " to specify the actual typeclass name inside the module too."
|
||||||
errstring += "\n Typeclass '%s' failed to load." % path
|
else:
|
||||||
|
errstring += "\n%s" % typeclass # this will hold an error message.
|
||||||
|
|
||||||
|
if not callable(typeclass):
|
||||||
|
# Still not a valid import. Fallback to default.
|
||||||
defpath = object.__getattribute__(self, "default_typeclass_path")
|
defpath = object.__getattribute__(self, "default_typeclass_path")
|
||||||
errstring += " Using Default class '%s'." % defpath
|
errstring += " Using Default class '%s'." % defpath
|
||||||
self.db_typeclass_path = defpath
|
self.db_typeclass_path = defpath
|
||||||
|
|
@ -669,7 +681,7 @@ class TypedObject(SharedMemoryModel):
|
||||||
typeclass = object.__getattribute__(self, "_path_import")(defpath)
|
typeclass = object.__getattribute__(self, "_path_import")(defpath)
|
||||||
errmsg(errstring)
|
errmsg(errstring)
|
||||||
if not callable(typeclass):
|
if not callable(typeclass):
|
||||||
# if typeclass still doesn't exist, we're in trouble.
|
# if typeclass still doesn't exist at this point, we're in trouble.
|
||||||
# fall back to hardcoded core class.
|
# fall back to hardcoded core class.
|
||||||
errstring = " %s\n%s" % (typeclass, errstring)
|
errstring = " %s\n%s" % (typeclass, errstring)
|
||||||
errstring += " Default class '%s' failed to load." % defpath
|
errstring += " Default class '%s' failed to load." % defpath
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,6 @@ class MetaTypeClass(type):
|
||||||
def __str__(cls):
|
def __str__(cls):
|
||||||
return "%s" % cls.__name__
|
return "%s" % cls.__name__
|
||||||
|
|
||||||
|
|
||||||
class TypeClass(object):
|
class TypeClass(object):
|
||||||
"""
|
"""
|
||||||
This class implements a 'typeclass' object. This is connected
|
This class implements a 'typeclass' object. This is connected
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue