void ExploreDungeon(Hero h, bool exit, IUnitController controller) { ExploreEvent e = (ExploreEvent)(Utils.Rand() % (int)ExploreEvent.Max); if (e == ExploreEvent.Stairs) { if (h.dungeon_level != h.lowest_level || h.know_down_stairs) { e = (ExploreEvent)(Utils.Rand() % ((int)ExploreEvent.Max - 1)); } } if (!exit) { controller.Notify($"{h.Name} explores dungeon."); } if (e == ExploreEvent.Nothing) { h.AddExp(h.dungeon_level / h.level, controller); } else if (e == ExploreEvent.Trap) { int attack = Utils.Random(1, 10) - h.dex; if (attack >= 3) { int dmg = Utils.Random(2, 8) - h.armor; if (dmg < 1) { dmg = 1; } h.hp -= dmg; if (h.immortal && h.hp < 0) { h.hp = 1; } if (h.hp <= 0) { to_remove.Add(h); if (watched == h && controlled) { controller.Notify($"You take {dmg} damage from trap."); pc.Die(); } else { controller.Notify($"{h.Name} takes {dmg} damage and is killed by a trap."); } } else { controller.Notify($"{h.Name} takes {dmg} damage from trap."); h.AddExp(5 * h.dungeon_level / h.level, controller); } } else { controller.Notify($"{h.Name} dodged trap."); h.AddExp(5 * h.dungeon_level / h.level, controller); } } else if (e == ExploreEvent.Combat) { UnitType enemy = GetCombatEnemy(h.dungeon_level); bool win = Combat(h, controller, enemy); if (watched == null) { string str; if (win) { str = "won combat"; } else { str = "got killed"; } controller.Notify($"{h.Name} was attacked by {enemy.name} and {str}."); } if (win) { int reward = enemy.gold.Random(); h.gold += reward; controller.Notify($"{h.Name} takes {reward} gold from corpse."); h.AddExp(enemy.CalculateExp(h.level), controller); if (enemy.killed == 0) { journal.Add($"{turn} - Hero {h.name} killed first {enemy.name}."); } enemy.killed++; } else { h.killer = enemy; enemy.kills++; if (watched == h) { if (controlled) { pc.Die(); } else { Utils.Ok(); } } } } else if (e == ExploreEvent.Treasure) { Treasure t = (Treasure)(Utils.Rand() % (int)Treasure.Max); string what = null; if ((t == Treasure.Item && (h.weapon == Item.max_item_level || h.weapon == h.dungeon_level) && (h.armor == Item.max_item_level || h.armor == h.dungeon_level) && (h.bow == Item.max_item_level || h.bow == h.dungeon_level)) || (t == Treasure.Potions && h.potions == Hero.max_potions && h.hp == h.hpmax)) { t = Treasure.GoldPile; } switch (t) { default: case Treasure.GoldPile: { int count = Utils.Random(5, 15) + 5 * h.dungeon_level; what = $"{count} gold pile"; h.gold += count; } break; case Treasure.Item: { ItemType itemType = (ItemType)(Utils.Rand() % 3); while (what == null) { switch (itemType) { case ItemType.Weapon: if (h.weapon == Item.max_item_level || h.weapon == h.dungeon_level) { itemType = (ItemType)((int)(itemType + 1) % 3); } else { h.weapon++; what = Item.weapon_names[h.weapon]; } break; case ItemType.Armor: if (h.armor == Item.max_item_level || h.armor == h.dungeon_level) { itemType = (ItemType)((int)(itemType + 1) % 3); } else { h.armor++; what = $"{Item.armor_names[h.armor]} armor"; } break; case ItemType.Bow: if (h.bow == Item.max_item_level || h.bow == h.dungeon_level) { itemType = (ItemType)((int)(itemType + 1) % 3); } else { h.bow++; what = Item.bow_names[h.bow]; } break; } } } break; case Treasure.Potions: h.potions += 2; if (h.potions > Hero.max_potions) { h.hp = Math.Min(h.hpmax, (Utils.Random(2, 5) + h.level / 2 + h.end) * (h.potions - Hero.max_potions)); h.potions = Hero.max_potions; } what = "potions"; break; case Treasure.GoldTreasure: { int count = Utils.Random(30, 80) + 20 * h.dungeon_level; what = $"{count} gold treasure"; h.gold += count; } break; } controller.Notify($"{h.Name} finds {what}."); h.AddExp(5 * h.dungeon_level / h.level, controller); } else if (e == ExploreEvent.Stairs) { h.know_down_stairs = true; controller.Notify($"{h.Name} finds stairs to lower level."); h.AddExp(5 * h.dungeon_level / h.level, controller); } }