def create_character(self, name, owner=""): '''Create an in-world character if one does not already exist. If one exists, return it.''' charobj = self.get_character(name) if not charobj: # No character in the db named that, # So create an object for the player and save it. charobj = Object(name=name, owner=owner, states=['player']) charobj.save() return charobj
def set_loaded(self): from sys import maxint obj = Object() obj.name = "Loading Complete." far = maxint*-1 obj.loc_x, obj.loc_y, obj.loc_z = far, far, far obj.states.extend(['hidden']) obj.save() print obj.name
def create(cls): obj = Object() obj.name = "Linnea" obj.resource = 'girl' obj.loc_x, obj.loc_y, obj.loc_z = 0, 0, 0 obj.rot_x, obj.rot_y, obj.rot_z = 0, 0, 0 obj.scale_x, obj.scale_y, obj.scale_z = 0, 0, 0 obj.vel_x, obj.vel_y, obj.vel_z = 0, 0, 0 obj.states.extend(['alive', 'whole', 'clickable']) obj.scripts = ['games.objects.chatbot'] obj.save() return obj
def head(self): lastdate = Object.get_objects(limit=1).last_modified cache_time = 10 * 365 * 24 * 60 * 60 # 10 Years. self.set_header('Last-Modified', lastdate) self.set_header('Expires', lastdate + datetime.timedelta(seconds=cache_time)) self.set_header('Cache-Control', 'max-age=' + str(cache_time))
def activate_object(self, object_id, character): # Instantiate the scripted object and call its activate thing. retval = [] for o in [Object.get(id=object_id)]: # TODO: Break this block into a method. for script in o.scripts: scriptclass = script.split('.')[-1] module = __import__(script, globals(), locals(), [scriptclass], -1) # For each entry in the script's dir() for key in dir(module): C = getattr(module, key) try: if not issubclass(C, Script): # If it isn't a subclass of Script, skip it. continue except TypeError: # If C isn't a class at all, skip it. continue # Finally activate the script. script_val = C(o).activate(character) if script_val: # Only return it if the script actually returns something. # So clients should only react to activating scripts that # return something meaningful. retval.append(script_val) return retval
def insert_objects(self): '''Insert any objects you want to be present in the zone into the database in this call. This gets called exactly once per database. If you change something here and want it to appear in the zone's database, you will need to clear the database first. Deleting the "Loading Complete" object will only cause duplicates. Do not do this. ''' # Place 100 barrels randomly: self.randobj(name="Barrel #%d", resource='barrel', states=['closed', 'whole', 'clickable'], count=100) # Place 10 chickens randomly: self.randobj(name="Chicken #%d", resource='chicken', scripts=['games.objects.chicken'], count=10) print[o.name for o in Object.get_objects()]
def set_movement(self, character, xmod, ymod, zmod, user=None): charobj = self.create_character(character, owner=user) # try: # charobj.loc # except(AttributeError): # # Character doesn't exist, create a new one. # self.set_status(500) # self.write('Character "%s" was not set to online, and didn\'t exist in the database.' % character) # return # Set the character's new position based on the x, y and z modifiers. charobj.loc_x += xmod * charobj.speed charobj.loc_y += ymod * charobj.speed charobj.loc_z += zmod * charobj.speed charobj.set_modified() # Do simple physics here. # TODO: Split this into its own method. def manhattan(x1, y1, x2, y2): return abs(x1-x2) + abs(y1-y2) for o in Object.get_objects(physical=True): if o.id == charobj.id: continue # Is the distance between that object and the character less than 3? if manhattan(o.loc_x, o.loc_y, charobj.loc_x, charobj.loc_y) < 3: # We collided against something, so return now and don't # save the location changes into the database. return False # We didn't collide, hooray! # So we'll save to the database and return it. charobj.save() return charobj
def set_movement(self, character, xmod, ymod, zmod, user=None): charobj = self.create_character(character, owner=user) # try: # charobj.loc # except(AttributeError): # # Character doesn't exist, create a new one. # self.set_status(500) # self.write('Character "%s" was not set to online, and didn\'t exist in the database.' % character) # return # Set the character's new position based on the x, y and z modifiers. charobj.loc_x += xmod * charobj.speed charobj.loc_y += ymod * charobj.speed charobj.loc_z += zmod * charobj.speed charobj.set_modified() # Do simple physics here. # TODO: Split this into its own method. def manhattan(x1, y1, x2, y2): return abs(x1 - x2) + abs(y1 - y2) for o in Object.get_objects(physical=True): if o.id == charobj.id: continue # Is the distance between that object and the character less than 3? if manhattan(o.loc_x, o.loc_y, charobj.loc_x, charobj.loc_y) < 3: # We collided against something, so return now and don't # save the location changes into the database. return False # We didn't collide, hooray! # So we'll save to the database and return it. charobj.save() return charobj
def get_character(self, character): '''Gets a character from the database by name. Returns the Character object, or False if it isn't a well-formed character object.''' try: charobj = Object.get_objects(limit=1, player=character) except Object.DoesNotExist: charobj = False return charobj
def test_get_character_non_existent_no_states(self): from elixir_models import Object MockCharacter = Mock() MockCharacter.get_objects = Mock(side_effect=Object.DoesNotExist('')) MockCharacter.DoesNotExist = Object.DoesNotExist with patch.object(zoneserver, 'Object', MockCharacter): result = self.character_controller.get_character("character") self.assertFalse(result)
def randobj(name="Object #%s", resource='object', count=1, states=None, scripts=None): objs = [] for i in xrange(count): obj = Object() obj.name = name % i obj.resource = resource obj.loc_x, obj.loc_y, obj.loc_z = randloc(), randloc(), randloc() obj.rot_x, obj.rot_y, obj.rot_z = randrot(), randrot(), randrot() obj.scale_x, obj.scale_y, obj.scale_z = randscale(), randscale(), randscale() obj.vel_x, obj.vel_y, obj.vel_z = 0, 0, 0 if states: obj.states.extend(states) if scripts: obj.scripts.extend(scripts) obj.save() objs.append(obj) return objs
def load_scripts(self): '''(Re)Load scripts for objects in this zone.''' self.scripts = {} # Query DB for a list of all objects' script names, # ordered according to proximity to players logger.info(Object.get_objects(scripted=True)) for o in Object.get_objects(scripted=True): logger.info("Scripted Object: {0}".format(o.name)) # Store list of script names in self # For each script name in the list: for script in o.scripts: logger.info("Importing %s" % script) if script not in self.scripts: self.scripts[script] = [] # Import those by name via __import__ scriptclass = script.split('.')[-1] module = __import__(script, globals(), locals(), [scriptclass], -1) # For each entry in the script's dir() for key in dir(module): C = getattr(module, key) # No sense in instantiating the default Script instance. if C == Script: continue try: # Does this object have the attributes that scripts need? if not all((C.tick, C.activate, C.create)): continue except AttributeError: continue # Store object instance in a list. self.scripts[script].append(C(mongo_engine_object=o)) return self.scripts
def randobj(name="Object #%s", resource='object', count=1, states=None, scripts=None): objs = [] for i in xrange(count): obj = Object() obj.name = name % i obj.resource = resource obj.loc_x, obj.loc_y, obj.loc_z = randloc(), randloc(), randloc() obj.rot_x, obj.rot_y, obj.rot_z = randrot(), randrot(), randrot() obj.scale_x, obj.scale_y, obj.scale_z = randscale(), randscale( ), randscale() obj.vel_x, obj.vel_y, obj.vel_z = 0, 0, 0 if states: obj.states.extend(states) if scripts: obj.scripts.extend(scripts) obj.save() objs.append(obj) return objs
def test_is_owner_no_char(self): username = "******" character = "character" MockObject = Mock(name="NoChar") from elixir_models import Object MockObject.DoesNotExist = Object.DoesNotExist MockObject.get_objects = Mock(side_effect=Object.DoesNotExist('')) with patch.object(zoneserver, 'Object', MockObject): result = self.character_controller.is_owner(username, character) self.assertEqual(result, None)
def __init__(self, zoneid): super(ZoneScriptRunner, self).__init__() # While the zone is not loaded, wait. logger.info("Waiting for zone to complete loading.") while not Object.get_objects(name="Loading Complete."): time.sleep(.1) # Watch the script path for any changes, and reboot the scriptserver if they do. self.observer = Observer() self.observer.schedule(ScriptEventHandler(), path=settings.SCRIPT_PATH, recursive=True) self.observer.start() self.load_scripts() logger.info("Started with data for zone: %s" % zoneid)
def set_loaded(self): from sys import maxint obj = Object() obj.name = "Loading Complete." far = maxint * -1 obj.loc_x, obj.loc_y, obj.loc_z = far, far, far obj.states.extend(['hidden']) obj.save() print obj.name
def move(self, xmod, ymod, zmod): self.me_obj.loc_x += xmod self.me_obj.loc_y += ymod self.me_obj.loc_z += zmod self.me_obj.set_modified() from helpers import manhattan ourx, oury = self.me_obj.loc_x, self.me_obj.loc_y for o in Object.get_objects(physical=True): # Is the distance between that object and the character less than 3? if manhattan(o.loc_x, o.loc_y, ourx, oury) < 1: # We collided against something, so return now and don't # save the location changes into the database. return False else: # We didn't collide with any objects. self.me_obj.save() return True
def get_objects(self, since=None): '''Gets a list of things from the database. Should not be called without an argument except when a client connects to the zone initially.''' return Object.get_objects(since=since)
def insert_objects(self): '''Insert any objects you want to be present in the zone into the database in this call. This gets called exactly once per database. If you change something here and want it to appear in the zone's database, you will need to clear the database first. Deleting the "Loading Complete" object will only cause duplicates. Do not do this. ''' self.logger.info("Placing chickens...") # Place 10 chickens randomly: for i in xrange(10): obj = Object() obj.name = "Chicken #%d" % i obj.resource = 'chicken' obj.loc_x, obj.loc_y, obj.loc_z = randloc(), randloc(), randloc() obj.rot_x, obj.rot_y, obj.rot_z = randrot(), randrot(), randrot() obj.scale_x, obj.scale_y, obj.scale_z = randscale(), randscale(), randscale() obj.vel_x, obj.vel_y, obj.vel_z = 0, 0, 0 obj.states.extend(['alive', 'whole', 'clickable']) obj.scripts = ['games.objects.chicken'] obj.save() self.logger.info(str([o.name for o in Object.get_objects()]))
def insert_objects(self): '''Insert any objects you want to be present in the zone into the database in this call. This gets called exactly once per database. If you change something here and want it to appear in the zone's database, you will need to clear the database first. Deleting the "Loading Complete" object will only cause duplicates. Do not do this. ''' self.logger.info("Placing chickens...") # Place 10 chickens randomly: for i in xrange(10): obj = Object() obj.name = "Chicken #%d" % i obj.resource = 'chicken' obj.loc_x, obj.loc_y, obj.loc_z = randloc(), randloc(), randloc() obj.rot_x, obj.rot_y, obj.rot_z = randrot(), randrot(), randrot() obj.scale_x, obj.scale_y, obj.scale_z = randscale(), randscale( ), randscale() obj.vel_x, obj.vel_y, obj.vel_z = 0, 0, 0 obj.states.extend(['alive', 'whole', 'clickable']) obj.scripts = ['games.objects.chicken'] obj.save() self.logger.info(str([o.name for o in Object.get_objects()]))
def head(self): lastdate = Object.get_objects(limit=1).last_modified cache_time = 10*365*24*60*60 # 10 Years. self.set_header('Last-Modified', lastdate) self.set_header('Expires', lastdate + datetime.timedelta(seconds=cache_time)) self.set_header('Cache-Control', 'max-age=' + str(cache_time))
def is_loaded(self): if Object.get_objects(name='Loading Complete.'): return True else: return False