A few minor tweaks to pets, rewards, and barricade bug fixes.

This commit is contained in:
Storm Dragon
2026-02-16 22:05:13 -05:00
parent 51599c9b99
commit ae249e6f09
4 changed files with 153 additions and 31 deletions

View File

@@ -11,6 +11,7 @@ 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 int BANDIT_HIDEOUT_ITEM_REWARD_MAX = 4;
const double BANDIT_HIDEOUT_FAVOR_PER_KILL = 0.08;
const double BANDIT_HIDEOUT_BASE_FAVOR = 0.30;
const double BANDIT_HIDEOUT_FAVOR_MAX = 1.0;
@@ -743,7 +744,7 @@ void give_bandit_hideout_rewards() {
rewards.insert_last("Storage rewards:");
bool anyItems = false;
for (int itemType = 0; itemType < ITEM_COUNT; itemType++) {
int roll = random(0, 5);
int roll = random(0, BANDIT_HIDEOUT_ITEM_REWARD_MAX);
if (roll <= 0) continue;
int addedAmount = add_hideout_storage_item(itemType, roll);
if (addedAmount <= 0) continue;

View File

@@ -269,12 +269,14 @@ const int PET_RANDOM_FIND_CHANCE = 20; // Percent per hour when loyalty is high
const int PET_ADVENTURE_CHANCE = 5; // Percent chance after adventure victory
const int PET_TREE_HAWK_CHANCE = 10; // Percent chance after reaching top of a tree
const int PET_LOYALTY_BONUS_THRESHOLD = 5;
const int PET_MOVE_SPEED = 320; // Slightly faster than base walk speed
const int PET_TRAVEL_MIN_MS = 100;
const int PET_RANGE = BOW_RANGE + 2;
const int PET_HEALTH_MAX = 10;
const int PET_ATTACK_SELF_DAMAGE = 1;
const int PET_KNOCKOUT_COOLDOWN_HOURS = 3;
const int PET_KNOCKOUT_COOLDOWN_HOURS = 4;
const float PET_CHARGE_SPEED_MULTIPLIER = 1.5;
const int PET_FOLLOW_COMFORT_DISTANCE = 2;
const int PET_FOLLOW_MAX_DISTANCE = 5;
// Goose settings
const int GOOSE_HEALTH = 1;

View File

@@ -159,8 +159,9 @@ void reinforce_barricade_max_with_sticks() {
int to_do = (max_reinforcements < can_afford) ? max_reinforcements : can_afford;
int total_cost = to_do * BARRICADE_STICK_COST;
int craft_time = (total_cost < to_do * 4) ? to_do * 4 : total_cost;
simulate_crafting(total_cost);
simulate_crafting(craft_time);
add_personal_count(ITEM_STICKS, -total_cost);
barricade_health += (to_do * BARRICADE_STICK_HEALTH);
if (barricade_health > BARRICADE_MAX_HEALTH) barricade_health = BARRICADE_MAX_HEALTH;
@@ -185,8 +186,9 @@ void reinforce_barricade_max_with_vines() {
int to_do = (max_reinforcements < can_afford) ? max_reinforcements : can_afford;
int total_cost = to_do * BARRICADE_VINE_COST;
int craft_time = (total_cost < to_do * 4) ? to_do * 4 : total_cost;
simulate_crafting(total_cost);
simulate_crafting(craft_time);
add_personal_count(ITEM_VINES, -total_cost);
barricade_health += (to_do * BARRICADE_VINE_HEALTH);
if (barricade_health > BARRICADE_MAX_HEALTH) barricade_health = BARRICADE_MAX_HEALTH;
@@ -211,8 +213,9 @@ void reinforce_barricade_max_with_log() {
int to_do = (max_reinforcements < can_afford) ? max_reinforcements : can_afford;
int total_cost = to_do * BARRICADE_LOG_COST;
int craft_time = (total_cost < to_do * 4) ? to_do * 4 : total_cost;
simulate_crafting(total_cost);
simulate_crafting(craft_time);
add_personal_count(ITEM_LOGS, -total_cost);
barricade_health += (to_do * BARRICADE_LOG_HEALTH);
if (barricade_health > BARRICADE_MAX_HEALTH) barricade_health = BARRICADE_MAX_HEALTH;
@@ -237,8 +240,9 @@ void reinforce_barricade_max_with_stones() {
int to_do = (max_reinforcements < can_afford) ? max_reinforcements : can_afford;
int total_cost = to_do * BARRICADE_STONE_COST;
int craft_time = (total_cost < to_do * 4) ? to_do * 4 : total_cost;
simulate_crafting(total_cost);
simulate_crafting(craft_time);
add_personal_count(ITEM_STONES, -total_cost);
barricade_health += (to_do * BARRICADE_STONE_HEALTH);
if (barricade_health > BARRICADE_MAX_HEALTH) barricade_health = BARRICADE_MAX_HEALTH;

View File

@@ -26,6 +26,7 @@ const int PET_TRAVEL_NONE = 0;
const int PET_TRAVEL_ATTACK = 1;
const int PET_TRAVEL_RETRIEVE = 2;
const int PET_TRAVEL_RETURN = 3;
const int PET_TRAVEL_LEAVE = 4;
bool petTravelActive = false;
int petTravelAction = PET_TRAVEL_NONE;
@@ -36,6 +37,8 @@ string petTravelTargetLabel = "";
int petTravelDurationMs = 0;
int petTravelSoundHandle = -1;
timer petTravelTimer;
bool petLeaving = false;
string petLeavingName = "";
string[] petSoundPaths;
bool petSoundsInitialized = false;
@@ -238,6 +241,8 @@ bool is_hawk_pet() {
}
void play_pet_travel_step_sound(int stepPos) {
if (stepPos < 0 || stepPos >= MAP_SIZE) return;
int listenerPos = get_pet_listener_pos();
if (abs(stepPos - listenerPos) > CREATURE_DEFAULT_FOOTSTEP_DISTANCE) return;
@@ -323,6 +328,16 @@ bool is_pet_at_player_position() {
return petPositionValid && petPosition == get_pet_listener_pos();
}
bool is_pet_within_follow_distance() {
if (!petPositionValid) return false;
return abs(petPosition - get_pet_listener_pos()) <= PET_FOLLOW_MAX_DISTANCE;
}
bool is_pet_within_follow_comfort_distance() {
if (!petPositionValid) return false;
return abs(petPosition - get_pet_listener_pos()) <= PET_FOLLOW_COMFORT_DISTANCE;
}
void complete_pet_return() {
petOut = false;
petRecallRequested = false;
@@ -409,16 +424,59 @@ void reset_pet_state() {
petTravelDurationMs = 0;
safe_destroy_sound(petTravelSoundHandle);
petTravelSoundHandle = -1;
petLeaving = false;
petLeavingName = "";
petAttackTimer.restart();
petRetrieveTimer.restart();
petTravelTimer.restart();
}
void pet_leave() {
if (!petActive) return;
string oldPet = normalize_pet_name_text(petType);
reset_pet_state();
if (oldPet != "") {
speak_with_history(oldPet + " leaves.", true);
if (oldPet == "") oldPet = "pet";
speak_with_history(oldPet + " leaves.", true);
if (!petOut) {
reset_pet_state();
return;
}
petRecallRequested = false;
petLeaving = true;
petLeavingName = oldPet;
stop_pet_travel();
}
void start_pet_travel_leave() {
stop_pet_travel();
petTravelActive = true;
petTravelAction = PET_TRAVEL_LEAVE;
petTravelStartPos = petPositionValid ? petPosition : get_pet_listener_pos();
petPosition = petTravelStartPos;
petPositionValid = true;
int listenerPos = get_pet_listener_pos();
int runDirection = (petTravelStartPos >= listenerPos) ? 1 : -1;
int outOfRangeDistance = PET_FOLLOW_MAX_DISTANCE + 1;
if (runDirection > 0) {
petTravelTargetPos = MAP_SIZE + outOfRangeDistance;
} else {
petTravelTargetPos = -outOfRangeDistance;
}
petTravelDurationMs = get_pet_travel_duration_ms(petTravelStartPos, petTravelTargetPos, true);
petTravelTimer.restart();
if (petSoundPath != "" && file_exists(petSoundPath)) {
petTravelSoundHandle = play_1d_with_volume_step(
petSoundPath,
get_pet_listener_pos(),
petTravelStartPos,
true,
PLAYER_WEAPON_SOUND_VOLUME_STEP
);
}
}
@@ -438,6 +496,12 @@ void adjust_pet_loyalty(int delta) {
void check_pet_call_key() {
if (!key_pressed(KEY_SPACE)) return;
if (petLeaving) {
string name = petLeavingName;
if (name == "") name = "pet";
speak_with_history("Your " + name + " is leaving.", true);
return;
}
if (!petActive) {
speak_with_history("No pet.", true);
return;
@@ -506,9 +570,15 @@ void stop_pet_travel() {
petTravelSoundHandle = -1;
}
int get_pet_travel_duration_ms(int startPos, int targetPos) {
int get_pet_travel_duration_ms(int startPos, int targetPos, bool chargeTravel = false) {
int distance = abs(targetPos - startPos);
int duration = distance * PET_MOVE_SPEED;
int speedPerTile = walk_speed;
if (chargeTravel) {
speedPerTile = int(float(walk_speed) / PET_CHARGE_SPEED_MULTIPLIER);
if (speedPerTile < 1) speedPerTile = 1;
}
int duration = distance * speedPerTile;
if (duration < PET_TRAVEL_MIN_MS) duration = PET_TRAVEL_MIN_MS;
return duration;
}
@@ -523,7 +593,7 @@ void start_pet_travel_attack(int targetPos, const string&in targetLabel, int tar
petTravelTargetPos = targetPos;
petTravelTargetLabel = targetLabel;
petTravelTargetKind = targetKind;
petTravelDurationMs = get_pet_travel_duration_ms(petTravelStartPos, targetPos);
petTravelDurationMs = get_pet_travel_duration_ms(petTravelStartPos, targetPos, true);
petTravelTimer.restart();
if (petSoundPath != "" && file_exists(petSoundPath)) {
@@ -545,7 +615,7 @@ void start_pet_travel_retrieve(int targetPos) {
petPosition = petTravelStartPos;
petPositionValid = true;
petTravelTargetPos = targetPos;
petTravelDurationMs = get_pet_travel_duration_ms(petTravelStartPos, targetPos);
petTravelDurationMs = get_pet_travel_duration_ms(petTravelStartPos, targetPos, true);
petTravelTimer.restart();
}
@@ -562,6 +632,7 @@ void start_pet_travel_return(int targetPos) {
}
void request_pet_return() {
if (petLeaving) return;
if (!petActive || !petOut) return;
if (!petPositionValid) {
petPosition = get_pet_listener_pos();
@@ -575,13 +646,14 @@ void request_pet_return() {
}
void request_pet_follow() {
if (petLeaving) return;
if (!petActive || !petOut) return;
petRecallRequested = false;
if (!petPositionValid) {
petPosition = get_pet_listener_pos();
petPositionValid = true;
}
if (is_pet_at_player_position()) {
if (is_pet_within_follow_comfort_distance()) {
stop_pet_travel();
return;
}
@@ -603,13 +675,61 @@ void update_pet_travel() {
if (!petTravelActive) return;
if (petTravelDurationMs < 1) petTravelDurationMs = 1;
if (petTravelAction == PET_TRAVEL_RETURN) {
if (!petPositionValid) {
petPosition = petTravelStartPos;
petPositionValid = true;
}
petTravelTargetPos = get_pet_listener_pos();
int distanceToPlayer = abs(petTravelTargetPos - petPosition);
if (petRecallRequested) {
if (distanceToPlayer == 0) {
complete_pet_return();
return;
}
} else if (distanceToPlayer <= PET_FOLLOW_COMFORT_DISTANCE) {
stop_pet_travel();
return;
}
int stepInterval = walk_speed;
if (distanceToPlayer > PET_FOLLOW_MAX_DISTANCE) {
stepInterval = int(float(walk_speed) / PET_CHARGE_SPEED_MULTIPLIER);
if (stepInterval < 1) stepInterval = 1;
}
if (stepInterval < PET_TRAVEL_MIN_MS) stepInterval = PET_TRAVEL_MIN_MS;
if (petTravelTimer.elapsed < stepInterval) {
return;
}
petTravelTimer.restart();
int stepDir = (petTravelTargetPos > petPosition) ? 1 : -1;
int stepPos = petPosition + stepDir;
update_pet_travel_position(stepPos);
if (petTravelSoundHandle != -1) {
p.update_sound_1d(petTravelSoundHandle, stepPos);
}
if (petRecallRequested && is_pet_at_player_position()) {
complete_pet_return();
return;
}
if (!petRecallRequested && is_pet_within_follow_comfort_distance()) {
stop_pet_travel();
return;
}
return;
}
if (petTravelAction == PET_TRAVEL_ATTACK) {
int refreshedTargetPos = -1;
if (find_pet_attack_target_by_kind(petTravelTargetKind, petTravelTargetPos, refreshedTargetPos)) {
petTravelTargetPos = refreshedTargetPos;
}
} else if (petTravelAction == PET_TRAVEL_RETURN) {
petTravelTargetPos = get_pet_listener_pos();
}
int elapsed = petTravelTimer.elapsed;
@@ -690,18 +810,8 @@ void update_pet_travel() {
request_pet_follow();
}
}
} else if (petTravelAction == PET_TRAVEL_RETURN) {
petPosition = petTravelTargetPos;
petPositionValid = true;
if (is_pet_at_player_position()) {
if (petRecallRequested) {
complete_pet_return();
} else {
stop_pet_travel();
}
return;
}
start_pet_travel_return(get_pet_listener_pos());
} else if (petTravelAction == PET_TRAVEL_LEAVE) {
reset_pet_state();
return;
}
@@ -987,7 +1097,7 @@ void update_pet_follow() {
int targetKind = -1;
if (find_pet_attack_target(targetPos, targetLabel, targetKind)) return;
if (is_pet_at_player_position()) return;
if (is_pet_within_follow_comfort_distance()) return;
request_pet_follow();
}
@@ -1010,6 +1120,7 @@ void attempt_pet_random_find() {
void handle_pet_hourly_update(int hour) {
if (!petActive) return;
if (petLeaving) return;
if (petKnockoutHoursRemaining > 0) {
petKnockoutHoursRemaining--;
@@ -1027,7 +1138,7 @@ void handle_pet_hourly_update(int hour) {
if (petOut) {
adjust_pet_loyalty(-1);
if (!petActive) return;
if (!petActive || petLeaving) return;
if (petLoyalty <= 1 && !petHungryWarned) {
notify("A " + get_pet_display_name() + " is getting hungry.");
petHungryWarned = true;
@@ -1047,6 +1158,10 @@ void handle_pet_hourly_update(int hour) {
}
void update_pets() {
if (petLeaving && !petTravelActive) {
start_pet_travel_leave();
}
update_pet_travel();
if (petActive && petOut) {
update_pet_retrieval();