def get(self, key): '''Returns a NonPlayerCharacter provided a key. ''' _trace = TRACE+'APINonPlayerCharacters:: get() ' logging.info(_trace) _character = db.get(key) if _character is not None and _character.class_name() == 'Monster': r = API200 r[MSG] = 'A villian returns!' r[_character.class_name()] = character.getJSONNonPlayer(_character) else: r = API404 r[MSG] = 'NonPlayerCharacter not found for key '+key+' .' return self.response.out.write(simplejson.dumps(r))
def get(self, key): """Returns a NonPlayerCharacter provided a key. """ _trace = TRACE + "APINonPlayerCharacters:: get() " logging.info(_trace) _character = db.get(key) if _character is not None and _character.class_name() == "Monster": r = API200 r[MSG] = "A villian returns!" r[_character.class_name()] = character.getJSONNonPlayer(_character) else: r = API404 r[MSG] = "NonPlayerCharacter not found for key " + key + " ." return self.response.out.write(simplejson.dumps(r))
def rollEncounter(player_party, geo_pt): '''Creates a random monster encounter. Returns a NonPlayerParty of monsters or None. The chance of encountering monsters is based on the player_party's encounter log. ''' _trace = TRACE+'rollEncounter():: ' logging.info(_trace) logging.info(_trace+' player_party = '+str(player_party)) # Determine likelyhood of encounter ... ''' {'encounter_log': {'total': 23, 'uniques': 2, 'start_time': POSIX 'last_encounter': {'time_since': POSIX, 'checks': 9}}} ''' log = player_party.log checks = log['encounter_log']['last_encounter']['checks'] player_party.log['encounter_log']['last_encounter']['checks'] = checks + 1 mod = checks*2 r = utils.roll(100, 1) logging.info(_trace+'r = '+str(r)) if r > 97: unique = True else: unique = False r = r + mod ### TEST ROLL - uncomment to test a specific roll r = 75 ### # There is an Encounter :) if r >= 75: # Update the Encounter Log ... player_party.log['encounter_log']['total'] += 1 last_encounter = {'time_since': time.time(), 'checks': 0} player_party.log['encounter_log']['last_encounter'] = last_encounter # Get number of PCs and the average level of the Party ... party_size = len(player_party.players) members = db.get(player_party.players) total = 0 for m in members: total = total + m.level avg_level = total/party_size logging.info(_trace+'avg_level = '+str(avg_level)) monster_party = models.NonPlayerParty(location = geo_pt, monsters = [], json = {'monsters': []}, level = avg_level) # Get the appropriate Monster table for the Party level ... monster_level = MONSTER_XP_LEVELS[avg_level] logging.info(_trace+'monster_level = '+str(monster_level)) # Get XP target for the encounter based on party level and size ... party_xp = monster_level[models.STAN]*party_size logging.info(_trace+'party_xp = '+str(party_xp)) # Roll Monster Encounter template if unique: r = 10 else: # Change die sides to exclude results from monster generator # Low level if avg_level < 3: r = utils.roll(8, 1) # Higher level includes Solo encounters else: r = utils.roll(9, 1) logging.info(_trace+'r = '+str(r)) ### TEST ROLL - uncomment to test a specific roll r = 1 ### entities = [] label = None ###################################################################### # Minions Minions Minions! if r == 1 or r == 2: logging.info(_trace+'Minions Minions Minions!') # Randomly adjust level to create more variety ... if avg_level > 3: r = utils.roll(5, 1) logging.info(_trace+'r = '+str(r)) level_mod = 0 if r == 1: level_mod = +2 if r == 2: level_mod = +1 if r == 3: level_mod = 0 if r == 4: level_mod = -1 if r == 5: level_mod = -2 avg_level += level_mod logging.info(_trace+'new avg_level = '+avg_level) # Get Minion XP and # of Minions for this level ... minion_xp = MONSTER_XP_LEVELS[avg_level][models.MIN] npc_party_size = party_xp/minion_xp logging.info(_trace+'npc_party_size = '+str(npc_party_size)) q = db.Query(models.NonPlayerCharacterTemplate, keys_only=True) q.filter('role = ', models.MIN) q.filter('challenge =', models.STAN) q.filter('level =', avg_level) q.filter('unique =', False) npc_keys = q.fetch(100) logging.info(_trace+'# npc_keys = '+str(len(npc_keys))) r = utils.roll(len(npc_keys), 1) logging.info(_trace+'r = '+str(r)) npc_key = npc_keys[r-1] # indexes start at 0 npc = db.get(npc_key) for i in range(npc_party_size): m = monster.createMonsterFromTemplate(npc) monster_party.monsters.append(m.key()) entities.append(m) label = str(npc_party_size) + ' ' + entities[0].name if npc_party_size > 1: label += 's' ###################################################################### # There's one for everyone. elif r == 3 or r == 4: logging.info(_trace+'There\'s one for everyone!') logging.info(_trace+'monster_level = '+str(monster_level[models.STAN])) q = db.Query(models.NonPlayerCharacter, keys_only=True) q.filter('challenge =', models.STAN) q.filter('experience =', monster_level[models.STAN]) q.filter('level =', avg_level) q.filter('unique =', False) logging.info(_trace+'query = '+str(q)) npc_keys = q.fetch(100) r = utils.roll(len(npc_keys), 1) logging.info(_trace+'r = '+str(r)) npc_key = npc_keys[r-1] npc = db.get(npc_key) monster_party_size = party_size for i in str(monster_party_size): m = models.Monster(npc = npc_key, json = character.getJSONNonPlayer(npc)) entities.append(m) ###################################################################### # Minions plus Mini-boss - oh noze! elif r == 5 or r == 6: logging.info(_trace+'Minions + Mini-boss!') boss_level = avg_level + 2 logging.info(_trace+'boss_level = '+boss_level) # Get Mini-boss q = db.Query(models.NonPlayerCharacter, keys_only=True) q.filter('challenge =', models.LEAD) q.filter('level =', boss_level) q.filter('unique =', False) npc_keys = q.fetch(100) logging.info(_trace+'# npc_keys = '+str(len(npc_keys))) r = utils.roll(len(npc_keys), 1) logging.info(_trace+'r = '+str(r)) npc_key = npc_keys[r] npc = db.get(npc_key) elite = models.Monster(npc = npc_key, json = character.getJSONNonPlayer(npc)) entities.append(elite) # Get Minions race = elite.race q = db.Query(models.NonPlayerCharacter, keys_only=True) q.filter('role =', models.MIN) q.filter('challenge =', models.STAN) q.filter('level =', avg_level) q.filter('unique =', False) q.filter('race =', race) npc_keys = q.fetch(100) logging.info(_trace+'# npc_keys = '+str(len(npc_keys))) r = utils.roll(len(npc_keys), 1) logging.info(_trace+'r = '+str(r)) npc_key = npc_keys[r] npc = db.get(npc_key) # Get Minion XP and # of Minions for this level ... minion_xp = MONSTER_XP_LEVELS[avg_level][models.MIN] npc_party_size = party_xp/minion_xp logging.info(_trace+'npc_party_size = '+str(npc_party_size)) for i in str(npc_party_size): m = models.Monster(npc = npc_key, json = character.getJSONNonPlayer(npc)) entities.append(m) ###################################################################### # Dungeon Master party. elif r == 7 or r == 8: logging.info(_trace+'You made the DM angry!') # Return a set monster party ... ###################################################################### # Solo boss - uh-oh. elif r == 9: logging.info(_trace+'Solo boss - uh-oh!') # Randomly adjust level to create more variety ... if avg_level > 1: r = utils.roll(3, 1) level_mod = 0 if r == 1: level_mod = -1 if r == 2: level_mod = 0 if r == 3: level_mod = 1 avg_level += level_mod logging.info(_trace+'new avg_level = '+avg_level) q = db.Query(models.NonPlayerCharacter, keys_only=True) q.filter('challenge =', models.SOLO) q.filter('level =', avg_level) q.filter('unique =', False) npc_keys = q.fetch(100) r = utils.roll(len(npc_keys), 1) npc_key = npc_keys[r] npc = db.get(npc_key) solo = models.Monster(npc = npc_key, json = character.getJSONNonPlayer(npc)) entities.append(solo) ###################################################################### elif r == 10: # Unique NPC. logging.info(_trace+'Unique NPC') player_party.log['encounters']['uniques'] += 1 q = db.Query(models.NonPlayerCharacter, keys_only=True) q.filter('level =', avg_level) q.filter('unique =', True) npc_keys = q.fetch(100) logging.info(_trace+'# npc_keys = '+str(len(npc_keys))) r = utils.roll(len(npc_keys), 1) logging.info(_trace+'r = '+str(r)) npc_key = npc_keys[r] npc = db.get(npc_key) solo = models.Monster(npc = npc_key, json = character.getJSONNonPlayer(npc)) entities.append(solo) # More than 1 Player? Throw in some Minions and make it a Party! if party_size > 1: q = db.Query(models.NonPlayerCharacter, keys_only=True) q.filter('role =', models.MIN) q.filter('challenge =', models.STAN) q.filter('level =', avg_level) q.filter('unique =', False) npc_keys = q.fetch(100) r = utils.roll(len(npc_keys), 1) npc_key = npc_keys[r] npc = db.get(npc_key) minion_party_size = party_size*4 for i in minion_party_size: m = models.Monster(npc = npc_key, json = character.getJSONNonPlayer(npc)) entities.append(m) else: return None db.put(entities) # IDs assigned # Need a new loop to get monster JSON after IDs are created ... for e in entities: monster_json = monster.getJSONMonsterLite(e) monster_party.json['monsters'].append(monster_json) parties = [player_party, monster_party] db.put(parties) # Create pin monster_loc = spawnLocation(player_party.location) _pin = pin.createMonsterPartyPin(monster_loc, monster_party, entities) monster_party.json['pin_key'] = str(_pin.key()) monster_party.json['location'] = str(monster_loc) monster_party.json['label'] = label return monster_party