def pq_evade(user, target): """Buff self with an Evade (+Skill to Defense)""" targstring = "You feel " if hasattr(user, "gear") \ else "The monster feels " send_to_console(targstring + "more evasive!") user.temp_bonus(["Defense"], user.stats[5], 4) return (True, 0)
def deadchar(rpg): """Deal with character death""" send_to_console("What would you like to do? Options: "\ "Generate (a new character), Load, Quit") dothis = choose_from_list("Dead> ", ["Generate", "Load", "Quit"], character=rpg.character, rand=False, allowed=["sheet", "help"]) if dothis == "Quit": confirm_quit() deadchar(rpg) return if dothis == "Load": rpg = load(rpg) if not rpg: send_to_console("I'm sorry, that didn't work... maybe you deleted " \ "the save file? Anyway...") deadchar(rpg) return else: send_to_console("Game successfully loaded!") send_to_console("You begin in the town square.") rpg.character.tellchar() rpg.destination("town") town(rpg) return if dothis == "Generate": rpg = generate(rpg) send_to_console("You begin in the town square.") town(rpg) return
def changequip(self, equipment): equipment = equipment.replace('Ring of ', '') if equipment not in self.loot['items']: send_to_console(equipment, self.loot['items']) return itemtype = pq_item_type(equipment) oldequip = '' if itemtype[0] == "ring": for i in pq_magic['ring'].keys(): if equipment.lower() == i.lower(): equipment = i break if self.gear['ring']: self.skill.remove(pq_magic['ring'][self.gear['ring']]) self.loot['items'].append(self.gear['ring']) oldequip = self.gear['ring'] self.skill.append(pq_magic['ring'][equipment]) self.gear['ring'] = equipment self.loot['items'].remove(equipment) else: new_rating = pq_item_rating(itemtype, equipment) if self.gear[itemtype[0]]['name']: self.loot['items'].append(self.gear[itemtype[0]]['name']) oldequip = self.gear[itemtype[0]]['name'] self.gear[itemtype[0]]['name'] = equipment self.gear[itemtype[0]]['rating'] = new_rating self.loot['items'].remove(equipment) self.combat['atk'] = [self.gear['weapon']['rating'], self.stats[0]] self.combat['dfn'] = [self.gear['armor']['rating'], self.stats[1]] return oldequip
def monster_turn(self): """YAY THE ENEMY GOES... this handles the VERY SIMPLISTIC monster AI.""" self.enemy.skillcounter -= 1 hitpointratio = float(self.enemy.hitpoints[0]) / \ float(self.enemy.hitpoints[1]) if self.enemy.flee and self.enemy.skillpoints[0] <= 0 and \ hitpointratio < 0.1 and random.random() < float(7 + \ self.enemy.stats[4])/100.: self.runaway(self.enemy) return skillcheck1 = self.enemy.skillpoints[0] > 0 skills_ok = [] skills_ok.append(self.enemy.skill == 'Petrify' and \ self.enemy.skillcounter < -3) skills_ok.append(self.enemy.skill == 'Flee' and self.turn >= 2) skills_ok.append(self.enemy.skill == 'Poison' and self.turn >= 2 and \ self.char.hitpoints[0] < self.char.hitpoints[1]) if self.enemy.skillcounter < 0: avail_skills = list(pq_dragonskill.values( )) # hack python3 dict does not have remove anymore avail_skills.remove('Petrify') avail_skills.remove('Flee') avail_skills.remove('Poison') skills_ok.append(self.enemy.skill in avail_skills) if sum(skills_ok) and skillcheck1: send_to_console("The enemy uses " + color.UNDERLINE + self.enemy.skill + color.END + "!") self.enemy.reset_skillcounter() self.use_skill(self.enemy.skill, self.enemy, self.char) else: send_to_console("It tries to cause you bodily harm!") self.attack_enemy(self.enemy, self.char)
def win_combat(self): """Handle scenarious where (by some miniscule chance) the player wins the combat.""" self.char.defeat_enemy(self.enemy.level[1], self.enemy.treasure) exp = self.enemy.level[1] send_to_console(color.BOLD + 'You receive ' + str(exp) + ' experience.' + color.END) treasure = self.enemy.treasure msg = "In the monster's lair, you find: " loot = [] for i in treasure.keys(): if treasure[i]: if i == 'gp': loot.append(str(treasure[i]) + " gp") elif i == 'ring': loot.append("a Ring of " + treasure[i]) elif i == 'quest': loot.append(treasure[i]) self.char.queststatus = "complete" else: loot.append("a " + treasure[i]) if not loot: loot = "Nothing!" else: loot = ', '.join(loot) + '.' send_to_console(msg + color.BOLD + loot + color.END) if self.char.level[0] >= self.char.level[1] * 10: self.char.levelup() self.done = True return
def use_skill(self, skill, user, target): """Parse the different skill options.""" if skill not in user.skill: send_to_console("You don't have that skill...") return if user.skillpoints[0] == 0: send_to_console( "Not enough skill points remaining to use that skill...") return if "charmed" in user.temp['condition']: targstring = "You are " if user == self.char else "The monster is " send_to_console(targstring + "charmed, and cannot use skills!") return user.skillpoints[0] -= 1 #first check for flee if skill == 'Flee': #escape from combat targstring = "You are " if hasattr(user, "gear") \ else "The monster is " send_to_console(targstring + "running away!") self.runaway(user, 1.) self.done = True return #then everything else, using the skill library hit = pqsl[skill](user, target) if hit[0] and hit[1] > 0: self.be_hit(target, hit[1]) return elif not hit[0]: targstring = "you." if hasattr(target, "gear") else "the enemy." send_to_console("The " + skill + " failed to affect " + targstring) return
def monster_turn(self): """YAY THE ENEMY GOES... this handles the VERY SIMPLISTIC monster AI.""" self.enemy.skillcounter -= 1 hitpointratio = float(self.enemy.hitpoints[0]) / \ float(self.enemy.hitpoints[1]) if self.enemy.flee and self.enemy.skillpoints[0] <= 0 and \ hitpointratio < 0.1 and random.random() < float(7 + \ self.enemy.stats[4])/100.: self.runaway(self.enemy) return skillcheck1 = self.enemy.skillpoints[0] > 0 skills_ok = [] skills_ok.append(self.enemy.skill == 'Petrify' and \ self.enemy.skillcounter < -3) skills_ok.append(self.enemy.skill == 'Flee' and self.turn >= 2) skills_ok.append(self.enemy.skill == 'Poison' and self.turn >= 2 and \ self.char.hitpoints[0] < self.char.hitpoints[1]) if self.enemy.skillcounter < 0: avail_skills = pq_dragonskill.values() avail_skills.remove('Petrify') avail_skills.remove('Flee') avail_skills.remove('Poison') skills_ok.append(self.enemy.skill in avail_skills) if sum(skills_ok) and skillcheck1: send_to_console("The enemy uses "+self.enemy.skill+"!") self.enemy.reset_skillcounter() self.use_skill(self.enemy.skill, self.enemy, self.char) else: send_to_console("It tries to cause you bodily harm!") self.attack_enemy(self.enemy, self.char)
def win_combat(self): """Handle scenarious where (by some miniscule chance) the player wins the combat.""" self.char.defeat_enemy(self.enemy.level[1], self.enemy.treasure) exp = self.enemy.level[1] send_to_console('You receive ' + str(exp) + ' experience.') treasure = self.enemy.treasure msg = "In the monster's pockets, you find: " loot = [] for i in treasure.keys(): if treasure[i]: if i == 'gp': loot.append(str(treasure[i]) + " gp") elif i == 'ring': loot.append("a Ring of " + treasure[i]) elif i == 'quest': loot.append(treasure[i]) self.char.queststatus = "complete" else: loot.append("a " + treasure[i]) if not loot: loot = "Nothing!" else: loot = ', '.join(loot) + '.' send_to_console(msg + loot) if self.char.level[0] >= self.char.level[1] * 10: self.char.levelup() self.done = True return
def use_skill(self, skill, user, target): """Parse the different skill options.""" if skill not in user.skill: send_to_console("You don't have that skill...") return if user.skillpoints[0] == 0: send_to_console("Not enough skill points remaining to use that skill...") return if "charmed" in user.temp['condition']: targstring = "You are " if user == self.char else "The monster is " send_to_console(targstring + "charmed, and cannot use skills!") return user.skillpoints[0] -= 1 #first check for flee if skill == 'Flee': #escape from combat targstring = "You are " if hasattr(user, "gear") \ else "The monster is " send_to_console(targstring+"running away!") self.runaway(user, 1.) self.done = True return #then everything else, using the skill library hit = pqsl[skill](user, target) if hit[0] and hit[1] > 0: self.be_hit(target, hit[1]) return elif not hit[0]: targstring = "you." if hasattr(target, "gear") else "the enemy." send_to_console("The " + skill + " failed to affect " + targstring) return
def pq_regeneration(user, target): """Passive skill: regain lvl hp each round.""" regen = max([user.level[1] / 2, 1]) user.cure(regen) targstring = "You regenerate " if hasattr(user, "gear") else \ "Enemy regenerates " send_to_console(targstring + str(regen) + " hitpoints!") return
def pq_regeneration(user, target): """Passive skill: regain lvl hp each round.""" regen = max([user.level[1]/2, 1]) user.cure(regen) targstring = "You regenerate " if hasattr(user, "gear") else \ "Enemy regenerates " send_to_console(targstring + str(regen) + " hitpoints!") return
def godownstairs(self): """Head to the next lower dungeon level.""" self.whereareyou = "start" self.dungeonlevel += 1 if self.dungeonlevel > self.maxdungeonlevel: self.maxdungeonlevel = self.dungeonlevel self.addshopitem() send_to_console("You head down the stairs to level " + str(self.dungeonlevel)) return
def pq_bardicknowledge(user, target): """Passive skill: Learn information about the target""" trigger_chance = user.level[1] * 0.02 if random.random() < trigger_chance: statstring = sum([[pq_stats_short[i], str(target.stats[i])] \ for i in range(6)], []) send_to_console("You recall learning about this kind of creature!") send_to_console("Enemy stats: " + " ".join(statstring)) return
def pq_track(user, target): """Passive skill: stops opponent from fleeing for rest of combat""" trigger_chance = 0.02 * user.level[1] if random.random() < trigger_chance and not \ target.temp['condition'].get("tracked",None): target.temp['condition']["tracked"] = 999 targstring = "You have tracked the enemy!" if \ hasattr(user, "gear") else "The enemy has tracked you!" send_to_console(targstring) return
def pq_turning(user, target): """Passive skill: chance to apply Turned condition, which prevents attack""" trigger_chance = float(1 + 3 * user.level[1]) / \ float(50 + 4 * user.level[1]) if random.random() < trigger_chance: target.temp['condition']["turned"] = 2 targstring = "Enemy is " if hasattr(user, "gear") else "You are " send_to_console(targstring + "turned!") return
def pq_precog(user, target): """Passive skill: Mind vs Mind for 1-round buff to attack and defense""" buff = atk_roll([0, user.stats[4]], [0, target.stats[4]], \ user.temp['stats'].get("Mind", 0), \ target.temp['stats'].get("Mind", 0)) if buff > 0: targstring = "You predict the enemy's actions!" if \ hasattr(user, "gear") else "The enemy predicts your actions!" user.temp_bonus(["Attack", "Defense"], buff, 2) send_to_console(targstring) return
def pq_bushido(user, target): """Passive skill: chance to remove a random condition.""" trigger_chance = user.level[1] * 0.02 if random.random() < trigger_chance and user.temp['condition']: condition_remove = random.choice(user.temp['condition'].keys()) targstring = "You shrug" if hasattr(user, "gear") else \ "The enemy throws" send_to_console(targstring + " off the " + condition_remove + "condition!") del user.temp['condition'][condition_remove] return
def pq_shapechange(user, target): """Passive skill: chance to gain 1-round buff every round.""" stats = ["Attack", "Defense", "Reflexes", "Fortitude"] trigger_chance = user.level[1] * 0.02 if random.random() < trigger_chance: targstring = "You change shape!" if hasattr(user, "gear") else \ "The enemy changes shape!" send_to_console(targstring) buff = random.randint(1, user.level[1]) if user.level[1] > 1 else 1 user.temp_bonus(stats, buff, 2) return
def pq_grace(user, target): """Passive skill: chance to gain +1dLevel to Ref, Fort, Mind as a 2-round buff.""" stats = ["Reflexes", "Fortitude", "Mind"] trigger_chance = user.level[1] * 0.02 if random.random() < trigger_chance: targstring = "You glow" if hasattr(user, "gear") else \ "The enemy glows" send_to_console(targstring + " with divine impetus!") buff = random.randint(1, user.level[1]) if user.level[1] > 1 else 1 user.temp_bonus(stats, buff, 4) return
def pq_burn(user, target): """Perform a Burn (Atk vs Ref, applies Burning condition which re-calls the skill each turn for 1dSkill turns.""" hit = atk_roll(user.combat['atk'], [0, target.stats[3]], \ user.temp['stats'].get("Attack", 0), \ target.temp['stats'].get("Reflexes", 0)) if hit > 0 and "burning" not in target.temp['condition']: targstring = "The monster is " if hasattr(user, "gear") \ else "You are " send_to_console(targstring + "burning!") target.temp['condition']["burning"] = 4 return (hit > 0, hit)
def pq_missile(user, target): """Perform a Missile -- a single attack, Skill vs Reflexes""" num_missile = user.level[1] / 3 + 1 targstring = "You send " if hasattr(user, "gear") \ else "The monster sends " send_to_console(targstring + str(num_missile) + " missiles!") hit = 0 for i in range(num_missile): hit += max([0, atk_roll([0, user.stats[5]], [0, target.stats[2]], \ user.temp['stats'].get("Skill", 0), \ target.temp['stats'].get("Reflex", 0))]) return (hit > 0, hit)
def pq_acidspray(user, target): """Perform an Acidspray -- Fort vs Def, full damage + 1/2 damage as Def debuff for 2 rounds""" hit = atk_roll([0, user.stats[3]], target.combat['dfn'], \ user.temp['stats'].get("Fortitude", 0), \ target.temp['stats'].get("Defense", 0)) if hit > 0: debuff = max([hit / 2, 1]) targstring = "The monster is " if hasattr(user, "gear") \ else "You are " send_to_console(targstring + "sprayed with acid!") target.temp_bonus(["Defense"], debuff, 4) return (hit > 0, hit)
def pq_fear(user, target): """Perform a Fear (Skill vs Mind) to debuff.""" hit = atk_roll([0, user.stats[5]], [0, target.stats[4]], \ user.temp['stats'].get("Skill", 0), \ target.temp['stats'].get("Mind", 0)) if hit > 0: hit = max([1, hit / 2]) targstring = "The monster is " if hasattr(user, "gear") \ else "You are " send_to_console(targstring + "frightened!") target.temp_bonus(["Attack", " Defense"], -hit, 4) return (True, 0) return (False, 0)
def pq_leech(user, target): """Perform a Leech -- a single attack which cures for half the damage it deals, up to Skill""" hit = atk_roll(user.combat['atk'], [0, target.stats[3]], \ user.temp['stats'].get("Attack", 0), \ target.temp['stats'].get("Fortitude", 0)) if hit > 0: cure = max([hit / 2, 1]) targstring = "You drain " if hasattr(user, "gear") \ else "The monster drains " send_to_console(targstring + str(cure) + " hit points!") user.cure(cure) return (hit > 0, hit)
def pq_entangle(user, target): """Perform an Entangle (Skill vs Reflexes) to debuff.""" hit = atk_roll([0, user.stats[5]], [0, target.stats[2]], \ user.temp['stats'].get("Skill", 0), \ target.temp['stats'].get("Reflex", 0)) if hit > 0: targstring = "The monster is " if hasattr(user, "gear") \ else "You are " send_to_console(targstring + "entangled!") target.temp['condition']["entangled"] = 4 target.temp_bonus(["Attack", "Defense"], -hit, 4) return (True, 0) return (False, 0)
def be_hit(self, target, dmg): """Handle if somebody takes damage.""" target.ouch(dmg) if target == self.char: send_to_console(color.BOLD+"Ouch! You're bleeding, maybe a lot. You take " + str(dmg) \ + " damage, and have "+ str(target.hitpoints[0]) + \ " hit points remaining."+color.END) else: send_to_console(color.BOLD+"A hit! A very palpable hit! You deal " + str(dmg) + \ " damage."+color.END) if target.hitpoints[0] <= 0: self.death(target) return True return False
def generate(rpg): """Wrapper for making a new character""" send_to_console( "Time to make a new character! It'll be saved under this player name.") rpg.character.chargen(rpg.player_name) save(rpg) msg = "In the town of North Granby, the town militia has recently " \ "discovered that the plague of monsters harrassing the townspeople " \ "originates from a nearby dungeon crammed with nasties. As the " \ "resident adventurer, the Mayor of North Granby (a retired " \ "adventurer by the name of Sir Percival) has recruited you to clear " \ "out the dungeon." send_to_console(textwrap.fill(msg)) return rpg
def success(self): """Handler for successful puzzle completion.""" msg = "The " + self.thing + " seems pleased. " + color.BOLD + \ "'You have proven worthy, and now may receive your reward.'" + \ color.END + " Then it vanishes, leaving no trace that this room " \ "of the dungeon was ever occupied." send_to_console(textwrap.fill(msg)) msg = "You gain " if self.choice == "gold": msg += str(self.gold) + " gp!" send_to_console(msg, '\n') self.char.defeat_enemy(0, {'gp':self.gold}) if self.choice == "riches": typ = pq_item_type(self.riches) msg += "a " if typ[0] == "ring": msg += "Ring of " msg += self.riches + "!" send_to_console(msg, '\n') self.char.defeat_enemy(0, {typ[0]:self.riches}) if self.choice == "knowledge": msg += str(self.knowledge) + " experience!" send_to_console(msg, '\n') self.char.defeat_enemy(self.knowledge, {}) if self.char.level[0] >= 10 * self.char.level[1]: self.char.levelup() self.finished = True return
def chargen(self, player): """ Generate a new character using (possibly random) race, class, and feat choices. """ send_to_console(textwrap.fill("It's time to generate a character! At any " \ "of the prompts below, enter 'random' (no quotes) to use " \ "a random choice.")) send_to_console("Available races: " + ", ".join(sorted(pq_races.keys()))) race = choose_from_list("Race> ", pq_races.keys(), rand=True, \ character=self, allowed=['sheet', 'help']) send_to_console("Available classes: " + ", ".join(sorted(pq_classes.keys()))) clas = choose_from_list("Class> ", pq_classes.keys(), rand=True, \ character=self, allowed=['sheet', 'help']) nfeat = 2 if race.lower() == "human" else 1 send_to_console("Available feats: " + ", ".join(sorted(pq_feats.keys()))) feats = [] for i in range(nfeat): feat = choose_from_list("Feat> ", pq_feats.keys(), rand=True, \ character=self, allowed=['sheet', 'help']) feats.append(feat) self.chargenerate(race, clas, feats, player) self.tellchar()
def pq_cure(user, target): """Perform a Cure (healing 1dSkill + level), followed by a normal attack.""" #logger.debug(user.name) cure = random.randint(1, user.stats[5] + \ user.temp['stats'].get("Skill", 0)) + user.level[1] user.cure(cure) hit = atk_roll(user.combat['atk'], target.combat['dfn'], \ user.temp['stats'].get("Attack", 0), \ target.temp['stats'].get("Defense", 0)) targstring = "You are " if (len(user.name) > 1) else "The monster is " send_to_console(targstring + "cured for " + str(cure) + " hp! An attack follows.") return (hit > 0, hit)
def questhall(self): """The character enters the Questhall! It's super effective!""" if self.character.queststatus == "active": msg = "As you enter the Questhall, Mayor Percival looks at you " \ "expectantly. " + color.BOLD + "'Did you collect the item " \ "and defeat the monster? No? Well, then, get back out there!" \ " I suggest you try Dungeon level " + str(self.questlevel) + \ ".'" + color.END send_to_console(textwrap.fill(msg)) return self.questlevel += 1 self.init_quest(self.questlevel) if self.character.queststatus == "inactive": msg1 = "In the Questhall, Mayor Percival frets behind his desk. " \ + color.BOLD + "'" + self.character.name[0] + "! Just the " \ "person I was looking for. There's... something I need you " \ "to do. See, there are rumors of a horrible creature, " \ "called " + self.quest.name + ", roaming the dungeon. " + \ self.quest.description + "This monstrosity " \ "draws its power from " + self.quest.artifact[0] + ", " + \ self.quest.artifact[1].lower() + " I need you to go into " \ "the dungeon, kill that beast, and bring back the artifact " \ "so my advisors can destroy it. The townspeople will be " \ "very grateful, and you'll receive a substantial reward! " \ "Now, get out of here and let me finish my paperwork.'" \ + color.END send_to_console(textwrap.fill(msg1)) elif self.character.queststatus == "complete": send_to_console("Mayor Percival looks up excitedly. " + color.BOLD + \ "'You have it! Well, thank my lucky stars. " \ "You're a True Hero, " + self.character.name[0] + "!'" + \ color.END) exp = 5 * (self.questlevel - 1) gold = int(random.random() * 2 + 1) * exp send_to_console("You gain " + str(exp) + " experience and " + str(gold) \ + " gp!") self.character.complete_quest(exp, gold) if self.character.level[0] >= self.character.level[1] * 10: self.character.levelup() self.addshopitem() msg1 = "Percival clears his throat hesitantly. " + color.BOLD + \ "'Since I have you here, there... have been rumors of " \ "another problem in the dungeon. " msg2 = self.quest.name + " is its name. " + self.quest.description msg3 = " The source of its power is " + self.quest.artifact[0] + \ ", " + self.quest.artifact[1] + " Will you take this quest, " \ "same terms as last time (adjusting for inflation)? Yes? " \ "Wonderful! Now get out.'" + color.END send_to_console(textwrap.fill(msg1 + msg2 + msg3)) self.character.queststatus = "active"
def pq_charm(user, target): """Perform a Charm vs Mind.""" hit1 = atk_roll([0, user.stats[5]], [0, target.stats[4]], \ user.temp['stats'].get("Skill", 0), \ target.temp['stats'].get("Mind", 0)) hit2 = atk_roll([0, user.stats[5]], [0, target.stats[4]], \ user.temp['stats'].get("Skill", 0), \ target.temp['stats'].get("Mind", 0)) if hit1 > 0 and hit2 > 0: targstring = "The monster is " if hasattr(user, "gear") \ else "You are " send_to_console(targstring + "charmed!") target.temp['condition']["charmed"] = 4 return (True, 0) return (False, 0)
def pq_prismspray(user, target): """Perform a Prismatic Spray (Skill vs random stat to debuff that stat""" effectstring = ('blunted', 'diminished', 'made sluggish', \ 'weakened', 'befuddled', 'disconcerted') statpick = random.choice([random.randint(0, 5) for i in range(6)]) affect = atk_roll([0, user.stats[5]], [0, target.stats[statpick]], \ user.temp['stats'].get("Skill", 0), \ target.temp['stats'].get(pq_reverse_stats[statpick], 0)) if affect > 0: targstring = "The monster is " if hasattr(user, "gear") \ else "You are " send_to_console(targstring + effectstring[statpick] + "!") target.temp_bonus([pq_reverse_stats[statpick]], -affect, 4) return (affect > 0, 0)
def pq_telekinesis(user, target): """Perform a TK (Skill vs Ref); if successful, enemy attacks self""" affect = atk_roll([0, user.stats[5]], [0, target.stats[3]], \ user.temp['stats'].get("Skill", 0), \ target.temp['stats'].get("Reflexes", 0)) if affect > 0: hit = atk_roll(target.combat['atk'], target.combat['dfn'], \ target.temp['stats'].get("Attack", 0) + affect, \ target.temp['stats'].get("Defense", 0)) targstring = "The monster is " if hasattr(user, "gear") \ else "You are " targstring2 = "s itself!" if hasattr(user, "gear") else " yourself!" send_to_console(targstring + "manipulated, and attack" + targstring2) return (hit > 0, hit) return (affect > 0, 0)