Oh wow, I thought I already pushed some of this stuff. Let's see if I can remember it all. Undead residents added. Whights added, Vampyrs added. Bandit Hideout adventure added.

This commit is contained in:
Storm Dragon
2026-02-04 00:52:16 -05:00
parent e1928a1039
commit 78a6156656
18 changed files with 1029 additions and 27 deletions

View File

@@ -3,6 +3,7 @@
#include "src/bosses/adventure_combat.nvgt"
#include "src/bosses/unicorn/unicorn_boss.nvgt"
#include "src/bosses/bandit_hideout.nvgt"
void check_adventure_menu(int player_x) {
if (key_pressed(KEY_TAB)) {
@@ -26,13 +27,18 @@ void run_adventure_menu(int player_x) {
// Check available adventures based on terrain
string[] options;
int[] adventure_ids; // 1 = Unicorn
int[] adventure_ids; // 1 = Unicorn, 2 = Bandit's Hideout
if (mountain !is null) {
// Mountain terrain
options.insert_last("Unicorn Hunt (Mountain Boss)");
adventure_ids.insert_last(1);
}
if (mountain is null && (terrain == "forest" || terrain == "deep_forest")) {
options.insert_last("Bandit's Hideout");
adventure_ids.insert_last(ADVENTURE_BANDIT_HIDEOUT);
}
if (options.length() == 0) {
speak_with_history("No adventures found in this area.", true);
@@ -78,5 +84,7 @@ void start_adventure(int adventure_id) {
last_adventure_day = current_day;
if (adventure_id == 1) {
run_unicorn_adventure();
} else if (adventure_id == ADVENTURE_BANDIT_HIDEOUT) {
run_bandit_hideout_adventure();
}
}

View File

@@ -0,0 +1,669 @@
// Bandit's Hideout Adventure logic
// Terrain: Forest / Deep Forest
// Objective: Break the barricade at the enemy base.
const int ADVENTURE_BANDIT_HIDEOUT = 2;
const int BANDIT_HIDEOUT_MAP_SIZE = 100;
const int BANDIT_HIDEOUT_SEGMENT_MIN = 5;
const int BANDIT_HIDEOUT_SEGMENT_MAX = 10;
const int BANDIT_HIDEOUT_BANDIT_COUNT = 5;
const int BANDIT_HIDEOUT_BASE_SPAWN_RANGE = 10;
const int BANDIT_HIDEOUT_START_SPAWN_RANGE = 10;
const int BANDIT_HIDEOUT_BARRICADE_HP_PER_DAY = 34;
const int BANDIT_HIDEOUT_BARRICADE_HP_MAX = 500;
const double BANDIT_HIDEOUT_FAVOR_PER_KILL = 0.2;
const double BANDIT_HIDEOUT_BASE_FAVOR = 3.0;
const double BANDIT_HIDEOUT_FAVOR_MAX = 10.0;
class HideoutBandit {
int position;
int health;
string alertSound;
string weaponType; // "spear" or "axe"
int soundHandle;
bool inWeaponRange;
timer moveTimer;
timer attackTimer;
int moveInterval;
HideoutBandit(int pos, const string&in alert, const string&in weapon, int interval) {
position = pos;
health = BANDIT_HEALTH;
alertSound = alert;
weaponType = weapon;
moveInterval = interval;
soundHandle = -1;
inWeaponRange = false;
moveTimer.restart();
attackTimer.restart();
}
}
HideoutBandit@[] hideoutBandits;
string[] hideoutTerrain;
int hideoutPlayerX = 0;
int hideoutPlayerFacing = 1; // 0 = west, 1 = east
int hideoutBaseX = BANDIT_HIDEOUT_MAP_SIZE - 1;
int hideoutBarricadeHealth = 0;
int hideoutBarricadeMax = 0;
int hideoutBanditsKilled = 0;
timer hideoutWalkTimer;
timer hideoutAttackTimer;
timer hideoutSearchTimer;
timer hideoutSearchDelayTimer;
bool hideoutSearching = false;
string pick_hideout_terrain() {
int roll = random(0, 2);
if (roll == 0) return "grass";
if (roll == 1) return "gravel";
return "stone";
}
void build_hideout_terrain() {
hideoutTerrain.resize(BANDIT_HIDEOUT_MAP_SIZE);
int index = 0;
while (index < BANDIT_HIDEOUT_MAP_SIZE) {
int segmentLength = random(BANDIT_HIDEOUT_SEGMENT_MIN, BANDIT_HIDEOUT_SEGMENT_MAX);
string terrain = pick_hideout_terrain();
for (int i = 0; i < segmentLength && index < BANDIT_HIDEOUT_MAP_SIZE; i++) {
hideoutTerrain[index] = terrain;
index++;
}
}
if (hideoutBaseX >= 0 && hideoutBaseX < int(hideoutTerrain.length())) {
hideoutTerrain[hideoutBaseX] = "stone";
}
}
string get_hideout_terrain_at(int pos) {
if (pos < 0 || pos >= int(hideoutTerrain.length())) return "grass";
string terrain = hideoutTerrain[pos];
if (terrain == "") return "grass";
return terrain;
}
string get_hideout_footstep_sound(int pos) {
string terrain = get_hideout_terrain_at(pos);
if (terrain == "stone") return "sounds/terrain/stone.ogg";
if (terrain == "gravel") return "sounds/terrain/gravel.ogg";
return "sounds/terrain/grass.ogg";
}
void play_hideout_player_footstep() {
string soundFile = get_hideout_footstep_sound(hideoutPlayerX);
if (file_exists(soundFile)) {
p.play_stationary(soundFile, false);
}
}
void play_hideout_positional_footstep(int listenerX, int stepX, int maxDistance, float volumeStep) {
if (abs(stepX - listenerX) > maxDistance) return;
string soundFile = get_hideout_footstep_sound(stepX);
if (file_exists(soundFile)) {
play_1d_with_volume_step(soundFile, listenerX, stepX, false, volumeStep);
}
}
void clear_hideout_bandits() {
for (uint i = 0; i < hideoutBandits.length(); i++) {
if (hideoutBandits[i].soundHandle != -1) {
p.destroy_sound(hideoutBandits[i].soundHandle);
hideoutBandits[i].soundHandle = -1;
}
hideoutBandits[i].inWeaponRange = false;
}
hideoutBandits.resize(0);
}
HideoutBandit@ get_hideout_bandit_at(int pos) {
for (uint i = 0; i < hideoutBandits.length(); i++) {
if (hideoutBandits[i].position == pos) {
return @hideoutBandits[i];
}
}
return null;
}
int clamp_hideout_spawn_start(int startX) {
if (startX < 0) return 0;
if (startX >= BANDIT_HIDEOUT_MAP_SIZE) return BANDIT_HIDEOUT_MAP_SIZE - 1;
return startX;
}
int clamp_hideout_spawn_end(int endX) {
if (endX < 0) return 0;
if (endX >= BANDIT_HIDEOUT_MAP_SIZE) return BANDIT_HIDEOUT_MAP_SIZE - 1;
return endX;
}
int pick_hideout_spawn_position(int startX, int endX) {
int startClamp = clamp_hideout_spawn_start(startX);
int endClamp = clamp_hideout_spawn_end(endX);
if (startClamp > endClamp) {
int swapTemp = startClamp;
startClamp = endClamp;
endClamp = swapTemp;
}
int spawnX = -1;
for (int attempt = 0; attempt < 20; attempt++) {
int candidate = random(startClamp, endClamp);
if (candidate == hideoutPlayerX) continue;
if (get_hideout_bandit_at(candidate) != null) continue;
spawnX = candidate;
break;
}
if (spawnX == -1) {
spawnX = random(startClamp, endClamp);
}
return spawnX;
}
void spawn_hideout_bandit_in_range(int startX, int endX) {
int spawnX = pick_hideout_spawn_position(startX, endX);
string alertSound = pick_invader_alert_sound("bandit");
if (alertSound == "") alertSound = "sounds/enemies/bandit1.ogg";
string weaponType = (random(0, 1) == 0) ? "spear" : "axe";
int moveInterval = random(BANDIT_MOVE_INTERVAL_MIN, BANDIT_MOVE_INTERVAL_MAX);
HideoutBandit@ bandit = HideoutBandit(spawnX, alertSound, weaponType, moveInterval);
hideoutBandits.insert_last(bandit);
bandit.soundHandle = play_1d_with_volume_step(bandit.alertSound, hideoutPlayerX, bandit.position, true, BANDIT_SOUND_VOLUME_STEP);
}
void spawn_hideout_bandits_initial() {
int baseSpawnStart = hideoutBaseX - (BANDIT_HIDEOUT_BASE_SPAWN_RANGE - 1);
int baseSpawnEnd = hideoutBaseX;
for (int i = 0; i < BANDIT_HIDEOUT_BANDIT_COUNT; i++) {
spawn_hideout_bandit_in_range(baseSpawnStart, baseSpawnEnd);
}
}
void respawn_hideout_bandit() {
int startSpawnStart = 0;
int startSpawnEnd = BANDIT_HIDEOUT_START_SPAWN_RANGE - 1;
if (startSpawnEnd > hideoutBaseX) startSpawnEnd = hideoutBaseX;
int baseSpawnStart = hideoutBaseX - (BANDIT_HIDEOUT_BASE_SPAWN_RANGE - 1);
int baseSpawnEnd = hideoutBaseX;
int roll = random(0, 1);
if (roll == 0) {
spawn_hideout_bandit_in_range(startSpawnStart, startSpawnEnd);
} else {
spawn_hideout_bandit_in_range(baseSpawnStart, baseSpawnEnd);
}
}
void init_bandit_hideout_adventure() {
reset_adventure_combat_state();
hideoutPlayerX = 0;
hideoutPlayerFacing = 1;
hideoutBaseX = BANDIT_HIDEOUT_MAP_SIZE - 1;
hideoutBanditsKilled = 0;
int barricadeBase = current_day * BANDIT_HIDEOUT_BARRICADE_HP_PER_DAY;
if (barricadeBase < BANDIT_HIDEOUT_BARRICADE_HP_PER_DAY) barricadeBase = BANDIT_HIDEOUT_BARRICADE_HP_PER_DAY;
if (barricadeBase > BANDIT_HIDEOUT_BARRICADE_HP_MAX) barricadeBase = BANDIT_HIDEOUT_BARRICADE_HP_MAX;
hideoutBarricadeMax = barricadeBase;
hideoutBarricadeHealth = barricadeBase;
build_hideout_terrain();
clear_hideout_bandits();
spawn_hideout_bandits_initial();
}
void cleanup_bandit_hideout_adventure() {
clear_hideout_bandits();
reset_adventure_combat_state();
p.destroy_all();
}
void run_bandit_hideout_adventure() {
// Stop main game sounds
p.destroy_all();
init_bandit_hideout_adventure();
string[] intro;
intro.insert_last("=== Bandit's Hideout ===");
intro.insert_last("");
intro.insert_last("You find a hidden bandit base deep in the forest.");
intro.insert_last("The base lies far to the east, guarded by a barricade.");
intro.insert_last("");
intro.insert_last("Objective:");
intro.insert_last(" - Reach the base and destroy the barricade");
intro.insert_last("");
intro.insert_last("Bandits will, of course, not take this lying down.");
text_reader_lines(intro, "Adventure", true);
while (true) {
wait(5);
if (key_pressed(KEY_ESCAPE)) {
cleanup_bandit_hideout_adventure();
speak_with_history("You flee the hideout.", true);
return;
}
// Standard game keys
check_quick_slot_keys();
check_notification_keys();
check_speech_history_keys();
if (key_pressed(KEY_H)) {
speak_with_history(player_health + " health of " + max_health, true);
}
if (key_pressed(KEY_X)) {
int distanceToBase = hideoutBaseX - hideoutPlayerX;
if (distanceToBase < 0) distanceToBase = 0;
string terrain = get_hideout_terrain_at(hideoutPlayerX);
speak_with_history("x " + hideoutPlayerX + ", terrain " + terrain + ". Base " + distanceToBase + " tiles east. Barricade " + hideoutBarricadeHealth + " of " + hideoutBarricadeMax + ".", true);
}
handle_hideout_player_movement();
handle_hideout_player_actions();
update_hideout_search();
update_hideout_bandits();
adventure_update_bow_shot(hideoutPlayerX);
if (hideoutBarricadeHealth <= 0) {
cleanup_bandit_hideout_adventure();
p.play_stationary("sounds/actions/break_snare.ogg", false);
give_bandit_hideout_rewards();
return;
}
if (player_health <= 0) {
cleanup_bandit_hideout_adventure();
speak_with_history("The bandits cut you down.", true);
return;
}
p.update_listener_1d(hideoutPlayerX);
}
}
void handle_hideout_player_movement() {
if (key_pressed(KEY_LEFT) && hideoutPlayerFacing != 0) {
hideoutPlayerFacing = 0;
speak_with_history("west", true);
hideoutWalkTimer.restart();
}
if (key_pressed(KEY_RIGHT) && hideoutPlayerFacing != 1) {
hideoutPlayerFacing = 1;
speak_with_history("east", true);
hideoutWalkTimer.restart();
}
if (hideoutWalkTimer.elapsed > walk_speed) {
if (key_down(KEY_LEFT) && hideoutPlayerX > 0) {
hideoutPlayerFacing = 0;
hideoutPlayerX--;
hideoutWalkTimer.restart();
if (player_health > 0) play_hideout_player_footstep();
} else if (key_down(KEY_RIGHT) && hideoutPlayerX < hideoutBaseX) {
hideoutPlayerFacing = 1;
hideoutPlayerX++;
hideoutWalkTimer.restart();
if (player_health > 0) play_hideout_player_footstep();
}
}
}
void handle_hideout_player_actions() {
bool ctrlDown = (key_down(KEY_LCTRL) || key_down(KEY_RCTRL));
// Bow draw detection
if (bow_equipped) {
if (ctrlDown && !bow_drawing) {
if (get_personal_count(ITEM_ARROWS) > 0) {
bow_drawing = true;
bow_draw_timer.restart();
p.play_stationary("sounds/weapons/bow_draw.ogg", false);
} else {
speak_ammo_blocked("No arrows.");
}
}
if (bow_drawing && !ctrlDown) {
adventure_release_bow_attack(hideoutPlayerX, hideoutPlayerFacing, @bandit_hideout_ranged_attack);
bow_drawing = false;
}
}
if (!bow_equipped && bow_drawing) {
bow_drawing = false;
}
// Sling charge detection
if (!bow_equipped && sling_equipped && ctrlDown && !sling_charging) {
if (get_personal_count(ITEM_STONES) > 0) {
sling_charging = true;
sling_charge_timer.restart();
sling_sound_handle = p.play_stationary("sounds/weapons/sling_swing.ogg", true);
last_sling_stage = -1;
} else {
speak_ammo_blocked("No stones.");
}
}
if (sling_charging && ctrlDown) {
update_sling_charge();
}
if (sling_charging && !ctrlDown) {
adventure_release_sling_attack(hideoutPlayerX, hideoutPlayerFacing, @bandit_hideout_ranged_attack);
sling_charging = false;
safe_destroy_sound(sling_sound_handle);
}
if (!bow_equipped && !bow_drawing && !sling_equipped && !sling_charging) {
if (fishing_pole_equipped) return;
int weaponType = get_hideout_melee_weapon_type();
if (weaponType == -1) return;
int attackCooldown = 1000;
if (weaponType == ADVENTURE_WEAPON_SPEAR) attackCooldown = 800;
if (weaponType == ADVENTURE_WEAPON_AXE) attackCooldown = 1600;
if (ctrlDown && hideoutAttackTimer.elapsed > attackCooldown) {
hideoutAttackTimer.restart();
play_hideout_melee_swing(weaponType);
if (hideout_melee_hit(weaponType)) {
play_hideout_melee_hit(weaponType);
}
}
}
}
void update_hideout_search() {
bool shiftDown = (key_down(KEY_LSHIFT) || key_down(KEY_RSHIFT));
if (shiftDown) {
if (key_pressed(KEY_COMMA) || key_pressed(KEY_PERIOD)) {
hideoutSearching = false;
hideoutSearchDelayTimer.restart();
}
}
bool searchKeyDown = shiftDown || key_down(KEY_SLASH) || key_down(KEY_Z);
if (!searchKeyDown && !hideoutSearching) {
hideoutSearchTimer.restart();
}
int searchTime = apply_rune_gather_bonus(2000);
if (searchKeyDown && hideoutSearchTimer.elapsed > searchTime && !hideoutSearching) {
hideoutSearching = true;
hideoutSearchDelayTimer.restart();
}
if (hideoutSearching && hideoutSearchDelayTimer.elapsed >= 1000) {
hideoutSearching = false;
hideoutSearchTimer.restart();
perform_hideout_search();
}
}
void perform_hideout_search() {
if (random(1, 100) <= 10) {
speak_with_history("Found nothing.", true);
return;
}
string terrain = get_hideout_terrain_at(hideoutPlayerX);
if (terrain == "stone" || terrain == "gravel") {
if (try_search_for_terrain(terrain)) {
return;
}
}
speak_with_history("Found nothing.", true);
}
int get_hideout_melee_weapon_type() {
if (spear_equipped) return ADVENTURE_WEAPON_SPEAR;
if (axe_equipped) return ADVENTURE_WEAPON_AXE;
return -1;
}
void play_hideout_melee_swing(int weaponType) {
if (weaponType == ADVENTURE_WEAPON_SPEAR) {
p.play_stationary("sounds/weapons/spear_swing.ogg", false);
} else if (weaponType == ADVENTURE_WEAPON_AXE) {
p.play_stationary("sounds/weapons/axe_swing.ogg", false);
}
}
void play_hideout_melee_hit(int weaponType) {
if (weaponType == ADVENTURE_WEAPON_SPEAR) {
p.play_stationary("sounds/weapons/spear_hit.ogg", false);
} else if (weaponType == ADVENTURE_WEAPON_AXE) {
p.play_stationary("sounds/weapons/axe_hit.ogg", false);
}
}
bool hideout_melee_hit(int weaponType) {
int range = (weaponType == ADVENTURE_WEAPON_SPEAR) ? 1 : 0;
int damage = (weaponType == ADVENTURE_WEAPON_SPEAR) ? SPEAR_DAMAGE : AXE_DAMAGE;
for (int offset = -range; offset <= range; offset++) {
int targetX = hideoutPlayerX + offset;
if (damage_hideout_bandit_at(targetX, damage)) {
play_creature_hit_sound("sounds/enemies/zombie_hit.ogg", hideoutPlayerX, targetX, BANDIT_SOUND_VOLUME_STEP);
return true;
}
}
if (abs(hideoutPlayerX - hideoutBaseX) <= range) {
if (apply_hideout_barricade_damage(damage)) {
return true;
}
}
return false;
}
bool apply_hideout_barricade_damage(int damage) {
if (damage <= 0) return false;
if (hideoutBarricadeHealth <= 0) return false;
hideoutBarricadeHealth -= damage;
if (hideoutBarricadeHealth < 0) hideoutBarricadeHealth = 0;
play_1d_with_volume_step("sounds/weapons/axe_hit.ogg", hideoutPlayerX, hideoutBaseX, false, BANDIT_SOUND_VOLUME_STEP);
return true;
}
int find_hideout_ranged_target(int playerX, int direction, int range) {
for (int dist = 1; dist <= range; dist++) {
int checkX = playerX + (dist * direction);
if (checkX < 0 || checkX >= BANDIT_HIDEOUT_MAP_SIZE) break;
if (get_hideout_bandit_at(checkX) != null) {
return checkX;
}
if (hideoutBarricadeHealth > 0 && checkX == hideoutBaseX) {
return checkX;
}
}
return -1;
}
int bandit_hideout_ranged_attack(int playerX, int direction, int range, int weaponType, int damage) {
int targetX = find_hideout_ranged_target(playerX, direction, range);
if (targetX == -1) return -1;
if (targetX == hideoutBaseX) {
apply_hideout_barricade_damage(damage);
return targetX;
}
if (damage_hideout_bandit_at(targetX, damage)) {
return targetX;
}
return -1;
}
bool damage_hideout_bandit_at(int pos, int damage) {
for (uint i = 0; i < hideoutBandits.length(); i++) {
if (hideoutBandits[i].position == pos) {
hideoutBandits[i].health -= damage;
if (hideoutBandits[i].health <= 0) {
if (hideoutBandits[i].soundHandle != -1) {
p.destroy_sound(hideoutBandits[i].soundHandle);
hideoutBandits[i].soundHandle = -1;
}
if (hideoutBandits[i].inWeaponRange) {
play_weapon_range_sound("sounds/enemies/exit_range.ogg", hideoutBandits[i].position);
}
play_creature_death_sounds("sounds/enemies/enemy_falls.ogg", hideoutBandits[i].alertSound, hideoutPlayerX, pos, BANDIT_SOUND_VOLUME_STEP);
hideoutBandits.remove_at(i);
hideoutBanditsKilled++;
respawn_hideout_bandit();
}
return true;
}
}
return false;
}
bool try_hideout_bandit_attack_player(HideoutBandit@ bandit) {
if (player_health <= 0) return false;
if (abs(bandit.position - hideoutPlayerX) > 1) return false;
if (bandit.attackTimer.elapsed < BANDIT_ATTACK_INTERVAL) return false;
bandit.attackTimer.restart();
if (bandit.weaponType == "spear") {
play_creature_attack_sound("sounds/weapons/spear_swing.ogg", hideoutPlayerX, bandit.position, BANDIT_SOUND_VOLUME_STEP);
} else {
play_creature_attack_sound("sounds/weapons/axe_swing.ogg", hideoutPlayerX, bandit.position, BANDIT_SOUND_VOLUME_STEP);
}
int damage = random(BANDIT_DAMAGE_MIN, BANDIT_DAMAGE_MAX);
player_health -= damage;
if (player_health < 0) player_health = 0;
if (bandit.weaponType == "spear") {
play_creature_attack_sound("sounds/weapons/spear_hit.ogg", hideoutPlayerX, bandit.position, BANDIT_SOUND_VOLUME_STEP);
} else {
play_creature_attack_sound("sounds/weapons/axe_hit.ogg", hideoutPlayerX, bandit.position, BANDIT_SOUND_VOLUME_STEP);
}
play_player_damage_sound();
return true;
}
void update_hideout_bandit_audio(HideoutBandit@ bandit) {
if (bandit.soundHandle != -1 && p.sound_is_active(bandit.soundHandle)) {
p.update_sound_1d(bandit.soundHandle, bandit.position);
return;
}
if (bandit.soundHandle != -1) {
p.destroy_sound(bandit.soundHandle);
}
bandit.soundHandle = play_1d_with_volume_step(bandit.alertSound, hideoutPlayerX, bandit.position, true, BANDIT_SOUND_VOLUME_STEP);
}
void update_hideout_bandit(HideoutBandit@ bandit) {
update_weapon_range_audio_with_listener(hideoutPlayerX, bandit.position, bandit.inWeaponRange);
if (try_hideout_bandit_attack_player(bandit)) {
update_hideout_bandit_audio(bandit);
return;
}
if (bandit.moveTimer.elapsed < bandit.moveInterval) {
update_hideout_bandit_audio(bandit);
return;
}
bandit.moveTimer.restart();
int direction = 0;
if (hideoutPlayerX > bandit.position) direction = 1;
else if (hideoutPlayerX < bandit.position) direction = -1;
if (direction != 0) {
int targetX = bandit.position + direction;
if (targetX >= 0 && targetX < BANDIT_HIDEOUT_MAP_SIZE) {
if (get_hideout_bandit_at(targetX) == null) {
bandit.position = targetX;
play_hideout_positional_footstep(hideoutPlayerX, bandit.position, BANDIT_FOOTSTEP_MAX_DISTANCE, BANDIT_SOUND_VOLUME_STEP);
}
}
}
update_hideout_bandit_audio(bandit);
}
void update_hideout_bandits() {
for (uint i = 0; i < hideoutBandits.length(); i++) {
update_hideout_bandit(hideoutBandits[i]);
}
}
int add_hideout_storage_item(int itemType, int amount) {
if (amount <= 0) return 0;
int capacity = BASE_STORAGE_MAX - get_storage_count(itemType);
if (capacity <= 0) return 0;
int addedAmount = amount;
if (addedAmount > capacity) addedAmount = capacity;
if (addedAmount <= 0) return 0;
add_storage_count(itemType, addedAmount);
if (itemType == ITEM_SMALL_GAME) {
for (int i = 0; i < addedAmount; i++) {
storage_small_game_types.insert_last("small game");
}
}
if (itemType == ITEM_FISH) {
for (int i = 0; i < addedAmount; i++) {
add_storage_fish_weight(get_default_fish_weight());
}
}
return addedAmount;
}
void give_bandit_hideout_rewards() {
speak_with_history("Victory!", true);
string[] rewards;
rewards.insert_last("=== Victory Rewards ===");
rewards.insert_last("");
rewards.insert_last("Bandits defeated: " + hideoutBanditsKilled + ".");
if (world_altars.length() > 0) {
double favorReward = BANDIT_HIDEOUT_BASE_FAVOR + (hideoutBanditsKilled * BANDIT_HIDEOUT_FAVOR_PER_KILL);
if (favorReward > BANDIT_HIDEOUT_FAVOR_MAX) favorReward = BANDIT_HIDEOUT_FAVOR_MAX;
if (favorReward < BANDIT_HIDEOUT_BASE_FAVOR) favorReward = BANDIT_HIDEOUT_BASE_FAVOR;
favor += favorReward;
rewards.insert_last("Favor awarded: " + format_favor(favorReward) + ".");
} else {
rewards.insert_last("Altar not built. No favor awarded.");
}
rewards.insert_last("");
if (world_storages.length() == 0) {
rewards.insert_last("Storage not built. No item rewards.");
} else {
rewards.insert_last("Storage rewards:");
bool anyItems = false;
for (int itemType = 0; itemType < ITEM_COUNT; itemType++) {
int roll = random(0, 9);
if (roll <= 0) continue;
int addedAmount = add_hideout_storage_item(itemType, roll);
if (addedAmount <= 0) continue;
rewards.insert_last(get_item_display_name(itemType) + ": +" + addedAmount + ".");
anyItems = true;
}
if (!anyItems) {
rewards.insert_last("No items were recovered.");
}
}
text_reader_lines(rewards, "Bandit's Hideout", true);
}