def throw_item(level): direction = get_dir_action(level) if direction is None: return target = find_target(direction, 10, level) message("Throw what?") i = get_id_action(level) if i is None: return itm = get_from_inventory(i, level.player.inventory) if itm is None or not hasattr(itm, 'item'): message("No such item") return if itm.item in [level.player.wearing, level.player.wielding]: message("Rogue is using {}, can't throw it".format(itm.name)) return if type(itm.item) == MagicWand: itm.count = 1 # So decr function will do rest of disposing of it itm = decr(itm, i, level.player.inventory) if type(target) == Location: itm.location = target level.items.append(itm) itm.picked_up = False message("Rogue threw {}".format(itm.name)) elif type(target) == Monster: if does_attack_hit(level.player, target, level.number, itm): make_attack(level.player, target, thrown_damage_done_by(itm, level.player)) else: itm.location = target.location itm.found = False level.items.append(itm) message("Rogue attacks {} and misses".format(target.name))
def pickup(player, item): if same_location(player.location, item.location): if is_amulet(item): player.has_amulet_of_yendor = True message("Rogue picked up The Amulet Of Yendor") return if is_scare_monster(item): if item.used_up: message("The scroll crumbles away to nothing") return else: item.used_up = True # See if existing location existing = [l for l, i in player.inventory.items() if i is not None and i.item.name == item.name] for e in existing: if not player.inventory[e].full: more_items(item, player.inventory, e) item.picked_up = True message("Rogue picked up {} ({})".format(item.name, e)) return # Or add to new slot spaces = [l for l, i in player.inventory.items() if i is None] overburdened = sum([i.weight for i in player.inventory.values() if i is not None]) >= player.inventory_limit if len(spaces) > 0 and not overburdened: player.inventory[spaces[0]] = make_inventory_item(item) item.picked_up = True item.found = False if is_amulet(item): player.has_amulet_of_yendor = True message("Rogue picked up {} ({})".format(item.name, spaces[0])) else: message("Inventory is full, moved onto {}".format(item.name))
def heal(level): """Heal Player""" level.player.hp += randint(1, 1 + level.player.xp_level) if level.player.hp >= level.player.max_hp: level.player.max_hp += 1 level.player.hp = level.player.max_hp level.player.state = "ACTIVE" message("Rogue feels better")
def takeoff_armour(level): if level.player.wearing is not None: dfnc = level.player.wearing.defence message("Rogue removes {} [{}]".format(level.player.wearing.name, 11-dfnc)) level.player.wearing = None else: message("Rogue is already not wearing armour")
def is_confused(obj): confused = False if obj.state == "CONFUSED": obj.state = "ACTIVE" message("{} is no longer confused".format(obj.name.capitalize())) elif obj.state.startswith("CONFUSED"): obj.state = obj.state[:-1] confused = True return confused
def xp_up(level): """Level up player""" p = level.player p.xp = p.xp_to_level_up + 1 p.xp_level += 1 hp_up = randint(3, 15) p.hp += hp_up p.max_hp += hp_up message("Rogue gained experience")
def hold_monster(level): """Freezes nearby monsters""" message("Nearby monsters freeze") close_by = [ m for m in level.monsters if distance_to(level.player.location, m.location) < 6 ] for m in close_by: m.flags.append("S")
def armour_drain(monster, player): if (randint(1, 2) == 1 and player.wearing is not None and not player.wearing.protected and "eather" not in player.wearing.name): player.wearing.defence += 1 message("{} rusts your armour".format(monster.name)) else: message("A strange liquid evapourates off your armour".format(monster.name))
def make_attack(x, y, dmg): msg = "{} attacks {}".format(x.name, y.name) y.hp -= dmg if y.hp <= 0: y.state = "DEAD" msg += " and defeats it." update_xp(x, y) else: msg += " and hits." message(msg)
def update_xp(x, y): if type(x) == Player: x.xp += y.xp # Level Up if x.xp >= x.xp_to_level_up: x.xp_level += 1 hp_up = dice_roll("3d5") x.hp += hp_up x.max_hp += hp_up message("Welcome to level {}".format(x.xp_level))
def extra_healing(level): """Extra healing for Player""" hp = level.player.hp max_hp = level.player.max_hp level.player.hp += sum( [randint(1, 8) for _ in range(level.player.xp_level)]) if hp >= max_hp: level.player.max_hp += randint(1, 2) level.player.hp = level.player.max_hp level.player.state = "ACTIVE" message("Rogue feels *much* better")
def player_sleeping(level): player = level.player sleeping = False if player.state == "SLEEP": player.state = "ACTIVE" message("Rogue awakens") elif player.state.startswith("SLEEP"): message("Rogue sleeps") player.state = player.state[:-1] sleeping = True return sleeping
def getting_hungry(player): player.hunger += 1 if player.hunger == HUNGRY: message("Rogue is hungry") if player.hunger == HUNGRY_WEAK: message("Rogue is weak") if player.hunger in HUNGRY_FEINT: hungry_popup("Rogue is faint") return False # Can't move if player.hunger > HUNGRY_DIE: player.state = "DEAD" return True # Move
def create_monster(level): monster = make_monster(choice(monsters_for(level))) monster.state = "TARGETING" monster.location = level.player.location for _ in range(5): if monster.location == level.player.location: x, y = movements[choice(list(movements))] _move(monster, x, y, level) else: level.monsters.append(monster) message("A {} appeared".format(monster.name)) return message("You hear a feint cry in the distance")
def read_scroll(level): message("Read what?") i = get_id_action(level) if i is None: return itm = get_from_inventory(i, level.player.inventory) if itm is None: return if type(itm.item) == Scroll: itm = decr(itm, i, level.player.inventory) itm.name.name = itm.name.realname return itm.function(level) else: message("Can't read {}".format(itm.item.name))
def get_dir_action(level): message("direction?") update_screen(level) key = tcod.console_wait_for_keypress(flush=False) while not is_direction_key(key): if key.vk == 1: # ESC return None key = tcod.console_wait_for_keypress(flush=False) if key.vk in arrows: return arrows[key.vk] elif key.vk == 66 and key.text in "hjklyubn": return vim[key.text] else: return None
def quaff_potion(level): message("Quaff what?") i = get_id_action(level) if i is None: return itm = get_from_inventory(i, level.player.inventory) if itm is None: return if type(itm.item) == Potion: itm = decr(itm, i, level.player.inventory) itm.name.name = itm.name.realname return itm.function(level) else: message("Can't quaff {}".format(itm.item.name))
def get_id_action(level): message("--- (* to view inventory)") update_screen(level) key = tcod.console_wait_for_keypress(flush=True) while key.vk not in [66, 1]: key = tcod.console_wait_for_keypress(flush=False) if key.text == "*": inventory_menu(level) return get_id_action(level) if key.text in level.player.inventory: return key.text else: message("Unknown item") return None
def enchant_weapon(level): name = level.player.wielding.name message("Rogue's {} glows blue for a second".format(name)) """ atck = level.player.wielding.attack dice, sides = map(int, atck.split('d')) total = dice * sides dice += 1 sides = ceil(total/dice) level.player.wielding.attach = "{}d{}".format(dice, sides) """ if randint(0, 1) == 0: level.player.wielding.attack_mod += 1 else: level.player.wielding.dexterity_mod += 1
def attack(x, y, level): if type(x) == type(y): return if does_attack_hit(x, y, level.number): dmg = damage_done_by(x) if type(x) == Monster: if "A" in x.flags: armour_drain(x, y) if "V" in x.flags: hp_drain(x, dmg) if "X" in x.flags: xp_drain(x, y) if "Z" in x.flags: str_drain(x, y) if type(y) == Monster: if "H" in y.flags: y.flags = y.flags.replace("H", "") make_attack(x, y, dmg) else: message("{} attacks {} and misses".format(x.name, y.name))
def does_attack_hit(x, y, lvl_num, weapon=None): mod = 0 if type(x) == Player: if weapon is None: weapon = x.wielding mod = weapon.dexterity_mod if hasattr(weapon, "dexterity_mod") else 0 if x.state == "CONFUSE_NEXT_MONSTER": y.state = "CONFUSED1234567890" x.state = "ACTIVE" message("{} looks confused".format(y.name.capitalize())) elif not y.state.startswith("CONFUSED"): y.state = "TARGETING" mod += strength_mod(x, y) level = x.xp_level if "F" in y.flags: mod -= 3 else: level = lvl_num mod = 0 if "F" in x.flags: mod -= 3 return randint(1, 20) + mod >= 20 - level - y.armour
def eat(level): message("Eat what?") i = get_id_action(level) if i is None: return itm = get_from_inventory(i, level.player.inventory) if itm is None: message("No such food") if not type(itm.item) in [Food, Fruit]: message("Can't eat {}".format(itm.item.name)) else: itm = decr(itm, i, level.player.inventory) message("Rogue eats the {}, it tastes {}".format(itm.name, itm.taste)) itm.function(level)
def zap_wand(level): direction = get_dir_action(level) if direction is None: return target = find_target(direction, 8, level) message("Zap with what?") i = get_id_action(level) if i is None: return itm = get_from_inventory(i, level.player.inventory) if itm is None or not hasattr(itm, 'item') or itm.item is None: message("No such wand") if not type(itm.item) == MagicWand: message("Can't zap with {}".format(itm.item.name)) return if type(target) == Monster: itm = decr(itm, i, level.player.inventory) message("Rogue zaps {}".format(target.name)) if target.state in ["SLEEPING", "SNOOZING"]: target.state = "ACTIVE" itm.function(level, target) else: message("Rogue has no target")
def wear_armour(level): if level.player.wearing is not None: message("Rogue is already wearing armour") else: message("Wear what?") i = get_id_action(level) if i is None: return itm = get_from_inventory(i, level.player.inventory) if itm is None: return itm = itm.item if type(itm) == Armour: level.player.wearing = itm message("Rogue puts on {} [{}]".format(itm.name, 11-itm.defence)) else: message("Can't wear {} as armour".format(itm.name))
def wield_weapon(level): message("Wield what?") i = get_id_action(level) if i is None: return itm = get_from_inventory(i, level.player.inventory) if itm is None: return itm = itm.item if type(itm) in [Weapon, Projectile]: level.player.wielding = itm message("Rogue wields {}".format(itm.name)) else: message("Can't wield {} as weapon".format(itm.name))
def identify(level): message("What would you like to identify?") key = get_id_action(level) while key is None: key = get_id_action(level) itm = get_from_inventory(key, level.player.inventory) if itm is None: message("No such item, try again.") return identify(level) itm = itm.item if hasattr(itm.name, "realname"): itm.name.name = itm.name.realname elif hasattr(itm, "realname"): itm.name = itm.realname message("You identified {}".format(itm.name))
def drop_item(level): message("Drop what?") i = get_id_action(level) if i is None: return itm = get_from_inventory(i, level.player.inventory) if itm is None: return if itm.item in [level.player.wearing, level.player.wielding]: message("Rogue is using {}, can't drop it".format(itm.item.name)) else: if type(itm) == MagicWand: itm.count = 1 # Let decr drop the whole wand itm = decr(itm, i, level.player.inventory) itm.picked_up = False itm.location = level.player.location level.items.append(itm) message("Dropped {}".format(itm.name))
def play_game(): player = make_player() level_number = 1 level = setup_level("NORMAL", level_number, player) message("Welcome to Rogue: Through The Veil") message( "Find the Amulet of Yendor and return it, but beware, the magic realm is never far away.\n" ) message("--- (? to view controls)") update_screen(level) while not tcod.console_is_window_closed(): game_state = play_level(level) if game_state == "EXIT": break elif game_state == "NEXT_LEVEL": if level.player.has_amulet_of_yendor: level_number = level.number - 1 if level_number == 0: game_state = "WON" break else: level_number += 1 level = setup_level("NORMAL", level_number, player) update_screen(level) game_state = "PLAYING" elif game_state == "TOGGLE_WORLDS": world = "MAGIC" if level.world == "NORMAL" else "NORMAL" if level.world == "MAGIC": level_number += 1 level = setup_level(world, level_number, player) update_screen(level) game_state = "PLAYING" elif game_state == "PLAYER_DEAD": break if game_state == "EXIT": print("Thanks for playing! Come back soon, we have cake.") elif game_state == "WON": win_screen() print("Congratulations, I suppose.") elif game_state == "PLAYER_DEAD": died_screen(level) print("Oops, you died. Better luck next time.")
def str_drain(monster, player): if randint(1, 3) == 3: message("Fighting {} drains your strength".format(monster.name)) player.strength -= randint(1, 2) if player.strength < 0: player.strength = 0
def teleport(level): """Teleport player""" place_in_room(level, level.player) message("You have been transported")