Skip to content

Commit

Permalink
Balance related tweaks (#118)
Browse files Browse the repository at this point in the history
* fix enemy levels

* tune down item frequency a bit

* Don't interrupt movement after bribe/run away

* changelog

* increase hp for all classes

* chest equipment level based on distance instead of player level

* don't double beat if already dead

* changelog
  • Loading branch information
facundoolano authored Sep 5, 2021
1 parent e64fb05 commit f872e5f
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 43 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
* Show items bought and money spent in the buy command output #108
* Show mp cost in magic attacks 9f92efc
* The stat command can be used to describe items and equipment #117
* Equipment level found in chest based on distance instead of player level d22d3b9
* Game balance related tweaks #118

### Fixed
* Reach level 50 and 100 unlock and reward 4128f75
Expand All @@ -36,6 +38,7 @@
* Missed levels with class quest completion 1ec760
* Tweak gold found in chests 0317979 83691fa
* Don't add xp beyond the actual inflicted damage (prevents high xp when beating weaker enemies) 812a5f1
* Continue moving through dirs after successful bribe/run away 570a0de

## [0.6.0](https://github.com/facundoolano/rpg-cli/releases/tag/0.6.0) - 2021-08-04
### Added
Expand Down
42 changes: 21 additions & 21 deletions src/character/classes.yaml
Original file line number Diff line number Diff line change
@@ -1,116 +1,116 @@
- name: warrior
hp: [30, 7]
hp: [50, 10]
strength: [12, 3]
speed: [11, 2]
category: player
- name: mage
hp: [20, 4]
hp: [30, 6]
mp: [10, 4]
strength: [10, 3]
speed: [10, 2]
category: player
- name: thief
hp: [21, 5]
hp: [35, 7]
strength: [7, 2]
speed: [19, 4]
category: player
- name: rat
hp: [10, 3]
hp: [15, 5]
strength: [5, 2]
speed: [16, 2]
category: common
- name: wolf
hp: [15, 3]
hp: [25, 5]
strength: [8, 2]
speed: [12, 2]
category: common
- name: snake
hp: [13, 3]
hp: [23, 7]
strength: [7, 2]
speed: [6, 2]
inflicts: [poison, 5]
category: common
- name: slime
hp: [80, 3]
hp: [80, 4]
strength: [3, 2]
speed: [4, 2]
inflicts: [poison, 10]
category: common
- name: spider
hp: [10, 3]
hp: [16, 5]
strength: [9, 2]
speed: [12, 2]
inflicts: [poison, 20]
category: common
- name: zombie
hp: [50, 3]
hp: [80, 5]
strength: [8, 2]
speed: [6, 2]
category: rare
- name: orc
hp: [35, 3]
hp: [60, 5]
strength: [13, 2]
speed: [12, 2]
category: rare
- name: skeleton
hp: [30, 3]
hp: [45, 5]
strength: [10, 2]
speed: [10, 2]
category: rare
- name: demon
hp: [50, 3]
hp: [70, 5]
strength: [10, 2]
speed: [18, 2]
inflicts: [burn, 10]
category: rare
- name: vampire
hp: [50, 3]
hp: [70, 5]
strength: [13, 2]
speed: [10, 2]
category: rare
- name: dragon
hp: [100, 3]
hp: [110, 5]
strength: [25, 2]
speed: [8, 2]
inflicts: [burn, 2]
category: rare
- name: golem
hp: [50, 3]
hp: [70, 5]
strength: [45, 2]
speed: [2, 1]
category: rare
- name: sorcerer
hp: [30, 3]
hp: [45, 5]
mp: [13, 1]
strength: [10, 2]
speed: [8, 2]
inflicts: [burn, 5]
category: rare
- name: chimera
hp: [200, 2]
hp: [250, 2]
strength: [90, 2]
speed: [16, 2]
inflicts: [poison, 3]
category: legendary
- name: basilisk
hp: [150, 3]
hp: [180, 3]
strength: [100, 2]
speed: [18, 2]
inflicts: [poison, 2]
category: legendary
- name: minotaur
hp: [100, 3]
hp: [120, 3]
strength: [60, 2]
speed: [40, 2]
category: legendary
- name: balrog
hp: [200, 3]
hp: [270, 3]
strength: [200, 2]
speed: [14, 2]
inflicts: [burn, 3]
category: legendary
- name: phoenix
hp: [350, 3]
hp: [500, 3]
strength: [180, 2]
speed: [28, 2]
inflicts: [burn, 3]
Expand Down
4 changes: 2 additions & 2 deletions src/character/enemy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pub fn spawn(location: &location::Location, player: &Character) -> Option<Charac
.or_else(|| spawn_dev(player, location))
.unwrap_or_else(|| spawn_random(player, &distance));

let level = random().enemy_level(level);
let enemy = Character::new(class, level);
log::enemy_appears(&enemy, location);
Some(enemy)
Expand All @@ -43,7 +44,7 @@ fn spawn_gorthaur(player: &Character, location: &location::Location) -> Option<(
class.hp.0 *= 2;
class.strength.0 *= 2;
class.category = Category::Legendary;
Some((class, 100))
Some((class, player.level))
} else {
None
}
Expand Down Expand Up @@ -106,7 +107,6 @@ fn spawn_random(player: &Character, distance: &location::Distance) -> (Class, i3
.clone();

let level = std::cmp::max(player.level / 10 + distance.len() - 1, 1);
let level = random().enemy_level(level);
(Class::random(category).clone(), level)
}

Expand Down
4 changes: 3 additions & 1 deletion src/character/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,9 @@ impl Character {

/// If the double beat ring is equipped, attack the receiver.
pub fn maybe_double_beat(&mut self, receiver: &mut Self) {
if self.left_ring == Some(Ring::Double) || self.right_ring == Some(Ring::Double) {
if receiver.current_hp > 0
&& (self.left_ring == Some(Ring::Double) || self.right_ring == Some(Ring::Double))
{
// assuming it's always the player and we don't need to handle death
let _ = self.attack(receiver);
}
Expand Down
14 changes: 9 additions & 5 deletions src/game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,9 @@ impl Game {

if !self.location.is_home() {
if let Some(mut enemy) = enemy::spawn(&self.location, &self.player) {
return self.battle(&mut enemy, run, bribe);
if self.battle(&mut enemy, run, bribe)? {
return Ok(());
}
}
}
}
Expand Down Expand Up @@ -218,19 +220,21 @@ impl Game {

/// Attempt to bribe or run away according to the given options,
/// and start a battle if that fails.
/// Return Ok(true) if a battle took place, Ok(false) if it was avoided,
/// Err<Dead> if the character dies.
pub fn battle(
&mut self,
enemy: &mut Character,
run: bool,
bribe: bool,
) -> Result<(), character::Dead> {
) -> Result<bool, character::Dead> {
// don't attempt bribe and run in the same turn
if bribe {
let bribe_cost = self.player.gold_gained(enemy.level) / 2;
if self.gold >= bribe_cost && random().bribe_succeeds() {
self.gold -= bribe_cost;
log::bribe(&self.player, bribe_cost);
return Ok(());
return Ok(false);
};
log::bribe(&self.player, 0);
} else if run {
Expand All @@ -242,13 +246,13 @@ impl Game {
);
log::run_away(&self.player, success);
if success {
return Ok(());
return Ok(false);
}
}

if let Ok(xp) = self.run_battle(enemy) {
self.battle_won(enemy, xp);
Ok(())
Ok(true)
} else {
self.battle_lost();
Err(character::Dead)
Expand Down
16 changes: 9 additions & 7 deletions src/item/chest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ impl Chest {
chest.gold = game.player.gold_gained(game.player.level + distance.len());
}
if equipment_chest {
let (sword, shield) = random_equipment(game.player.rounded_level());
let (sword, shield) = random_equipment(distance.len());
chest.sword = sword;
chest.shield = shield;
}
Expand Down Expand Up @@ -170,9 +170,11 @@ fn maybe_upgrade(current: &mut Option<Equipment>, other: &mut Option<Equipment>)
false
}

fn random_equipment(level: i32) -> (Option<Equipment>, Option<Equipment>) {
fn random_equipment(distance: i32) -> (Option<Equipment>, Option<Equipment>) {
let mut rng = rand::thread_rng();

let level = std::cmp::max(1, (distance / 5) * 5);

vec![
(100, (Some(Equipment::sword(level)), None)),
(80, (None, Some(Equipment::shield(level)))),
Expand All @@ -193,11 +195,11 @@ fn random_item(level: i32) -> Box<dyn Item> {
(10, Box::new(Remedy::new())),
(10, Box::new(Escape::new())),
(50, Box::new(Ether::new(level))),
(10, Box::new(stone::Health)),
(10, Box::new(stone::Magic)),
(10, Box::new(stone::Power)),
(10, Box::new(stone::Speed)),
(5, Box::new(stone::Level)),
(5, Box::new(stone::Health)),
(5, Box::new(stone::Magic)),
(5, Box::new(stone::Power)),
(5, Box::new(stone::Speed)),
(1, Box::new(stone::Level)),
];

// make a separate vec with enumerated weights, then remove from the item vec
Expand Down
14 changes: 7 additions & 7 deletions src/randomizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ impl Randomizer for DefaultRandomizer {
let mut rng = rand::thread_rng();

match distance {
location::Distance::Near(_) => false,
location::Distance::Near(_) => rng.gen_ratio(1, 30),
location::Distance::Mid(_) => rng.gen_ratio(3, 30),
location::Distance::Far(_) => rng.gen_ratio(5, 30),
}
Expand All @@ -180,19 +180,19 @@ impl Randomizer for DefaultRandomizer {
let mut rng = rand::thread_rng();

match distance {
location::Distance::Near(_) => rng.gen_ratio(1, 30),
location::Distance::Mid(_) => rng.gen_ratio(4, 30),
location::Distance::Far(_) => rng.gen_ratio(6, 30),
location::Distance::Near(_) => false,
location::Distance::Mid(_) => rng.gen_ratio(3, 30),
location::Distance::Far(_) => rng.gen_ratio(5, 30),
}
}

fn item_chest(&self, distance: &location::Distance) -> bool {
let mut rng = rand::thread_rng();

match distance {
location::Distance::Near(_) => rng.gen_ratio(5, 50),
location::Distance::Mid(_) => rng.gen_ratio(10, 50),
location::Distance::Far(_) => rng.gen_ratio(16, 50),
location::Distance::Near(_) => rng.gen_ratio(1, 50),
location::Distance::Mid(_) => rng.gen_ratio(5, 50),
location::Distance::Far(_) => rng.gen_ratio(10, 50),
}
}
}
Expand Down

0 comments on commit f872e5f

Please sign in to comment.