diff --git a/contrib/chargen.py b/contrib/chargen.py new file mode 100644 index 0000000000..bf990c7728 --- /dev/null +++ b/contrib/chargen.py @@ -0,0 +1,196 @@ +""" + +Contribution - Griatch 2011 + +This is a simple character creation commandset. A suggestion is to +test this together with menu_login, which doesn't create a Character +on its own. This shows some more info and gives the Player the option +to create a character without any more customizations than their name +(further options are unique for each game anyway). + +Since this extends the OOC cmdset, logging in from the menu will +automatically drop the Player into this cmdset unless they logged off +while puppeting a Character already before. + +Installation: + +Import this module in game.gamesrc.basecmdset and +add the following line to the end of OOCCmdSet's at_cmdset_creation(): + + self.add(character_creation.OOCCmdSetExtended) + +You could also add/edit this line to your game/settings.py file: + +CMDSET_OOC = "contrib.character_creation.OOCCmdSetExtended" + +(uncomment the super() statement in OOCCmdSetExtended in this case +too) This will however only affect NEWLY created players, not those +already in the game, so you'd usually only do this if you are starting +from scratch. + +""" + +from django.conf import settings +from src.commands.command import Command +from src.commands.default.general import CmdLook +from src.commands.default.cmdset_ooc import OOCCmdSet +from src.objects.models import ObjectDB +from src.utils import utils, create + +CHARACTER_TYPECLASS = settings.BASE_CHARACTER_TYPECLASS + +class CmdOOCLook(CmdLook): + """ + ooc look + + Usage: + look + look + + This is an OOC version of the look command. Since a Player doesn't + have an in-game existence, there is no concept of location or + "self". + + If any characters are available for you to control, you may look + at them with this command. + """ + + key = "look" + aliases = ["l", "ls"] + locks = "cmd:all()" + help_cateogory = "General" + + def func(self): + """ + Implements the ooc look command + + We use an attribute _character_dbrefs on the player in order + to figure out which characters are "theirs". A drawback of this + is that only the CmdCharacterCreate command adds this attribute, + and thus e.g. player #1 will not be listed (although it will work). + Existence in this list does not depend on puppeting rights though, + that is checked by the @ic command directly. + """ + + # making sure caller is really a player + self.character = None + if utils.inherits_from(self.caller, "src.objects.objects.Object"): + # An object of some type is calling. Convert to player. + #print self.caller, self.caller.__class__ + self.character = self.caller + if hasattr(self.caller, "player"): + self.caller = self.caller.player + + if not self.character: + # ooc mode, we are players + + avail_chars = self.caller.db._character_dbrefs + if self.args: + # Maybe the caller wants to look at a character + if not avail_chars: + self.caller.msg("You have no characters to look at. Why not create one?") + return + objs = ObjectDB.objects.get_objs_with_key_and_typeclass(self.args.strip(), CHARACTER_TYPECLASS) + objs = [obj for obj in objs if obj.id in avail_chars] + if not objs: + self.caller.msg("You cannot see this Character.") + return + self.caller.msg(objs[0].return_appearance(self.caller)) + return + + # not inspecting a character. Show the OOC info. + charobjs = [] + charnames = [] + if self.caller.db._character_dbrefs: + dbrefs = self.caller.db._character_dbrefs + charobjs = [ObjectDB.objects.get_id(dbref) for dbref in dbrefs] + charnames = [charobj.key for charobj in charobjs if charobj] + if charnames: + charlist = "The following Character(s) are available:\n\n" + charlist += "\n\r".join(["{w %s{n" % charname for charname in charnames]) + charlist += "\n\n Use {w@ic {n to switch to that Character." + else: + charlist = "You have no Characters." + string = \ +""" You, %s, are an {wOOC ghost{n without form. The world is hidden + from you and besides chatting on channels your options are limited. + You need to have a Character in order to interact with the world. + + %s + + Use {wcreate {n to create a new character and {whelp{n for a + list of available commands.""" % (self.caller.key, charlist) + self.caller.msg(string) + + else: + # not ooc mode - leave back to normal look + self.caller = self.character # we have to put this back for normal look to work. + super(CmdOOCLook, self).func() + +class CmdOOCCharacterCreate(Command): + """ + creates a character + + Usage: + create + + This will create a new character, assuming + the given character name does not already exist. + """ + + key = "create" + locks = "cmd:all()" + + def func(self): + """ + Tries to create the Character object. We also put an + attribute on ourselves to remember it. + """ + + # making sure caller is really a player + self.character = None + if utils.inherits_from(self.caller, "src.objects.objects.Object"): + # An object of some type is calling. Convert to player. + #print self.caller, self.caller.__class__ + self.character = self.caller + if hasattr(self.caller, "player"): + self.caller = self.caller.player + + if not self.args: + self.caller.msg("Usage: create ") + return + charname = self.args.strip() + old_char = ObjectDB.objects.get_objs_with_key_and_typeclass(charname, CHARACTER_TYPECLASS) + if old_char: + self.caller.msg("Character {c%s{n already exists." % charname) + return + # create the character + + new_character = create.create_object(CHARACTER_TYPECLASS, key=charname) + if not new_character: + self.caller.msg("{rThe Character couldn't be created. This is a bug. Please contact an admin.") + return + # make sure to lock the character to only be puppeted by this player + new_character.locks.add("puppet:id(%i) or pid(%i) or perm(Immortals) or pperm(Immortals)" % + (new_character.id, self.caller.id)) + + # save dbref + avail_chars = self.caller.db._character_dbrefs + if avail_chars: + avail_chars.append(new_character.id) + else: + avail_chars = [new_character.id] + self.caller.db._character_dbrefs = avail_chars + + self.caller.msg("{gThe Character {c%s{g was successfully created!" % charname) + +class OOCCmdSetCharGen(OOCCmdSet): + """ + Extends the default OOC cmdset. + """ + def at_cmdset_creation(self): + "Install everything from the default set, then overload" + #super(OOCCmdSetExtended, self).at_cmdset_creation() + self.add(CmdOOCLook()) + self.add(CmdOOCCharacterCreate()) + diff --git a/game/gamesrc/commands/basecmdset.py b/game/gamesrc/commands/basecmdset.py index c45e8f6837..72ffd98443 100644 --- a/game/gamesrc/commands/basecmdset.py +++ b/game/gamesrc/commands/basecmdset.py @@ -24,7 +24,7 @@ from game.gamesrc.commands.basecommand import Command from contrib import menusystem, lineeditor #from contrib import misc_commands -#from contrib import character_creation +from contrib import chargen class DefaultCmdSet(cmdset_default.DefaultCmdSet): """ @@ -93,8 +93,8 @@ class OOCCmdSet(cmdset_ooc.OOCCmdSet): # # any commands you add below will overload the default ones. # + self.add(chargen.OOCCmdSetCharGen) - class BaseCmdSet(CmdSet): """ Implements an empty, example cmdset. diff --git a/src/objects/manager.py b/src/objects/manager.py index 52b1427cc7..8a19129780 100644 --- a/src/objects/manager.py +++ b/src/objects/manager.py @@ -69,11 +69,11 @@ class ObjectManager(TypedObjectManager): return self.get_object_with_user(dbref) @returns_typeclass_list - def get_objs_with_key_and_typeclass(oname, otypeclass_path): + def get_objs_with_key_and_typeclass(self, oname, otypeclass_path): """ Returns objects based on simultaneous key and typeclass match. """ - return self.filter(db_key__iexact=oname).filter(db_typeclass_path_exact=otypeclass_path) + return self.filter(db_key__iexact=oname).filter(db_typeclass_path__exact=otypeclass_path) # attr/property related