Added VisibleKey, allowing objects to be locked so they are not visible by normal look command.

Fixed bug in create_object that sometimes caused rooms to be created with a location !=None
Expanded @destroy to better handle names and not just dbrefs.
/Griatch
This commit is contained in:
Griatch 2009-10-22 19:44:16 +00:00
parent 557c4eb07b
commit 656ecd9f97
6 changed files with 163 additions and 42 deletions

View file

@ -1022,6 +1022,7 @@ def cmd_dig(command):
None,
source_object,
script_parent=room_parent)
ptext = ""
if room_parent:
if new_room.get_script_parent() == room_parent:
@ -1277,26 +1278,26 @@ def cmd_destroy(command):
switch_override = True
for targetname in targetlist:
target_obj = source_object.search_for_object(targetname)
target_obj = source_object.search_for_object_global(targetname)
# Use search_for_object to handle duplicate/nonexistant results.
if not target_obj:
return
if target_obj.is_player() or target_obj.has_flag('SAFE'):
if source_object.id == target_obj.id:
source_object.emit_to("You can't destroy yourself.")
return
source_object.emit_to("%s: You can't destroy yourself." % targetname)
continue
if not switch_override:
source_object.emit_to("You must use @destroy/override on Players and objects with the SAFE flag set.")
return
source_object.emit_to("%s: You must use @destroy/override on Players and objects with the SAFE flag set." % targetname)
continue
if target_obj.is_superuser():
source_object.emit_to("You can't destroy a superuser.")
return
source_object.emit_to("%s: You can't destroy a superuser." % targetname)
continue
elif target_obj.is_garbage():
source_object.emit_to("That object is already destroyed.")
return
source_object.emit_to("%s: That object is already destroyed." % targetname)
continue
elif target_obj.is_going() and 'instant' not in switches:
source_object.emit_to("That object is already scheduled for destruction.")
return
source_object.emit_to("%s: That object is already scheduled for destruction." % targetname)
continue
# Run any scripted things that happen before destruction.
target_obj.scriptlink.at_object_destruction(pobject=source_object)
@ -1370,10 +1371,13 @@ def cmd_lock(command):
EnterLock: Players/Things: controls who may enter/teleport into
the object.
VisibleLock: Players/Things: controls if the object is visible to
someone using the look command.
Fail messages echoed to the player are stored in the attributes 'lock_msg',
'use_lock_msg' and 'enter_lock_msg' on the locked object in question. If no
such message is stored, a default will be used (or none at all in some cases).
'use_lock_msg', 'enter_lock_msg' and 'visible_lock_msg' on the locked object
in question. If no such message is stored, a default will be used (or none at
all in some cases).
"""
source_object = command.source_object
@ -1397,7 +1401,7 @@ def cmd_lock(command):
ltype = "DefaultLock"
obj_name, ltype = obj_name.strip(), ltype.strip()
if ltype not in ["DefaultLock","UseLock","EnterLock"]:
if ltype not in ["DefaultLock","UseLock","EnterLock","VisibleLock"]:
source_object.emit_to("Lock type '%s' not recognized." % ltype)
return
@ -1407,7 +1411,7 @@ def cmd_lock(command):
obj_locks = obj.get_attribute_value("LOCKS")
if "list" in switches or not switches:
if "list" in switches:
if not obj_locks:
s = "There are no locks on %s." % obj.get_name()
else:

View file

@ -44,10 +44,9 @@ class Key(object):
def __str__(self):
string = " "
if not self.criteria:
string += " <Impassable>"
for crit in self.criteria:
string += " %s," % crit
return string[:-1].strip()
string += " (Impassable)"
string += ", ".join(self.criteria)
return string
def _result(self, result):
"Return result depending on exact criterion."

View file

@ -133,21 +133,35 @@ class ObjectManager(models.Manager):
except IndexError:
return None
def global_object_name_search(self, ostring, exact_match=False, limit_types=[]):
def global_object_name_search(self, ostring, exact_match=True, limit_types=[]):
"""
Searches through all objects for a name match.
limit_types is a list of types as defined in defines_global.
"""
if self.is_dbref(ostring):
return [self.dbref_search(ostring, limit_types=limit_types)]
o_query = self.dbref_search(ostring, limit_types=limit_types)
if o_query:
return [o_query]
return None
# get rough match
o_query = self.filter(name__icontains=ostring)
o_query = o_query.exclude(type__in=[defines_global.OTYPE_GARBAGE,
defines_global.OTYPE_GOING])
if not o_query:
# use list-search to catch N-style queries. Note
# that we want to keep the original ostring since
# search_object_namestr does its own N-string treatment
# on this.
dum, test_ostring = self._parse_match_number(ostring)
o_query = self.filter(name__icontains=test_ostring)
o_query = o_query.exclude(type__in=[defines_global.OTYPE_GARBAGE,
defines_global.OTYPE_GOING])
match_type = "fuzzy"
if exact_match:
o_query = self.filter(name__iexact=ostring)
else:
o_query = self.filter(name__icontains=ostring)
if limit_types is not False:
for limiter in limit_types:
o_query.filter(type=limiter)
match_type = "exact"
return self.list_search_object_namestr(o_query, ostring,
limit_types=limit_types,
match_type=match_type)
return o_query.exclude(type__in=[defines_global.OTYPE_GARBAGE,
defines_global.OTYPE_GOING])
@ -196,16 +210,16 @@ class ObjectManager(models.Manager):
if prospect.dbref_match(ostring)]
#search by name - this may return multiple matches.
results = self._list_search_helper1(searchlist,ostring,dbref_only,
results = self._match_name_attribute(searchlist,ostring,dbref_only,
limit_types, match_type,
attribute_name=attribute_name)
match_number = None
if not results:
#if we have no match, check if we are dealing
#with a "N-keyword" query - if so, strip it and run again.
match_number, ostring = self._list_search_helper2(ostring)
match_number, ostring = self._parse_match_number(ostring)
if match_number != None and ostring:
results = self._list_search_helper1(searchlist,ostring,dbref_only,
results = self._match_name_attribute(searchlist,ostring,dbref_only,
limit_types, match_type,
attribute_name=attribute_name)
if match_type == "fuzzy":
@ -226,7 +240,7 @@ class ObjectManager(models.Manager):
pass
return results
def _list_search_helper1(self, searchlist, ostring, dbref_only,
def _match_name_attribute(self, searchlist, ostring, dbref_only,
limit_types, match_type,
attribute_name=None):
"""
@ -261,10 +275,10 @@ class ObjectManager(models.Manager):
return [prospect for prospect in searchlist
if prospect.name_match(ostring, match_type=match_type)]
def _list_search_helper2(self, ostring):
def _parse_match_number(self, ostring):
"""
Hhelper function for list_search_object_namestr -
strips eventual keyword-N endings from a search criterion
Helper function for list_search_object_namestr -
strips eventual N-keyword endings from a search criterion
"""
if not '-' in ostring:
return False, ostring
@ -426,6 +440,7 @@ class ObjectManager(models.Manager):
default_desc = defines_global.DESC_PLAYER
elif otype == defines_global.OTYPE_ROOM:
default_desc = defines_global.DESC_ROOM
location = None
elif otype == defines_global.OTYPE_EXIT:
default_desc = defines_global.DESC_EXIT
else:

View file

@ -221,23 +221,27 @@ class Object(models.Model):
else:
return results[0]
def search_for_object_global(self, ostring, exact_match=True, limit_types=[]):
def search_for_object_global(self, ostring, exact_match=True, limit_types=[],
emit_to_obj=None):
"""
Search for ostring in all objects, globally. Handle multiple-matches
and no matches gracefully. This is mainly intended to be used by
admin and build-type commands. It also accepts #dbref
search queries.
"""
if not emit_to_obj:
emit_to_obj = self
results = Object.objects.global_object_name_search(ostring, exact_match=exact_match,
limit_types=limit_types)
limit_types=limit_types)
if not results:
self.emit_to("No matches found for '%s'." % ostring)
emit_to_obj.emit_to("No matches found for '%s'." % ostring)
return
if len(results) > 1:
string = "More than one match for '%s' (please narrow target):" % ostring
for res in results:
string += "\n %s" % res.get_name()
self.emit_to(string)
emit_to_obj.emit_to(string)
return
return results[0]
@ -1157,7 +1161,10 @@ class Object(models.Model):
self.clear_all_attributes()
self.clear_all_flags()
self.clear_state()
self.home = None
self.owner = None
self.location = None
self.save()
# Deferred imports are poopy. This will require some thought to fix.
from src import cmdhandler

View file

@ -133,10 +133,17 @@ class EvenniaBasicObject(object):
* pobject: (Object) The object requesting the action.
"""
# This is the object being looked at.
target_obj = self.scripted_obj
target_obj = self.scripted_obj
# See if the envoker sees dbref numbers.
lock_msg = ""
if pobject:
#check visibility lock
if not target_obj.scriptlink.visible_lock(pobject):
temp = target_obj.get_attribute_value("visible_lock_msg")
if temp:
return temp
return "I don't see that here."
show_dbrefs = pobject.sees_dbrefs()
#check for the defaultlock, this shows a lock message after the normal desc, if one is defined.
@ -165,8 +172,11 @@ class EvenniaBasicObject(object):
con_exits = []
for obj in target_obj.get_contents():
# check visible lock.
if pobject and not obj.scriptlink.visible_lock(pobject):
continue
if obj.is_player():
if (obj != pobject and obj.is_connected_plr()) or pobject == None:
if (obj != pobject and obj.is_connected_plr()) or pobject == None:
con_players.append(obj)
elif obj.is_exit():
con_exits.append(obj)
@ -236,6 +246,21 @@ class EvenniaBasicObject(object):
else:
return True
def visible_lock(self, pobject):
"""
This method returns a True or False boolean value to determine whether
the actor passes the lock. This is generally used for picking up
objects or traversing exits.
values:
* pobject: (Object) The object requesting the action.
"""
locks = self.scripted_obj.get_attribute_value("LOCKS")
if locks:
return locks.check("VisibleLock", pobject)
else:
return True
def lock_func(self, obj):
"""
This is a custom function called by locks with the FuncKey key. Its

View file

@ -109,3 +109,74 @@ class EvenniaBasicPlayer(object):
location = pobject.get_location()
if location != None:
location.emit_to_contents("%s has disconnected." % (pobject.get_name(show_dbref=False),), exclude=pobject)
def default_lock(self, pobject):
"""
This method returns a True or False boolean value to determine whether
the actor passes the lock. This is generally used for picking up
objects or traversing exits.
values:
* pobject: (Object) The object requesting the action.
"""
locks = self.scripted_obj.get_attribute_value("LOCKS")
if locks:
return locks.check("DefaultLock", pobject)
else:
return True
def use_lock(self, pobject):
"""
This method returns a True or False boolean value to determine whether
the actor passes the lock. This is generally used for seeing whether
a player can use an object or any of its commands.
values:
* pobject: (Object) The object requesting the action.
"""
locks = self.scripted_obj.get_attribute_value("LOCKS")
if locks:
return locks.check("UseLock", pobject)
else:
return True
def enter_lock(self, pobject):
"""
This method returns a True or False boolean value to determine whether
the actor passes the lock. This is generally used for seeing whether
a player can enter another object.
values:
* pobject: (Object) The object requesting the action.
"""
locks = self.scripted_obj.get_attribute_value("LOCKS")
if locks:
return locks.check("EnterLock", pobject)
else:
return True
def visible_lock(self, pobject):
"""
This method returns a True or False boolean value to determine whether
the actor passes the lock. This is generally used for picking up
objects or traversing exits.
values:
* pobject: (Object) The object requesting the action.
"""
locks = self.scripted_obj.get_attribute_value("LOCKS")
if locks:
return locks.check("VisibleLock", pobject)
else:
return True
def lock_func(self, obj):
"""
This is a custom function called by locks with the FuncKey key. Its
return value should match that specified in the lock (so no true/false
lock result is actually determined in here). Default desired return
value is True. Also remember that the comparison in FuncKey is made
using the string representation of the return value, since @lock can
only define string lock criteria.
"""
return False