'''Dungeons and Dragons Mod for Source First Version found @ http://addons.eventscripts.com/addons/view/dnd Mod Based of Dungeons and Dragons 4.0 System (Pen and Paper) Preview Info: http://dnd4.com/phb By: J3ff Hoogland''' import es, popuplib, random, gamethread, cPickle, os.path, math info = es.AddonInfo() info.name = 'Dungeons and Dragons: Source' info.version = '0.0.1 Python' info.url = 'http://addons.eventscripts.com/addons/view/dnds' info.basename = 'dnds' info.author = 'J3ff Hoogland' es.ServerVar('D&D',info.version,'Dungeons and Dragons By: J3ff Hoogland').makepublic() #Being Events #Begin Player Events def player_spawn(ev): userid = int(ev['userid']) Player(userid).CheckCharacter() def player_death(ev): global Players userid = int(ev['userid']) if Players.has_key(userid): for d in Players[userid]['delay list']: gamethread.cancelDelayed(d) Players[userid]['delay list'] = [] #End Player Events #Begin global events def round_end(ev): global Players winner = int(ev['winner']) for d in Players['delay list']: gamethread.cancelDelayed(d) Players['delay list'] = [] for id in Players: if id != 'delay list': for d in Players[id]['delay list']: gamethread.cancelDelayed(d) Players[id]['delay list'] = [] #End global events #End Events #Our looping method that handel things such as saving and messaging that the mod is running def LoopBlock(): es.msg('#multi', '#green[Dungeons and Dragons] #defaultSource Mod is Running.') str_path = open(es.getAddonPath('dnds') + '/Characters.db', 'w') cPickle.dump(Characters, str_path) str_path.close() gamethread.delayed(30, LoopBlock) #Looping block that keep's all user's gravity at the correct amount def GravityCheck(): for id in es.getUseridList(): es.server.es_fire(id, '!self', 'addoutput', '"gravity %s"'%Player(id).Get('keyvalue', 'gravity')) gamethread.delayed(0.5, GravityCheck) #End looping block #Begin Load Method (And commands) dir = str(es.ServerVar('eventscripts_gamedir')).replace('\\', '/').split('/')[~0] if dir == 'cstrike': game = 'Counter-Strike: Source' elif dir == 'hl2mp': game = 'Half Life 2 Deathmatch' elif dir == 'dod': game = 'Day of Defeat: Source' elif dir == 'pvkii': game = 'Pirates, Vikings, and Knights' elif dir == 'tf': game = 'Team Fortress 2' else: game = 'Unknown' Players = {'delay list':[]} Races = {'Dragonborn':{'info':[]}, 'Dwarf':{'info':[]}, 'Eladrin':{'info':[]}, 'Elf':{'info':[]}, 'Half Elf':{'info':[]}, 'Halfling':{'info':[]}, 'Human':{'info':[]}, 'Tiefling':{'info':[]}} Race_List = ['Dragonborn','Dwarf','Eladrin','Elf','Half Elf','Halfling','Human','Tiefling'] Classes = {'Cleric':{'info':[]}, 'Fighter':{'info':[]}, 'Paladin':{'info':[]}, 'Ranger':{'info':[]}, 'Rogue':{'info':[]}, 'Warlock':{'info':[]}, 'Warlord':{'info':[]}, 'Wizard':{'info':[]}} Class_List = ['Cleric','Fighter','Paladin','Ranger','Rogue','Warlock','Warlord','Wizard'] Characters = {} # Level : Xp Needed to Obtain it Levels = {2:1000, 3:2250, 4:3750, 5:5500, 6:7500, 7:10000, 8:13000, 9:16500, 10:20500, 11:25500, 12:31500, 13:38500, 14:46500, 15:56500, 16:68500, 17:82500, 18:98500, 19:118500, 20:142500, 21:170500, 22:202500, 23:244000, 24:295000, 25:355500, 26:425500, 27:515500, 28:625500, 29:755500, 30:905500} def load(): es.dbgmsg(0, '[Dungeons and Dragons] - Begin Load') global Characters str_path = es.getAddonPath('dnds') + '/Characters.db' if os.path.isfile(str_path): file_users = open(str_path) Characters = cPickle.load(file_users) file_users.close() if not es.exists('saycommand', 'dnd'): es.regsaycmd('dnd', 'dnds/Command') if not es.exists('clientcommand', 'dnd'): es.regclientcmd('dnd', 'dnds/Command') ServerVars = {} for x in ServerVars: es.ServerVar(x).set(ServerVars[x]) es.mexec('..addons/eventscripts/dnds/dnds.cfg') LoopBlock() GravityCheck() es.dbgmsg(0, '[Dungeons and Dragons] - Load Finished') #End Load Methods #Begin unload methods def unload(): es.dbgmsg(0, '[Dungeons and Dragons] - Unload Start') es.dbgmsg(0, '[Dungeons and Dragons] - Unload End') #end unload methods #Begin global methods #End global methods #Begin Classes #Our menu class, handels all static and dynamic menus class Menu(object): def __init__(self, userid): self.userid = int(userid) Player(self.userid).Update() Character(self.userid).Update() self.name = es.getplayername(self.userid) if not Players[self.userid]['character']: Player(userid).CheckCharacter() self.character = Players[self.userid]['character'] self.characterkey = Characters[self.character] self.player = Player(self.userid) def MainMenu(self, userid=None, choice=None, popupid=None): MMenu = popuplib.create('MMenu') MMenu.addline('-{ Dungeons and Dragons Main Menu }-') MMenu.addline('-> 1. Create Character') MMenu.addline('-> 2. Load Character') MMenu.addline('-> 3. Current Character Information') MMenu.addline('-> 6. Information Menu') MMenu.addline('-> 7. Help Menu') MMenu.addline('0. - Exit') MMenu.menuselect = self.MainMenuSelect MMenu.send(self.userid) def MainMenuSelect(self, userid=None, choice=None, popupid=None): if choice == 1: if Player(self.userid).Get('isdead'): es.tell(self.userid, '#multi', '#green[Dungeons and Dragons] #defaultHit your #lightgreenEscape Key #defaultand then type the name you want in the open field.') es.escinputbox(10, self.userid, '-{ Dungeons and Dragons Character Creation }-', 'Enter a Name:', 'dnd create') else: es.tell(self.userid, '#multi', '#green[Dungeons and Dragons] #defaultYou must be dead to create a new character.') elif choice == 2: Player(self.userid).CharacterMenu() elif choice == 3: self.CharacterInformation() elif choice == 6: self.InfoMenu() elif choice == 7: self.HelpMenu() def CharacterInformation(self, userid=None, choice=None, popupid=None): if popuplib.exists('statsmenu'): popuplib.delete('statsmenu') statsmenu = popuplib.create('statsmenu') statsmenu.addline('Character Information:') statsmenu.addline('Name: %s'%self.character) statsmenu.addline('Experience: %s'%self.characterkey['xp']) statsmenu.addline('-> 9. Back to Main Menu') statsmenu.addline('0. - Exit') statsmenu.menuselect = self.CISelect statsmenu.send(self.userid) def HelpMenu(self, userid=None, choice=None, popupid=None): welcomemenu = popuplib.create('welcomemenu') welcomemenu.addline('-{ Welcome to a Dungeons and Dragons }-') welcomemenu.addline('- dnd Command List -') welcomemenu.addline('- dnd Menu - A main menu for the mod -') welcomemenu.addline('- dnd Create - Start creating your character -') welcomemenu.addline('- dnd Load - Load a preexisting character -') welcomemenu.addline('- dnd Stats - See what character your are playing -') welcomemenu.addline('- dnd Info - Displays information about different dnd features -') welcomemenu.addline('- dnd Help - This Menu -') welcomemenu.addline('-> 9. To Main Menu') welcomemenu.addline('0. - Exit') welcomemenu.menuselect = self.MainMenu welcomemenu.send(self.userid) def InfoMenu(self, userid=None, choice=None, popupid=None): infomenu = popuplib.create('infomenu') infomenu.addline('-{ Dungeons and Dragons Information Menu }-') infomenu.addline('-> 1. Races') infomenu.addline('-> 9. To Main Menu') infomenu.addline('0. - Exit') infomenu.menuselect = self.InfoSelect infomenu.send(self.userid) def InfoSelect(self, userid=None, choice=None, popupid=None): if choice == 9: self.MainMenu() elif choice is 1: self.RaceInfo() def RaceMenu(self, userid=None, choice=None, popupid=None): RMenu = popuplib.easymenu('race menu', None, self.RaceSelect) RMenu.settitle('Select a Race:') for race in Race_List: RMenu.addoption(race, race) RMenu.addoption('info', 'Race Information') RMenu.send(self.userid) def RaceSelect(self, userid=None, choice=None, popupid=None): if choice is not 'info': self.characterkey['race'] = choice self.ClassMenu() else: self.RaceInfo() def RaceInfo(self, userid=None, choice=None, popupid=None): RMenu = popuplib.easymenu('race info', None, self.RaceInfoSelect) RMenu.settitle('Select a Race to Learn About:') for race in Race_List: RMenu.addoption(race, race) if self.characterkey['race'] is 'Pending': RMenu.addoption('pick', 'Ready to Select a Race') RMenu.send(self.userid) def RaceInfoSelect(self, userid=None, choice=None, popupid=None): if choice is 'pick': self.RaceMenu() else: infomenu = popuplib.create('%s info'%choice) infomenu.addline('- %s Info -'%choice) for line in Races[choice]['info']: infomenu.addline(line) if self.characterkey['race'] is 'Pending': self.player.key['pending'] = choice infomenu.addline('-> 8. Select this Race') infomenu.addline('-> 9. Back') infomenu.addline('0. Exit') infomenu.menuselect = self.InfoRaceSelect infomenu.send(self.userid) def InfoRaceSelect(self, userid=None, choice=None, popupid=None): if choice == 8 and self.player.key['pending'] and self.characterkey['race'] is 'Pending': self.RaceSelect(choice=self.player.key['pending']) elif choice is 9: self.RaceInfo() self.player.key['pending'] = None def ClassMenu(self, userid=None, choice=None, popupid=None): CMenu = popuplib.easymenu('Class menu', None, self.Classeselect) CMenu.settitle('Select a Class:') for Class in Class_List: CMenu.addoption(Class, Class) CMenu.addoption('info', 'Class Information') CMenu.send(self.userid) def ClassSelect(self, userid=None, choice=None, popupid=None): if choice is not 'info': self.characterkey['classes'][choice] = {'level':1} else: self.ClassInfo() def ClassInfo(self, userid=None, choice=None, popupid=None): CMenu = popuplib.easymenu('Class info', None, self.ClassInfoSelect) CMenu.settitle('Select a Class to Learn About:') for Class in Class_List: CMenu.addoption(Class, Class) if not self.characterkey['classes']: CMenu.addoption('pick', 'Ready to Select a Class') CMenu.send(self.userid) def ClassInfoSelect(self, userid=None, choice=None, popupid=None): if choice is 'pick': self.ClassMenu() else: infomenu = popuplib.create('%s info'%choice) infomenu.addline('- %s Info -'%choice) for line in Classes[choice]['info']: infomenu.addline(line) if not self.characterkey['classes']: self.player.key['pending'] = choice infomenu.addline('-> 8. Select this Class') infomenu.addline('-> 9. Back') infomenu.addline('0. Exit') infomenu.menuselect = self.InfoClasseselect infomenu.send(self.userid) def InfoClasseselect(self, userid=None, choice=None, popupid=None): if choice is 8 and self.player.key['pending'] and not self.characterkey['classes']: self.Classeselect(choice=self.player.key['pending']) elif choice is 9: self.ClassInfo() self.player.key['pending'] = None #Begin Player Class class Player(object): global Players def __init__(self, userid): self.userid = int(userid) self.steamid = es.getplayersteamid(self.userid) self.name = es.getplayername(self.userid) if not Players.has_key(self.userid): Players[self.userid] = {} Players[self.userid]['character'] = None Players[self.userid]['pending'] = None Players[self.userid]['characters list'] = [] Players[self.userid]['delay list'] = [] Players[self.userid]['gravity'] = 1.0 self.attributes = es.createplayerlist(self.userid)[self.userid] self.key = Players[self.userid] def Update(self): pass def CheckCharacter(self): for x in Characters: if Characters[x]['creator'] == self.steamid: if not self.key['character']: self.key['character'] = x if x not in self.key['characters list']: self.key['characters list'].append(x) if not self.key['character']: Character(self.userid).Setup(self.name, 1) def AddCharacter(self, Name): self.key['characters list'].append(Name) self.key['character'] = Name def SetCharacter(self, Name): if Characters.has_key(Name): if not self.LoopCharacter(Name): self.key['character'] = Name es.tell(self.userid, '#multi', '#green[Dungeons and Dragons] #defaultCharacter changed to #lightgreen%s#default.'%Name) else: es.tell(self.userid, '#multi', '#green[Dungeons and Dragons] #defaultSorry #lightgreen%s #defaultis already loaded by another player.'%Name) else: es.tell(self.userid, '#multi', '#green[Dungeons and Dragons] #defaultSorry #lightgreen%s #defaultwas not found in our character database.'%Name) def LoopCharacter(self, Name): for x in es.getUseridList(): if Players[x]['character'] == Name: return 1 return 0 def TempCharacter(self, Name): if Characters.has_key(Name): if Characters[Name]['password'] != 'locked': self.key['pending'] = Name es.tell(self.userid, '#multi', '#green[Dungeons and Dragons] #defaultCharacter #lightgreen%s #defaultPending. Press your Escape Key to finish loading.'%Name) es.escinputbox(10, self.userid, '-{ Dungeons and Dragons Load Character }-', 'Enter the Password:', 'dnd passwordenter') else: es.tell(self.userid, '#multi', '#green[Dungeons and Dragons] #defaultSorry #lightgreen%s #defaultis a locked character.'%Name) else: es.tell(self.userid, '#multi', '#green[Dungeons and Dragons] #defaultSorry #lightgreen%s #defaultwas not found in our character database.'%Name) def PasswordEnter(self, Password): if self.key['pending']: if Password == Characters[self.key['pending']]['password']: self.SetCharacter(self.key['pending']) else: es.tell(self.userid, '#multi', '#green[Dungeons and Dragons] #defaultYou do not have a character waiting to be loaded.') def CharacterMenu(self): CMenu = popuplib.easymenu('CMenu', '_popup_choice', self.CharacterMenuSelect) CMenu.settitle('%s\'s Characters:'%self.name) for x in self.key['characters list']: CMenu.addoption(x, x) CMenu.send(self.userid) def CharacterMenuSelect(self, userid, choice, popupid): es.sexec(self.userid, 'dnd load %s'%choice) def Delayed(self, duration, function, parama=(), Endround=None): if not Endround: gamethread.delayedname(duration, len(self.key['delay list'])+1, function, parama) self.key['delay list'].append(len(self.key['delay list'])+1) else: gamethread.delayedname(duration, len(Players['delay list'])+1, function, parama) Players['delay list'].append(len(Players['delay list'])+1) #Most Get/Set Code taken from playerlib.py def Get(self, param, passparam=None): param = str(param).lower() if param == "keyvalue": if self.key.has_key(passparam): return self.key[passparam] else: return 0 #Syntax: .Get("nearplayer", ) elif param == "nearplayer": nearlist = [] x1,y1,z1 = es.getplayerlocation(self.userid) for id in es.getUseridList(): x2,y2,z2 = es.getplayerlocation(id) if abs(x1-x2) <= passparam and abs(y1-y2) <= passparam and abs(z1-z2) <= passparam and id != self.userid: nearlist.append(id) return nearlist #Syntax: .Get("nearcoord", (,,,)) elif param == "nearcoord": nearlist = [] x1,y1,z1 = passparam[0],passparam[1],passparam[2] for id in es.getUseridList(): x2,y2,z2 = es.getplayerlocation(id) if abs(x1-x2) <= passparam[3] and abs(y1-y2) <= passparam[3] and abs(z1-z2) <= passparam[3]: nearlist.append(id) return nearlist elif param == "onground": return es.getplayerprop(self.userid, 'CBasePlayer.m_fFlags') & 1 elif param == "viewangle": myRotation = es.getplayerprop(self.userid, "CBaseEntity.m_angRotation") myRotation = es.splitvectorstring(myRotation) myEyeAngle0 = es.getplayerprop(self.userid, "CBasePlayer.m_angEyeAngles[0]") myEyeAngle1 = es.getplayerprop(self.userid, "CBasePlayer.m_angEyeAngles[1]") if myEyeAngle1 < 0: myEyeAngle1 += 360 myViewAngle = (float(myEyeAngle0), float(myEyeAngle1), float(myRotation[2])) return myViewAngle elif param == "health": return es.getplayerprop(self.userid, "CBasePlayer.m_iHealth") elif param == "speed": return es.getplayerprop(self.userid, "CBasePlayer.localdata.m_flLaggedMovementValue") elif param == "viewvector": myEyeAngle0 = es.getplayerprop(self.userid, "CBasePlayer.m_angEyeAngles[0]") myEyeAngle1 = es.getplayerprop(self.userid, "CBasePlayer.m_angEyeAngles[1]") myX = math.cos(math.radians(myEyeAngle1)) myY = math.sin(math.radians(myEyeAngle1)) myZ = -1 * math.sin(math.radians(myEyeAngle0)) myViewVector = (myX, myY, myZ) return myViewVector elif param == "isdead": return es.getplayerprop(self.userid, "CBasePlayer.pl.deadflag") elif param == "noclip": movetype = es.getplayerprop(self.userid, "CBaseEntity.movetype") if (movetype == 8): return 1 else: return 0 elif param == "freeze": movetype = es.getplayerprop(self.userid, "CBaseEntity.movetype") if (movetype == 0): return 1 else: return 0 elif param == "color": color = es.getplayerprop(self.userid, "CBaseEntity.m_clrRender") retval = [] retval.append(color & 0xff) retval.append((color & 0xff00) >> 8) retval.append((color & 0xff0000) >> 16) retval.append((color & 0xff000000) >> 24) return tuple(map(int, retval)) elif param == "isducked": return es.getplayerprop(self.userid, 'CBasePlayer.localdata.m_Local.m_bDucked') % 2 def Set(self, param, value): param = str(param).lower() if param == "gravity": es.server.es_fire(self.userid, '!self', 'addoutput', '"gravity %s"'%value) self.key['gravity'] = value elif param == 'keyvalue': self.key[value[0]] = value[1] elif param == "health": es.setplayerprop(self.userid, "CBasePlayer.m_iHealth", value) elif param == "speed": es.setplayerprop(self.userid, "CBasePlayer.localdata.m_flLaggedMovementValue", value) elif param == 'burn': es.server.es_fire(self.userid, '!self', 'Ignite') gamethread.delayed(value, self.Set,('extinguish', None)) elif param == 'extinguish': napalmlist = es.createentitylist("entityflame") handle = es.getplayerhandle(self.userid) for entity in napalmlist: strg = es.getindexprop(entity,'CEntityFlame.m_hEntAttached') if strg == handle: es.setindexprop(entity,'CEntityFlame.m_flLifetime',0) break elif param == "viewplayer": myLocation = es.getplayerlocation(self.userid) hisLocation = es.getplayerlocation(value[0]) myVector = es.createvectorstring(myLocation[0], myLocation[1], myLocation[2]) hisVector = es.createvectorstring(hisLocation[0], hisLocation[1], hisLocation[2]) ourVector = es.createvectorfrompoints(myVector, hisVector) ourVector = es.splitvectorstring(ourVector) myViewAngle = self.get('viewangle') ourAtan = math.degrees(math.atan(float(ourVector[1])/float(ourVector[0]))) if float(ourVector[0]) < 0: RealAngle = ourAtan + 180 else: if float(ourVector[1]) < 0: RealAngle = ourAtan + 360 else: RealAngle = ourAtan yAngle = RealAngle xAngle = 0 - math.degrees(math.atan(ourVector[2]/math.sqrt(math.pow(float(ourVector[1]),2) + math.pow(float(ourVector[0]),2)))) es.server.es_setang(self.userid, xAngle, yAngle, myViewAngle[2]) elif param == "viewcoord": myLocation = es.getplayerlocation(self.userid) myVector = es.createvectorstring(myLocation[0], myLocation[1], myLocation[2]) theVector = es.createvectorstring(value[0], value[1], value[2]) ourVector = es.createvectorfrompoints(myVector, theVector) ourVector = es.splitvectorstring(ourVector) myViewAngle = self.get('viewangle') ourAtan = math.degrees(math.atan(float(ourVector[1])/float(ourVector[0]))) if float(ourVector[0]) < 0: RealAngle = ourAtan + 180 else: if float(ourVector[1]) < 0: RealAngle = ourAtan + 360 else: RealAngle = ourAtan yAngle = RealAngle xAngle = 0 - math.degrees(math.atan(ourVector[2]/math.sqrt(math.pow(float(ourVector[1]),2) + math.pow(float(ourVector[0]),2)))) es.server.es_setang(self.userid, xAngle, yAngle, myViewAngle[2]) elif param == "push": myVector = self.get('viewvector') horzX = float(value[0]) * float(myVector[0]) horzY = float(value[0]) * float(myVector[1]) if str(value[2]) == '0': vertZ = float(myVector[2]) * float(value[1]) else: vertZ = value[1] myNewVector = es.createvectorstring(horzX, horzY, vertZ) es.setplayerprop(self.userid,"CBasePlayer.localdata.m_vecBaseVelocity", myNewVector) elif param == "model": myModel = value.replace("/", "\\") if not myModel.startswith("models\\"): myModel = "models\\" + myModel if not myModel.endswith(".mdl"): myModel = myModel + ".mdl" es.setplayerprop(self.userid, "CBaseEntity.m_nModelIndex", es.precachemodel(myModel)) self.set('color', ['255', '255', '255', '255']) elif param == "color": value = map(int, value) color = value[0] color += value[1] << 8 color += value[2] << 16 if len(value) >= 4: color += value[3] << 24 else: color += self.get("color")[3] << 24 if color >= 2**31: color -= 2**32 oldRenderMode = es.getplayerprop(self.id, "CBaseEntity.m_nRenderMode") oldRenderFX = es.getplayerprop(self.id, "CBaseEntity.m_nRenderFX") newRenderMode = oldRenderMode | 1 newRenderFX = oldRenderFX | 256 es.setplayerprop(self.id, "CBaseEntity.m_nRenderMode", newRenderMode) es.setplayerprop(self.id, "CBaseEntity.m_nRenderFX", newRenderFX) es.setplayerprop(self.id, "CBaseEntity.m_clrRender", color) value = map(int, value) color = value[0] color += value[1] << 8 color += value[2] << 16 if len(value) >= 4: color += value [3] << 24 else: color += self.get("color")[3] << 24 if color >= 2**31: color -= 2**32 oldRenderMode = es.getplayerprop(self.id, "CBaseEntity.m_nRenderMode") oldRenderFX = es.getplayerprop(self.id, "CBaseEntity.m_nRenderFX") newRenderMode = oldRenderMode | 1 newRenderFX = oldRenderFX | 256 for entity in es.createentitylist(str(self.attributes["weapon"])): if es.getplayerhandle(self.id) == es.getindexprop(entity, 'CBaseEntity.m_hOwnerEntity'): es.setindexprop(entity, "CBaseEntity.m_nRenderMode", newRenderMode) es.setindexprop(entity, "CBaseEntity.m_nRenderFX", newRenderFX) es.setindexprop(entity, 'CBaseEntity.m_clrRender', color) break elif param == "noclip": if str(value) == '1': es.setplayerprop(self.userid, "CBaseEntity.movetype", '8') elif str(value) == '0': es.setplayerprop(self.userid, "CBaseEntity.movetype", '2') elif param == "freeze": if str(value) == '1': es.setplayerprop(self.userid, "CBaseEntity.movetype", '0') elif str(value) == '0': es.setplayerprop(self.userid, "CBaseEntity.movetype", '2') elif param == "moveto": hisLocation = list(es.getplayerlocation(value)) hisLocation[0] = float(hisLocation[0]) + 50 hisLocation[2] = float(hisLocation[2]) + 10 es.server.es_setpos(self.userid, hisLocation[0], hisLocation[1], hisLocation[2]) #End Player Class #Begin Character Class class Character(object): global Characters def __init__(self, userid=None): self.userid = int(userid) self.steamid = es.getplayersteamid(self.userid) self.character = Players[self.userid]['character'] if self.character: self.key = Characters[self.character] self.player = Player(self.userid) def Update(self): pass def Setup(self, Name, Forced=None): if not Characters.has_key(Name): if self.player.Get('isdead'): self.Create(Name) elif Forced: self.Create(Name) else: es.tell(self.userid, '#multi', '#green[Dungeons and Dragons] #defaultYou must be dead to create a new character.') elif Forced: self.Setup('%sX'%Name, 1) else: es.tell(self.userid, '#multi', '#green[Dungeons and Dragons] #defaultSorry #lightgreen%s #defaultis already a character. Please try another.'%Name) def Create(self, Name): Characters[Name] = {} Characters[Name]['creator'] = self.steamid Characters[Name]['race'] = 'Pending' Characters[Name]['classes'] = {} Characters[Name]['password'] = 'locked' Characters[Name]['xp'] = 0 Characters[Name]['level'] = 1 Player(self.userid).AddCharacter(Name) Menu(userid).RaceMenu() es.tell(self.userid, '#multi', '#green[Dungeons and Dragons] #lightgreen%s #defaultCreated.'%Name) def SetPassword(self, Password): Characters[self.character]['password'] = Password es.tell(self.userid, '#multi', '#green[Dungeons and Dragons] #defaultThis character can now be loaded by anyone this the username and password. Character: #lightgreen%s #defaultPassword: #lightgreen%s'%(self.character, Password)) #End Classes #Begin handels for our 'dnd' command that can be run in client console/chat def Command(): userid = int(es.getcmduserid()) steamid = es.getplayersteamid(userid) arg1 = es.getargv(1).lower() argcount = es.getargc() stringcount = 2 commandstring = '' while stringcount < argcount: addstring = es.getargv(stringcount) if commandstring: commandstring = '%s %s'%(commandstring, addstring) else: commandstring = addstring stringcount += 1 if arg1 == 'create': Character(userid).Setup(commandstring) elif arg1 == 'load': if Player(userid).Get('isdead'): if Characters.has_key(commandstring): if Characters[commandstring]['password'] == 'locked' and Characters[commandstring]['creator'] == steamid: Player(userid).SetCharacter(commandstring) else: Player(userid).TempCharacter(commandstring) else: es.tell(userid, '#multi', '#green[Dungeons and Dragons] #defaultSorry #lightgreen%s #defaultwas not found in our character database.'%Name) elif arg1 == 'passwordenter': Player(userid).PasswordEnter(commandstring) elif arg1 == 'passwordset': Character(userid).SetPassword(commandstring) elif arg1 == 'loadmenu': Player(userid).CharacterMenu() elif arg1 == 'menu' or arg1 == 'mainmenu': Menu(userid).MainMenu() elif arg1 == 'stats': Menu(userid).CharacterInformation() elif arg1 == 'help': Menu(userid).HelpMenu() elif arg1 == 'info': Menu(userid).InfoMenu() else: es.tell(userid, '#multi', '#green[Dungeons and Dragons] #defaultSorry #lightgreen%s #default is not a valid command.'%commandstring) #End Character Class #End our command handels