def handleGetMapRequest(inputs): """ Gets the map state of the game from the given player's interest model. @returns A built Response with the following sets of data: map_tiles: a list of serialized MapTiles. units: a list of serialized Units. resource_templates: a list of ResourceTemplates. equipment: a list of Equipment, only including equiped items. NOTE: Eventually this will include a more detailed interest model, to allow for fog of war, but for now we return the entire world, and only use the interest model (player_id) to determine if a tile is a player home or enemy home. """ # Make sure the player is already in the game. player_key = ndb.Key(urlsafe=inputs['player_id']) player = player_key.get() if not player.home_tile: # If the player does not have a home tile, then they aren't in the game, and # they need to join the game. logging.error('Player: ' + player_key.urlsafe() + " is not in the game!") error_message = 'Player is not in the game.' return ResponseBuilder().setErrorMessage(error_message).build() # Get the tiles map_query = MapTile.query() if map_query.count() > 0: map_tiles = map_query.fetch() ## The map_object will be built up and built into the response. ## Its keys will be a the urlsafe key of the serialized maptile value. map_object = {'mapTiles': []} for tile in map_tiles: # Serialize the map tile into what the client needs. serialized_tile = {} serialized_tile['key'] = tile.key.urlsafe() serialized_tile['coordinate_x'] = tile.coordinate_x serialized_tile['coordinate_y'] = tile.coordinate_y serialized_tile['resources'] = [] for resource_key in tile.resources: tile_resource = resource_key.get() resource = {} resource['saturation'] = tile_resource.saturation resource[ 'template_key'] = tile_resource.resource_template.urlsafe( ) serialized_tile['resources'].append(resource) serialized_tile['unit_keys'] = [] unit_keys = tile.units.fetch(keys_only=True) for unit_key in unit_keys: serialized_tile['unit_keys'].append(unit_key.urlsafe()) serialized_tile['structure_keys'] = [] structure_keys = tile.structures.fetch(keys_only=True) for structure_key in structure_keys: serialized_tile['structure_keys'].append( structure_key.urlsafe()) # Tell the client if this map tile is a home tile. serialized_tile['is_player_home'] = False serialized_tile['is_enemy_home'] = False if tile.is_home_tile: if tile.key == player.home_tile: serialized_tile['is_player_home'] = True else: # For now, anyone that isn't the player is an enemy. serialized_tile['is_enemy_home'] = True map_object['mapTiles'].append(serialized_tile) # TODO: There is a lot of repetition here, find a way to DRY this up. # Get the units. unit_query = Unit.query() if unit_query.count() > 0: map_object['units'] = [] units = unit_query.fetch() for unit in units: # Serialize the unit into what the client needs. serialized_unit = {} serialized_unit['key'] = unit.key.urlsafe() serialized_unit['unit_type'] = unit.unit_type serialized_unit['owner_key'] = unit.owner_key.urlsafe() serialized_unit['health'] = unit.health if unit.weapon: serialized_unit['weapon_key'] = unit.weapon.urlsafe() if unit.armor: serialized_unit['armor_key'] = unit.armor.urlsafe() location_tile = unit.location_tile.get() serialized_unit['coordinate_x'] = location_tile.coordinate_x serialized_unit['coordinate_y'] = location_tile.coordinate_y serialized_unit['has_order'] = unit.has_order if unit.has_order: serialized_unit[ 'current_order_key'] = unit.current_order.urlsafe() map_object['units'].append(serialized_unit) # Get the resource_templates. rt_query = ResourceTemplate.query() if rt_query.count() > 0: map_object['resource_templates'] = [] resource_templates = rt_query.fetch() for template in resource_templates: # Serialize the resource_template into what the client needs. serialized_rt = {} serialized_rt['key'] = template.key.urlsafe() serialized_rt['name'] = template.name serialized_rt['type'] = template.resource_type if template.resource_type == RESOURCE_TYPES_INT_MAPPING[METAL_KEY]: serialized_rt[ 'metal_properties'] = template.metal_properties.to_dict() if template.resource_type == RESOURCE_TYPES_INT_MAPPING[WOOD_KEY]: serialized_rt[ 'wood_properties'] = template.wood_properties.to_dict() if template.resource_type == RESOURCE_TYPES_INT_MAPPING[ LEATHER_KEY]: serialized_rt[ 'leather_properties'] = template.leather_properties.to_dict( ) map_object['resource_templates'].append(serialized_rt) # Get the equipment. eq_query = Equipment.query() if eq_query.count() > 0: map_object['equipment'] = [] equipment_list = eq_query.fetch() for equipment in equipment_list: # Serialize the equipment into what the client needs. serialized_eq = {} serialized_eq['key'] = equipment.key.urlsafe() serialized_eq['owner_key'] = equipment.player.urlsafe() serialized_eq['type'] = equipment.type if equipment.type == EQUIPMENT_TYPE_INT_MAPPING[ARMOR_KEY]: serialized_eq['armor_data'] = equipment.armor_data.to_dict() if equipment.type == EQUIPMENT_TYPE_INT_MAPPING[WEAPON_KEY]: serialized_eq['weapon_data'] = equipment.weapon_data.to_dict() map_object['equipment'].append() # Get the structures struct_query = PlayerStructure.query() if struct_query.count() > 0: map_object['structures'] = [] structures = struct_query.fetch() for structure in structures: # Serialize the structure into what the client needs. serialized_struct = {} serialized_struct['key'] = structure.key.urlsafe() serialized_struct['owner_key'] = structure.owner_key.urlsafe() serialized_struct['type'] = structure.structure_type serialized_struct['health'] = structure.health location_tile = structure.location.get() serialized_struct['coordinate_x'] = location_tile.coordinate_x serialized_struct['coordinate_y'] = location_tile.coordinate_y if (structure.structure_type == STRUCTURE_TYPE_INT_MAPPING[HARVESTING_CAMP_KEY]): # We need to further serialize the camp data. camp_data = { 'tile_resource_key': structure.harvesting_camp_data.tile_resource_key } map_object['structures'].append(serialized_struct) # The map_object is built, set it on the response data as a json string. if len(map_object['mapTiles']) > 0: return ResponseBuilder().setData(json.dumps(map_object)).build() # No tiles exist, the game has not started. else: return ResponseBuilder().setErrorMessage("No game has started.")