mirror of
https://github.com/evennia/evennia.git
synced 2026-03-27 18:26:32 +01:00
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:
parent
557c4eb07b
commit
656ecd9f97
6 changed files with 163 additions and 42 deletions
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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."
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue