mirror of
https://github.com/evennia/evennia.git
synced 2026-04-05 07:27:17 +02:00
Largely rewrote and refactored the help system.
The help entry database structure has changed! You have to resync or purge your database or your will get problems! New features: * Help entry access now fully controlled by evennia permissions * Categories for each help entry * All entries are created dynamically, with a See also: footer calculated after the current state of the database. * Indexes and topic list calculated on the fly (alphabetically/after category) * Added auto-help help entries for all default commands. * Only shows commands _actually implemented_ - MUX help db moved into 'MUX' category which is not shown by default. * More powerful auto-help markup - supports categories and permissions (and inheritance). * Global on/off switch for auto-help, when entering production * Auto_help_override switch for selectively activating auto-help when developing new commands (like the old system). * Refactored State help system; no more risk of overwriting global help entries. * State help now defers to main help db when no match found; makes system more transparent. * State help entries also support categories/permissions (state categories are not used much though). Other updates: * Added more commands to the batch processor * Many bug-fixes. /Griatch
This commit is contained in:
parent
46e2cd3ecb
commit
8074617285
27 changed files with 1995 additions and 1072 deletions
|
|
@ -4,11 +4,13 @@ This is where all of the crucial, core object models reside.
|
|||
import re
|
||||
import traceback
|
||||
|
||||
try: import cPickle as pickle
|
||||
except ImportError: import pickle
|
||||
try:
|
||||
import cPickle as pickle
|
||||
except ImportError:
|
||||
import pickle
|
||||
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import User, Group
|
||||
from django.contrib.auth.models import User
|
||||
from django.conf import settings
|
||||
from src.objects.util import object as util_object
|
||||
from src.objects.managers.object import ObjectManager
|
||||
|
|
@ -24,8 +26,6 @@ from src import logger
|
|||
import src.flags
|
||||
from src.util import functions_general
|
||||
|
||||
from src.logger import log_infomsg
|
||||
|
||||
class Attribute(models.Model):
|
||||
"""
|
||||
Attributes are things that are specific to different types of objects. For
|
||||
|
|
@ -46,9 +46,9 @@ class Attribute(models.Model):
|
|||
def __str__(self):
|
||||
return "%s(%s)" % (self.attr_name, self.id)
|
||||
|
||||
"""
|
||||
BEGIN COMMON METHODS
|
||||
"""
|
||||
#
|
||||
# BEGIN COMMON METHODS
|
||||
#
|
||||
def get_name(self):
|
||||
"""
|
||||
Returns an attribute's name.
|
||||
|
|
@ -74,7 +74,8 @@ class Attribute(models.Model):
|
|||
"""
|
||||
Returns True if the attribute is hidden.
|
||||
"""
|
||||
if self.attr_hidden or self.get_name().upper() in defines_global.HIDDEN_ATTRIBS:
|
||||
if self.attr_hidden or self.get_name().upper() \
|
||||
in defines_global.HIDDEN_ATTRIBS:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
|
@ -83,7 +84,8 @@ class Attribute(models.Model):
|
|||
"""
|
||||
Returns True if the attribute is unsettable.
|
||||
"""
|
||||
if self.get_name().upper() in defines_global.NOSET_ATTRIBS: return True
|
||||
if self.get_name().upper() in defines_global.NOSET_ATTRIBS:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
|
@ -103,21 +105,28 @@ class Object(models.Model):
|
|||
ROOM, or other entities within the database. Pretty much anything in the
|
||||
game is an object. Objects may be one of several different types, and
|
||||
may be parented to allow for differing behaviors.
|
||||
|
||||
We eventually want to find some way to implement object parents via loadable
|
||||
modules or sub-classing.
|
||||
"""
|
||||
name = models.CharField(max_length=255)
|
||||
ansi_name = models.CharField(max_length=255)
|
||||
owner = models.ForeignKey('self', related_name="obj_owner", blank=True, null=True)
|
||||
zone = models.ForeignKey('self', related_name="obj_zone", blank=True, null=True)
|
||||
script_parent = models.CharField(max_length=255, blank=True, null=True)
|
||||
home = models.ForeignKey('self', related_name="obj_home", blank=True, null=True)
|
||||
owner = models.ForeignKey('self',
|
||||
related_name="obj_owner",
|
||||
blank=True, null=True)
|
||||
zone = models.ForeignKey('self',
|
||||
related_name="obj_zone",
|
||||
blank=True, null=True)
|
||||
script_parent = models.CharField(max_length=255,
|
||||
blank=True, null=True)
|
||||
home = models.ForeignKey('self',
|
||||
related_name="obj_home",
|
||||
blank=True, null=True)
|
||||
type = models.SmallIntegerField(choices=defines_global.OBJECT_TYPES)
|
||||
location = models.ForeignKey('self', related_name="obj_location", blank=True, null=True)
|
||||
location = models.ForeignKey('self',
|
||||
related_name="obj_location",
|
||||
blank=True, null=True)
|
||||
flags = models.TextField(blank=True, null=True)
|
||||
nosave_flags = models.TextField(blank=True, null=True)
|
||||
date_created = models.DateField(editable=False, auto_now_add=True)
|
||||
date_created = models.DateField(editable=False,
|
||||
auto_now_add=True)
|
||||
|
||||
# 'scriptlink' is a 'get' property for retrieving a reference to the correct
|
||||
# script object. Defined down by get_scriptlink()
|
||||
|
|
@ -125,10 +134,15 @@ class Object(models.Model):
|
|||
|
||||
objects = ObjectManager()
|
||||
|
||||
#state system can set a particular command table to be used (not persistent).
|
||||
# state system can set a particular command
|
||||
# table to be used (not persistent).
|
||||
state = None
|
||||
|
||||
class Meta:
|
||||
"""
|
||||
Define permission types on the object class and
|
||||
how it is ordered in the database.
|
||||
"""
|
||||
ordering = ['-date_created', 'id']
|
||||
permissions = settings.PERM_OBJECTS
|
||||
|
||||
|
|
@ -147,13 +161,17 @@ class Object(models.Model):
|
|||
"""
|
||||
return "#%s" % str(self.id)
|
||||
|
||||
"""
|
||||
BEGIN COMMON METHODS
|
||||
"""
|
||||
def search_for_object(self, ostring, emit_to_obj=None, search_contents=True,
|
||||
search_location=True, dbref_only=False,
|
||||
limit_types=False, search_aliases=False,
|
||||
attribute_name=None):
|
||||
#
|
||||
# BEGIN COMMON METHODS
|
||||
#
|
||||
def search_for_object(self, ostring,
|
||||
emit_to_obj=None,
|
||||
search_contents=True,
|
||||
search_location=True,
|
||||
dbref_only=False,
|
||||
limit_types=False,
|
||||
search_aliases=False,
|
||||
attribute_name=None):
|
||||
"""
|
||||
Perform a standard object search, handling multiple
|
||||
results and lack thereof gracefully.
|
||||
|
|
@ -187,13 +205,15 @@ class Object(models.Model):
|
|||
attribute_name=attribute_name)
|
||||
|
||||
if len(results) > 1:
|
||||
s = "More than one match for '%s' (please narrow target):" % ostring
|
||||
string = "More than one match for '%s' (please narrow target):" % ostring
|
||||
for num, result in enumerate(results):
|
||||
invtext = ""
|
||||
if result.get_location() == self:
|
||||
invtext = " (carried)"
|
||||
s += "\n %i-%s%s" % (num+1, result.get_name(show_dbref=False),invtext)
|
||||
emit_to_obj.emit_to(s)
|
||||
string += "\n %i-%s%s" % (num+1,
|
||||
result.get_name(show_dbref=False),
|
||||
invtext)
|
||||
emit_to_obj.emit_to(string)
|
||||
return False
|
||||
elif len(results) == 0:
|
||||
emit_to_obj.emit_to("I don't see that here.")
|
||||
|
|
@ -224,13 +244,18 @@ class Object(models.Model):
|
|||
for session in sessions:
|
||||
session.msg(parse_ansi(message))
|
||||
|
||||
def execute_cmd(self, command_str, session=None):
|
||||
def execute_cmd(self, command_str, session=None, ignore_state=False):
|
||||
"""
|
||||
Do something as this object.
|
||||
|
||||
bypass_state - ignore the fact that a player is in a state
|
||||
(means the normal command table will be used
|
||||
no matter what)
|
||||
"""
|
||||
# The Command object has all of the methods for parsing and preparing
|
||||
# for searching and execution. Send it to the handler once populated.
|
||||
cmdhandler.handle(cmdhandler.Command(self, command_str, session=session))
|
||||
cmdhandler.handle(cmdhandler.Command(self, command_str, session=session),
|
||||
ignore_state=ignore_state)
|
||||
|
||||
def emit_to_contents(self, message, exclude=None):
|
||||
"""
|
||||
|
|
@ -384,7 +409,8 @@ class Object(models.Model):
|
|||
|
||||
# When builder_override is enabled, a builder permission means
|
||||
# the object controls the other.
|
||||
if builder_override and not other_obj.is_player() and self.has_group('Builders'):
|
||||
if builder_override and not other_obj.is_player() \
|
||||
and self.has_group('Builders'):
|
||||
return True
|
||||
|
||||
# They've failed to meet any of the above conditions.
|
||||
|
|
@ -466,7 +492,8 @@ class Object(models.Model):
|
|||
uobj.is_active = False
|
||||
uobj.save()
|
||||
except:
|
||||
functions_general.log_errmsg('Destroying object %s but no matching player.' % (self,))
|
||||
string = 'Destroying object %s but no matching player.' % (self,)
|
||||
functions_general.log_errmsg(string)
|
||||
|
||||
# Set the object type to GOING
|
||||
self.type = defines_global.OTYPE_GOING
|
||||
|
|
@ -511,7 +538,7 @@ class Object(models.Model):
|
|||
"""
|
||||
# Gather up everything, other than exits and going/garbage, that is under
|
||||
# the belief this is its location.
|
||||
objs = self.obj_location.filter(type__in=[1,2,3])
|
||||
objs = self.obj_location.filter(type__in=[1, 2, 3])
|
||||
default_home_id = ConfigValue.objects.get_configvalue('default_home')
|
||||
try:
|
||||
default_home = Object.objects.get(id=default_home_id)
|
||||
|
|
@ -644,7 +671,8 @@ class Object(models.Model):
|
|||
"""
|
||||
Returns a QuerySet of an object's attributes.
|
||||
"""
|
||||
return [attr for attr in self.attribute_set.all() if not attr.is_hidden()]
|
||||
return [attr for attr in self.attribute_set.all()
|
||||
if not attr.is_hidden()]
|
||||
|
||||
|
||||
def clear_all_attributes(self):
|
||||
|
|
@ -684,9 +712,11 @@ class Object(models.Model):
|
|||
re.IGNORECASE)
|
||||
# If the regular expression search returns a match object, add to results.
|
||||
if exclude_noset:
|
||||
return [attr for attr in attrs if match_exp.search(attr.get_name()) and not attr.is_hidden() and not attr.is_noset()]
|
||||
return [attr for attr in attrs if match_exp.search(attr.get_name())
|
||||
and not attr.is_hidden() and not attr.is_noset()]
|
||||
else:
|
||||
return [attr for attr in attrs if match_exp.search(attr.get_name()) and not attr.is_hidden()]
|
||||
return [attr for attr in attrs if match_exp.search(attr.get_name())
|
||||
and not attr.is_hidden()]
|
||||
|
||||
|
||||
def has_flag(self, flag):
|
||||
|
|
@ -751,7 +781,10 @@ class Object(models.Model):
|
|||
self.save()
|
||||
|
||||
def unset_flag(self, flag):
|
||||
self.set_flag(flag,value=False)
|
||||
"""
|
||||
Clear the flag.
|
||||
"""
|
||||
self.set_flag(flag, value=False)
|
||||
|
||||
def get_flags(self):
|
||||
"""
|
||||
|
|
@ -815,7 +848,8 @@ class Object(models.Model):
|
|||
try:
|
||||
return self.location
|
||||
except:
|
||||
functions_general.log_errmsg("Object '%s(#%d)' has invalid location: #%s" % (self.name,self.id,self.location_id))
|
||||
functions_general.log_errmsg("Object '%s(#%d)' has invalid location: #%s" % \
|
||||
(self.name,self.id,self.location_id))
|
||||
return False
|
||||
|
||||
def get_scriptlink(self):
|
||||
|
|
@ -827,7 +861,7 @@ class Object(models.Model):
|
|||
|
||||
# Load the script reference into the object's attribute.
|
||||
self.scriptlink_cached = scripthandler.scriptlink(self,
|
||||
script_to_load)
|
||||
script_to_load)
|
||||
if self.scriptlink_cached:
|
||||
# If the scriptlink variable can't be populated, this will fail
|
||||
# silently and let the exception hit in the scripthandler.
|
||||
|
|
@ -857,7 +891,8 @@ class Object(models.Model):
|
|||
script_parent: (string) String pythonic import path of the script parent
|
||||
assuming the python path is game/gamesrc/parents.
|
||||
"""
|
||||
if script_parent != None and scripthandler.scriptlink(self, str(script_parent).strip()):
|
||||
if script_parent != None and scripthandler.scriptlink(self,
|
||||
str(script_parent).strip()):
|
||||
#assigning a custom parent
|
||||
self.script_parent = str(script_parent).strip()
|
||||
self.save()
|
||||
|
|
@ -1046,7 +1081,10 @@ class Object(models.Model):
|
|||
|
||||
#state access functions
|
||||
|
||||
def get_state(self):
|
||||
def get_state(self):
|
||||
"""
|
||||
Returns the player's current state.
|
||||
"""
|
||||
return self.state
|
||||
|
||||
def set_state(self, state_name=None):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue