removes monster to-hit bonus from player
This commit is contained in:
parent
f55f4504db
commit
bd90c3f760
8 changed files with 41 additions and 12 deletions
|
|
@ -192,7 +192,7 @@
|
||||||
"weight": 6,
|
"weight": 6,
|
||||||
"value": 10,
|
"value": 10,
|
||||||
"flags": ["EQUIP_SHIELD"],
|
"flags": ["EQUIP_SHIELD"],
|
||||||
"effects": { "ac": "2" }
|
"effects": { "ac": "2", "to_hit": "-1" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "equip_largeshield",
|
"id": "equip_largeshield",
|
||||||
|
|
@ -201,7 +201,7 @@
|
||||||
"weight": 12,
|
"weight": 12,
|
||||||
"value": 35,
|
"value": 35,
|
||||||
"flags": ["EQUIP_SHIELD"],
|
"flags": ["EQUIP_SHIELD"],
|
||||||
"effects": { "ac": "3" }
|
"effects": { "ac": "3", "to_hit": "-2" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "equip_body_weakleather",
|
"id": "equip_body_weakleather",
|
||||||
|
|
|
||||||
|
|
@ -316,6 +316,11 @@ pub struct ArmourClassBonus {
|
||||||
pub amount: i32,
|
pub amount: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Component, ConvertSaveload, Clone)]
|
||||||
|
pub struct ToHitBonus {
|
||||||
|
pub amount: i32,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Component, Serialize, Deserialize, Clone)]
|
#[derive(Component, Serialize, Deserialize, Clone)]
|
||||||
pub struct Equippable {
|
pub struct Equippable {
|
||||||
pub slot: EquipmentSlot,
|
pub slot: EquipmentSlot,
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ pub fn hp_per_level(rng: &mut rltk::RandomNumberGenerator, constitution: i32) ->
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
/// Returns a total HP roll for a player, based on a given constitution score and level.
|
/// Returns a total HP roll for a player, based on a given constitution score and level.
|
||||||
pub fn player_hp_at_level(rng: &mut rltk::RandomNumberGenerator, constitution: i32, level: i32) -> i32 {
|
pub fn player_hp_at_level(rng: &mut rltk::RandomNumberGenerator, constitution: i32, level: i32) -> i32 {
|
||||||
let mut total = 10 + attr_bonus(constitution);
|
let mut total = 8 + attr_bonus(constitution);
|
||||||
for _i in 0..level {
|
for _i in 0..level {
|
||||||
total += hp_per_level(rng, constitution);
|
total += hp_per_level(rng, constitution);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -489,7 +489,7 @@ pub fn obfuscate_name_ecs(ecs: &World, item: Entity) -> (String, String) {
|
||||||
if has_beatitude.known {
|
if has_beatitude.known {
|
||||||
let prefix = match has_beatitude.buc {
|
let prefix = match has_beatitude.buc {
|
||||||
BUC::Cursed => Some("cursed "),
|
BUC::Cursed => Some("cursed "),
|
||||||
BUC::Uncursed => None,
|
BUC::Uncursed => Some("uncursed "),
|
||||||
BUC::Blessed => Some("blessed "),
|
BUC::Blessed => Some("blessed "),
|
||||||
};
|
};
|
||||||
if prefix.is_some() {
|
if prefix.is_some() {
|
||||||
|
|
|
||||||
|
|
@ -611,6 +611,7 @@ fn main() -> rltk::BError {
|
||||||
gs.ecs.register::<MeleeWeapon>();
|
gs.ecs.register::<MeleeWeapon>();
|
||||||
gs.ecs.register::<NaturalAttacks>();
|
gs.ecs.register::<NaturalAttacks>();
|
||||||
gs.ecs.register::<ArmourClassBonus>();
|
gs.ecs.register::<ArmourClassBonus>();
|
||||||
|
gs.ecs.register::<ToHitBonus>();
|
||||||
gs.ecs.register::<MoveMode>();
|
gs.ecs.register::<MoveMode>();
|
||||||
gs.ecs.register::<ProvidesHealing>();
|
gs.ecs.register::<ProvidesHealing>();
|
||||||
gs.ecs.register::<InflictsDamage>();
|
gs.ecs.register::<InflictsDamage>();
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,8 @@ use super::{
|
||||||
gamelog, gamesystem,
|
gamelog, gamesystem,
|
||||||
gui::renderable_colour,
|
gui::renderable_colour,
|
||||||
ArmourClassBonus, Attributes, EquipmentSlot, Equipped, HungerClock, HungerState, MeleeWeapon, MultiAttack, Name,
|
ArmourClassBonus, Attributes, EquipmentSlot, Equipped, HungerClock, HungerState, MeleeWeapon, MultiAttack, Name,
|
||||||
NaturalAttacks, ParticleBuilder, Pools, Position, Renderable, Skill, Skills, WantsToMelee, WeaponAttribute,
|
NaturalAttacks, ParticleBuilder, Pools, Position, Renderable, Skill, Skills, ToHitBonus, WantsToMelee,
|
||||||
|
WeaponAttribute,
|
||||||
};
|
};
|
||||||
use rltk::prelude::*;
|
use rltk::prelude::*;
|
||||||
use specs::prelude::*;
|
use specs::prelude::*;
|
||||||
|
|
@ -26,6 +27,7 @@ impl<'a> System<'a> for MeleeCombatSystem {
|
||||||
ReadStorage<'a, MeleeWeapon>,
|
ReadStorage<'a, MeleeWeapon>,
|
||||||
ReadStorage<'a, NaturalAttacks>,
|
ReadStorage<'a, NaturalAttacks>,
|
||||||
ReadStorage<'a, ArmourClassBonus>,
|
ReadStorage<'a, ArmourClassBonus>,
|
||||||
|
ReadStorage<'a, ToHitBonus>,
|
||||||
ReadStorage<'a, HungerClock>,
|
ReadStorage<'a, HungerClock>,
|
||||||
ReadStorage<'a, MultiAttack>,
|
ReadStorage<'a, MultiAttack>,
|
||||||
WriteExpect<'a, rltk::RandomNumberGenerator>,
|
WriteExpect<'a, rltk::RandomNumberGenerator>,
|
||||||
|
|
@ -47,6 +49,7 @@ impl<'a> System<'a> for MeleeCombatSystem {
|
||||||
melee_weapons,
|
melee_weapons,
|
||||||
natural_attacks,
|
natural_attacks,
|
||||||
ac,
|
ac,
|
||||||
|
to_hit,
|
||||||
hunger_clock,
|
hunger_clock,
|
||||||
multi_attackers,
|
multi_attackers,
|
||||||
mut rng,
|
mut rng,
|
||||||
|
|
@ -96,10 +99,10 @@ impl<'a> System<'a> for MeleeCombatSystem {
|
||||||
attacks.push((
|
attacks.push((
|
||||||
MeleeWeapon {
|
MeleeWeapon {
|
||||||
attribute: WeaponAttribute::Strength,
|
attribute: WeaponAttribute::Strength,
|
||||||
hit_bonus: 0,
|
|
||||||
damage_n_dice: 1,
|
damage_n_dice: 1,
|
||||||
damage_die_type: 4,
|
damage_die_type: 4,
|
||||||
damage_bonus: 0,
|
damage_bonus: 0,
|
||||||
|
hit_bonus: 0,
|
||||||
},
|
},
|
||||||
"punches".to_string(),
|
"punches".to_string(),
|
||||||
));
|
));
|
||||||
|
|
@ -124,7 +127,12 @@ impl<'a> System<'a> for MeleeCombatSystem {
|
||||||
let d20 = rng.roll_dice(1, 20);
|
let d20 = rng.roll_dice(1, 20);
|
||||||
let attribute_hit_bonus = attacker_attributes.dexterity.bonus;
|
let attribute_hit_bonus = attacker_attributes.dexterity.bonus;
|
||||||
let skill_hit_bonus = gamesystem::skill_bonus(Skill::Melee, &*attacker_skills);
|
let skill_hit_bonus = gamesystem::skill_bonus(Skill::Melee, &*attacker_skills);
|
||||||
let weapon_hit_bonus = weapon_info.hit_bonus;
|
let mut equipment_hit_bonus = weapon_info.hit_bonus;
|
||||||
|
for (wielded, to_hit) in (&equipped, &to_hit).join() {
|
||||||
|
if wielded.owner == entity {
|
||||||
|
equipment_hit_bonus += to_hit.amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
let mut status_hit_bonus = 0;
|
let mut status_hit_bonus = 0;
|
||||||
let hc = hunger_clock.get(entity);
|
let hc = hunger_clock.get(entity);
|
||||||
if let Some(hc) = hc {
|
if let Some(hc) = hc {
|
||||||
|
|
@ -141,8 +149,13 @@ impl<'a> System<'a> for MeleeCombatSystem {
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let attacker_bonuses =
|
// Total to-hit bonus
|
||||||
attacker_pools.level + attribute_hit_bonus + skill_hit_bonus + weapon_hit_bonus + status_hit_bonus;
|
let attacker_bonuses = 1 // +1 for being in melee combat
|
||||||
|
+ attacker_pools.level // + level
|
||||||
|
+ attribute_hit_bonus // +- str/dex bonus depending on weapon used
|
||||||
|
+ skill_hit_bonus // +- relevant skill modifier
|
||||||
|
+ equipment_hit_bonus // +- any other to-hit modifiers from equipment
|
||||||
|
+ status_hit_bonus; // +- any to-hit modifiers from status effects
|
||||||
|
|
||||||
// Get armour class
|
// Get armour class
|
||||||
let bac = target_pools.bac;
|
let bac = target_pools.bac;
|
||||||
|
|
@ -164,17 +177,21 @@ impl<'a> System<'a> for MeleeCombatSystem {
|
||||||
armour_class_roll = -armour_class_roll;
|
armour_class_roll = -armour_class_roll;
|
||||||
}
|
}
|
||||||
|
|
||||||
let target_number = 10 + armour_class_roll + attacker_bonuses;
|
// Monster attacks receive a +10 to-hit bonus against the player.
|
||||||
|
let monster_v_player_bonus = if wants_melee.target == *player_entity { 10 } else { 0 };
|
||||||
|
|
||||||
|
let target_number = monster_v_player_bonus + armour_class_roll + attacker_bonuses;
|
||||||
|
|
||||||
let target_name = names.get(wants_melee.target).unwrap();
|
let target_name = names.get(wants_melee.target).unwrap();
|
||||||
if COMBAT_LOGGING {
|
if COMBAT_LOGGING {
|
||||||
rltk::console::log(format!(
|
rltk::console::log(format!(
|
||||||
"ATTACKLOG: {} *{}* {}: rolled ({}) 1d20 vs. {} (10 + {}AC + {}to-hit)",
|
"ATTACKLOG: {} *{}* {}: rolled ({}) 1d20 vs. {} ({} + {}AC + {}to-hit)",
|
||||||
&name.name,
|
&name.name,
|
||||||
attack_verb,
|
attack_verb,
|
||||||
&target_name.name,
|
&target_name.name,
|
||||||
d20,
|
d20,
|
||||||
target_number,
|
target_number,
|
||||||
|
monster_v_player_bonus,
|
||||||
armour_class_roll,
|
armour_class_roll,
|
||||||
attacker_bonuses
|
attacker_bonuses
|
||||||
));
|
));
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ macro_rules! apply_effects {
|
||||||
"aoe" => $eb = $eb.with(AOE { radius: effect.1.parse::<i32>().unwrap() }),
|
"aoe" => $eb = $eb.with(AOE { radius: effect.1.parse::<i32>().unwrap() }),
|
||||||
"confusion" => $eb = $eb.with(Confusion { turns: effect.1.parse::<i32>().unwrap() }),
|
"confusion" => $eb = $eb.with(Confusion { turns: effect.1.parse::<i32>().unwrap() }),
|
||||||
"ac" => $eb = $eb.with(ArmourClassBonus { amount: effect.1.parse::<i32>().unwrap() }),
|
"ac" => $eb = $eb.with(ArmourClassBonus { amount: effect.1.parse::<i32>().unwrap() }),
|
||||||
|
"to_hit" => $eb = $eb.with(ToHitBonus { amount: effect.1.parse::<i32>().unwrap() }),
|
||||||
"particle_line" => $eb = $eb.with(parse_particle_line(&effect.1)),
|
"particle_line" => $eb = $eb.with(parse_particle_line(&effect.1)),
|
||||||
"particle_burst" => $eb = $eb.with(parse_particle_burst(&effect.1)),
|
"particle_burst" => $eb = $eb.with(parse_particle_burst(&effect.1)),
|
||||||
"particle" => $eb = $eb.with(parse_particle(&effect.1)),
|
"particle" => $eb = $eb.with(parse_particle(&effect.1)),
|
||||||
|
|
@ -230,7 +231,7 @@ pub fn spawn_named_item(
|
||||||
) -> Option<Entity> {
|
) -> Option<Entity> {
|
||||||
if raws.item_index.contains_key(key) {
|
if raws.item_index.contains_key(key) {
|
||||||
let item_template = &raws.raws.items[raws.item_index[key]];
|
let item_template = &raws.raws.items[raws.item_index[key]];
|
||||||
let dm = ecs.fetch::<crate::map::MasterDungeonMap>();
|
let mut dm = ecs.fetch_mut::<crate::map::MasterDungeonMap>();
|
||||||
let scroll_names = dm.scroll_map.clone();
|
let scroll_names = dm.scroll_map.clone();
|
||||||
let potion_names = dm.potion_map.clone();
|
let potion_names = dm.potion_map.clone();
|
||||||
let wand_names = dm.wand_map.clone();
|
let wand_names = dm.wand_map.clone();
|
||||||
|
|
@ -256,6 +257,9 @@ pub fn spawn_named_item(
|
||||||
}
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
if known_beatitude && !identified_items.contains(&item_template.name.name) {
|
||||||
|
dm.identified_items.insert(item_template.name.name.clone());
|
||||||
|
}
|
||||||
std::mem::drop(player_entity);
|
std::mem::drop(player_entity);
|
||||||
std::mem::drop(dm);
|
std::mem::drop(dm);
|
||||||
// -- DROP EVERYTHING THAT INVOLVES THE ECS BEFORE THIS POINT ---
|
// -- DROP EVERYTHING THAT INVOLVES THE ECS BEFORE THIS POINT ---
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,7 @@ pub fn save_game(ecs: &mut World) {
|
||||||
SpawnParticleSimple,
|
SpawnParticleSimple,
|
||||||
TakingTurn,
|
TakingTurn,
|
||||||
Telepath,
|
Telepath,
|
||||||
|
ToHitBonus,
|
||||||
Viewshed,
|
Viewshed,
|
||||||
Charges,
|
Charges,
|
||||||
WantsToApproach,
|
WantsToApproach,
|
||||||
|
|
@ -234,6 +235,7 @@ pub fn load_game(ecs: &mut World) {
|
||||||
SpawnParticleSimple,
|
SpawnParticleSimple,
|
||||||
TakingTurn,
|
TakingTurn,
|
||||||
Telepath,
|
Telepath,
|
||||||
|
ToHitBonus,
|
||||||
Viewshed,
|
Viewshed,
|
||||||
Charges,
|
Charges,
|
||||||
WantsToApproach,
|
WantsToApproach,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue