382 lines
12 KiB
Python
382 lines
12 KiB
Python
from evennia import default_cmds, create_object, search_tag
|
|
from evennia.utils import inherits_from
|
|
from evennia.utils.eveditor import EvEditor
|
|
from evennia.prototypes import spawner
|
|
|
|
from commands.command import Command
|
|
from typeclasses.exits import BaseDoor
|
|
from typeclasses.rooms import Room, Zone
|
|
|
|
def _descdoor_load(caller):
|
|
return caller.db.evmenu_target.db.desc or ""
|
|
|
|
|
|
def _descdoor_save(caller, buf):
|
|
"""
|
|
Save line buffer to the desc prop. This should
|
|
return True if successful and also report its status to the user.
|
|
"""
|
|
caller.db.evmenu_target.setdesc(buf)
|
|
caller.msg("Saved.")
|
|
return True
|
|
|
|
|
|
def _descdoor_quit(caller):
|
|
caller.attributes.remove("evmenu_target")
|
|
caller.msg("Exited editor.")
|
|
|
|
|
|
class CmdDescDoor(Command):
|
|
"""
|
|
describe a BaseDoor in the current room.
|
|
|
|
Usage:
|
|
descdoor <obj> = <description>
|
|
|
|
Switches:
|
|
edit - Open up a line editor for more advanced editing.
|
|
|
|
Sets the "desc" attribute on an object. If an object is not given,
|
|
describe the current room.
|
|
"""
|
|
|
|
key = "descdoor"
|
|
aliases = ["descd"]
|
|
switch_options = ("edit",)
|
|
locks = "cmd:perm(descdoor) or perm(Builder)"
|
|
help_category = "Building"
|
|
|
|
def edit_handler(self):
|
|
if self.rhs:
|
|
self.msg("|rYou may specify a value, or use the edit switch, " "but not both.|n")
|
|
return
|
|
if self.args:
|
|
obj = self.caller.search(self.args)
|
|
else:
|
|
obj = self.caller.location or self.msg("|rYou can't describe oblivion.|n")
|
|
if not obj:
|
|
return
|
|
|
|
if not (obj.access(self.caller, "control") or obj.access(self.caller, "edit")):
|
|
self.caller.msg("You don't have permission to edit the description of %s." % obj.key)
|
|
|
|
self.caller.db.evmenu_target = obj
|
|
# launch the editor
|
|
EvEditor(
|
|
self.caller,
|
|
loadfunc=_descdoor_load,
|
|
savefunc=_descdoor_save,
|
|
quitfunc=_descdoor_quit,
|
|
key="desc",
|
|
persistent=True,
|
|
)
|
|
return
|
|
|
|
def func(self):
|
|
"""Define command"""
|
|
|
|
caller = self.caller
|
|
if not self.args or ("=" in self.args and "edit" in self.switches):
|
|
caller.msg("Usage: descdoor <obj> = <description>")
|
|
return
|
|
|
|
if "edit" in self.switches:
|
|
self.edit_handler()
|
|
return
|
|
|
|
# We have an =
|
|
obj = caller.search(self.lhs)
|
|
if not obj:
|
|
return
|
|
desc = self.rhs or ""
|
|
|
|
if inherits_from(obj, BaseDoor):
|
|
if obj.access(self.caller, "control") or obj.access(self.caller, "edit"):
|
|
obj.setdesc(desc)
|
|
caller.msg("The description was set on %s." % obj.get_display_name(caller))
|
|
else:
|
|
caller.msg("You don't have permission to edit the description of %s." % obj.key)
|
|
else:
|
|
self.msg("|rYou can't describe oblivion.|n")
|
|
|
|
|
|
class CmdOpen(default_cmds.CmdOpen):
|
|
__doc__ = default_cmds.CmdOpen.__doc__
|
|
# overloading parts of the default CmdOpen command to support doors.
|
|
|
|
def create_exit(self, exit_name, location, destination, exit_aliases=None, typeclass=None):
|
|
"""
|
|
Simple wrapper for the default CmdOpen.create_exit
|
|
"""
|
|
# create a new exit as normal
|
|
new_exit = super().create_exit(
|
|
exit_name, location, destination, exit_aliases=exit_aliases, typeclass=typeclass
|
|
)
|
|
if hasattr(self, "return_exit_already_created"):
|
|
# we don't create a return exit if it was already created (because
|
|
# we created a door)
|
|
del self.return_exit_already_created
|
|
return new_exit
|
|
if inherits_from(new_exit, BaseDoor):
|
|
# a door - create its counterpart and make sure to turn off the default
|
|
# return-exit creation of CmdOpen
|
|
self.caller.msg(
|
|
"Note: A door-type exit was created - ignored eventual custom return-exit type."
|
|
)
|
|
self.return_exit_already_created = True
|
|
back_exit = self.create_exit(
|
|
exit_name, destination, location, exit_aliases=exit_aliases, typeclass=typeclass
|
|
)
|
|
new_exit.db.return_exit = back_exit
|
|
back_exit.db.return_exit = new_exit
|
|
return new_exit
|
|
|
|
|
|
class CmdUpdateLightState(Command):
|
|
"""
|
|
update room light state.
|
|
|
|
Usage:
|
|
update_light [targetroom]
|
|
"""
|
|
|
|
key = "update_light"
|
|
aliases = ["up_l"]
|
|
locks = "cmd:perm(update_light) or perm(Builder)"
|
|
help_category = "Building"
|
|
arg_regex = r"(?:^(?:\s+|\/).*$)|^$"
|
|
|
|
def func(self):
|
|
caller = self.caller
|
|
if not self.args:
|
|
target = caller.location
|
|
if not target:
|
|
caller.msg("You have no location to update!")
|
|
return
|
|
else:
|
|
target = caller.search(self.args)
|
|
if not (target.attributes.has("is_lit") and hasattr(target, "check_light_state")):
|
|
caller.msg(
|
|
"You cannot update lights on {}!".format(target.key))
|
|
return
|
|
|
|
target.check_light_state()
|
|
caller.msg("Performed update on {}!".format(target.key))
|
|
|
|
|
|
class CmdZone(Command):
|
|
"""
|
|
creates, deletes or lists zones
|
|
|
|
Usage:
|
|
zone[/add||/del||/map] [zonename] [= room|size]
|
|
|
|
Manages zones.
|
|
|
|
"""
|
|
|
|
key = "zone"
|
|
locks = "cmd:perm(zone) or perm(Builders)"
|
|
help_category = "Building"
|
|
|
|
def func(self):
|
|
"""
|
|
Creates the zone.
|
|
"""
|
|
|
|
caller = self.caller
|
|
|
|
if [ele for ele in ["del", "add", "map"] if(ele in self.switches)] and not self.args:
|
|
caller.msg(self.get_help(caller, self.cmdset))
|
|
return
|
|
|
|
if "del" in self.switches:
|
|
self.delete_zone()
|
|
elif "map" in self.switches:
|
|
self.print_map()
|
|
elif "add" in self.switches:
|
|
zone, errors = Zone.create(key=self.lhs, size=self.rhs)
|
|
if not errors:
|
|
caller.msg("Created zone |w{}|n.".format(zone.name))
|
|
else:
|
|
caller.msg("Errors creating zone:|n{}|n.".format(errors))
|
|
else:
|
|
string = ""
|
|
zones = search_tag(key="zone", category="general")
|
|
for zone in zones:
|
|
string += "|c{}|n ({})\n".format(zone.name, zone.dbref)
|
|
rooms = search_tag(key=zone.name, category="zoneId")
|
|
for room in rooms:
|
|
string += "- {} ({}) ({},{})\n".format(room.name, room.dbref, room.db.x, room.db.y)
|
|
|
|
caller.msg("Zones found: \n" + string)
|
|
|
|
def print_map(self):
|
|
caller = self.caller
|
|
zone = caller.search(self.args, global_search=True, exact=True)
|
|
if not zone:
|
|
return
|
|
|
|
map_str = ""
|
|
for y in range(zone.db.size):
|
|
for x in range(zone.db.size):
|
|
map_str += zone.ndb.map[x][y]['room_map_icon']
|
|
|
|
map_str += '|/'
|
|
|
|
caller.msg(map_str)
|
|
|
|
def delete_zone(self):
|
|
caller = self.caller
|
|
zone = caller.search(self.args, global_search=True, exact=True)
|
|
if not zone:
|
|
return
|
|
if not inherits_from(zone, Zone):
|
|
caller.msg("{} is not a valid zone.".format(zone.name))
|
|
return
|
|
|
|
key = zone.name
|
|
zone.delete()
|
|
caller.msg("Zone {} deleted.".format(key))
|
|
|
|
|
|
class CmdAddToZone(Command):
|
|
"""
|
|
add a room to a zone
|
|
|
|
Usage:
|
|
addtozone obj = zone,x,y
|
|
|
|
Adds a room to an existing zone.
|
|
"""
|
|
key = "addtozone"
|
|
locks = "cmd:perm(zone) or perm(Builders)"
|
|
help_category = "Building"
|
|
|
|
def func(self):
|
|
"""
|
|
Adds a room to an existing zone.
|
|
"""
|
|
|
|
caller = self.caller
|
|
if len(self.rhslist) < 3:
|
|
caller.msg(self.get_help(caller, self.cmdset))
|
|
return
|
|
|
|
zone_key, x, y = self.rhslist
|
|
|
|
if zone_key and x and y:
|
|
zone = caller.search(zone_key, global_search=True, exact=True)
|
|
if not zone:
|
|
caller.msg("Zone {} doesn't exist.".format(zone_key))
|
|
return
|
|
if not inherits_from(zone, Zone):
|
|
caller.msg("|r{} is not a valid zone.|n".format(zone.name))
|
|
return
|
|
|
|
room = caller.search(self.lhs, global_search=True, nofound_string="|rRoom {} doesn't exist.|n".format(self.lhs))
|
|
if not room:
|
|
return
|
|
if not inherits_from(room, Room):
|
|
caller.msg("|r{} is not a valid room.|n".format(room.name))
|
|
return
|
|
try:
|
|
if room.db.zone:
|
|
caller.msg("|r{} is already assigned to zone {}.|n".format(room.name, zone.name))
|
|
return
|
|
zone.add_room(room, x, y)
|
|
except ValueError as ve:
|
|
caller.msg(ve.args[0])
|
|
return
|
|
|
|
caller.msg("Room {} ({}) added to zone {} ({}).".format(room.name, room.dbref, zone.name, zone.dbref))
|
|
else:
|
|
caller.msg(self.get_help(caller, self.cmdset))
|
|
return
|
|
|
|
|
|
class CmdPopen(Command):
|
|
"""
|
|
open a new exit from prototype linking two rooms
|
|
|
|
Usage:
|
|
popen <prototype>[;alias;alias..] [,<return exit>[;alias;..]]] = <origin>,<destination>
|
|
|
|
Handles the creation of exits. If a destination is given, the exit
|
|
will point there. The <return exit> argument sets up an exit at the
|
|
destination leading back to the current room. Destination name
|
|
can be given both as a #dbref and a name, if that name is globally
|
|
unique.
|
|
|
|
"""
|
|
key = "popen"
|
|
locks = "cmd:perm(open) or perm(Builder)"
|
|
help_category = "Building"
|
|
|
|
new_obj_lockstring = "control:id({id}) or perm(Admin);delete:id({id}) or perm(Admin)"
|
|
|
|
def func(self):
|
|
"""
|
|
This is where the processing starts.
|
|
Uses the ObjManipCommand.parser() for pre-processing
|
|
as well as the self.create_exit() method.
|
|
"""
|
|
caller = self.caller
|
|
|
|
if not self.args or not self.rhs or len(self.rhslist) != 2:
|
|
caller.msg(self.get_help(caller, self.cmdset))
|
|
return
|
|
|
|
exit_prototype = self.lhs_objs[0]["name"]
|
|
exit_aliases = self.lhs_objs[0]["aliases"]
|
|
|
|
location_name, destination_name = self.rhslist
|
|
|
|
# first, check if the destination and origin exist.
|
|
destination = caller.search(destination_name, global_search=True)
|
|
if not destination:
|
|
return
|
|
|
|
location = caller.search(location_name, global_search=True)
|
|
if not location:
|
|
return
|
|
|
|
try:
|
|
exit_obj, *rest = spawner.spawn(exit_prototype)
|
|
except KeyError:
|
|
caller.msg("Prototype {} not found".format(exit_prototype))
|
|
return
|
|
|
|
exit_obj.location = location
|
|
exit_obj.destination = destination
|
|
exit_obj.aliases.add(exit_aliases)
|
|
|
|
return_exit_object = None
|
|
|
|
if len(self.lhs_objs) == 2:
|
|
return_exit_prototype = self.lhs_objs[1]["name"]
|
|
return_exit_aliases = self.lhs_objs[1]["aliases"]
|
|
|
|
try:
|
|
return_exit_object, *rest = spawner.spawn(return_exit_prototype)
|
|
except KeyError:
|
|
caller.msg("Return prototype {} not found, rolling back...".format(return_exit_prototype))
|
|
exit_obj.delete()
|
|
return
|
|
|
|
return_exit_object.location = destination
|
|
return_exit_object.destination = location
|
|
|
|
# BaseDoor requires a return exit
|
|
if inherits_from(exit_obj, "typeclasses.exits.BaseDoor"):
|
|
if not return_exit_object:
|
|
return_exit_object, *rest = spawner.spawn(exit_prototype)
|
|
return_exit_object.location = destination
|
|
return_exit_object.destination = location
|
|
|
|
exit_obj.db.return_exit = return_exit_object
|
|
return_exit_object.db.return_exit = exit_obj
|
|
|
|
caller.msg("Created exit {} from {} to {}.".format(exit_obj.name, location.name, destination.name))
|
|
if return_exit_object:
|
|
caller.msg("Created exit {} from {} to {}.".format(return_exit_object.name, destination.name, location.name))
|