Make craft and fighting cause stress, and too much block them

This commit is contained in:
Condorra 2023-09-08 22:03:42 +10:00
parent 8336c5be9b
commit c054c8473a
6 changed files with 103 additions and 1 deletions

View File

@ -17,6 +17,7 @@ use crate::{
comms::broadcast_to_room,
destroy_container,
skills::skill_check_and_grind,
urges::change_stress_considering_cool,
},
static_content::possession_type::{can_butcher_possessions, possession_data},
};
@ -34,6 +35,15 @@ impl QueueCommandHandler for QueueHandler {
"You butcher things while they are dead, not while YOU are dead!".to_owned(),
)?;
}
if ctx.item.urges.as_ref().map(|u| u.stress.value).unwrap_or(0) > 7000 {
user_error(
ansi!(
"You are too tired and stressed to consider crafts. Maybe try to \
<bold>sit<reset> or <bold>recline<reset> for a bit!"
)
.to_owned(),
)?;
}
let (from_corpse_id, what_part) = match ctx.command {
QueueCommand::Cut {
from_corpse,
@ -213,6 +223,7 @@ impl QueueCommandHandler for QueueHandler {
}
if skill_check_and_grind(&ctx.trans, ctx.item, &SkillType::Craft, 10.0).await? < 0.0 {
change_stress_considering_cool(&ctx.trans, &mut ctx.item, 500).await?;
broadcast_to_room(
&ctx.trans,
&ctx.item.location,

View File

@ -12,6 +12,7 @@ use crate::{
comms::broadcast_to_room,
destroy_container,
skills::{crit_fail_penalty_for_skill, skill_check_and_grind},
urges::change_stress_considering_cool,
},
static_content::possession_type::{
improv_by_ingredient, improv_by_output, possession_data, possession_type_names,
@ -37,6 +38,16 @@ impl QueueCommandHandler for WithQueueHandler {
QueueCommand::ImprovWith { possession_id } => possession_id,
_ => user_error("Unexpected command".to_owned())?,
};
if ctx.item.urges.as_ref().map(|u| u.stress.value).unwrap_or(0) > 7000 {
user_error(
ansi!(
"You are too tired and stressed to consider crafts. Maybe try to \
<bold>sit<reset> or <bold>recline<reset> for a bit!"
)
.to_owned(),
)?;
}
let item = match ctx
.trans
.find_item_by_type_code("possession", &item_id)
@ -304,6 +315,7 @@ impl QueueCommandHandler for FromQueueHandler {
)
.await?;
if skill_result <= -0.5 {
change_stress_considering_cool(&ctx.trans, &mut ctx.item, 1000).await?;
crit_fail_penalty_for_skill(&ctx.trans, ctx.item, &craft_data.skill).await?;
ctx.trans
.delete_item(&item.item_type, &item.item_code)
@ -320,6 +332,7 @@ impl QueueCommandHandler for FromQueueHandler {
.await?;
}
} else if skill_result <= 0.0 {
change_stress_considering_cool(&ctx.trans, &mut ctx.item, 500).await?;
if let Some((sess, _)) = session {
ctx.trans
.queue_for_session(

View File

@ -11,11 +11,13 @@ use crate::{
comms::broadcast_to_room,
destroy_container,
skills::{crit_fail_penalty_for_skill, skill_check_and_grind},
urges::change_stress_considering_cool,
},
static_content::possession_type::{
possession_data, recipe_craft_by_recipe, CraftData, PossessionType,
},
};
use ansi::ansi;
use async_trait::async_trait;
use std::time;
use std::{collections::BTreeSet, sync::Arc};
@ -37,6 +39,16 @@ impl QueueCommandHandler for QueueHandler {
if ctx.item.death_data.is_some() {
user_error("The dead aren't very good at making stuff.".to_owned())?;
}
if ctx.item.urges.as_ref().map(|u| u.stress.value).unwrap_or(0) > 7000 {
user_error(
ansi!(
"You are too tired and stressed to consider crafts. Maybe try to \
<bold>sit<reset> or <bold>recline<reset> for a bit!"
)
.to_owned(),
)?;
}
let (bench_id_opt, instructions_id) = match ctx.command {
QueueCommand::Make {
ref bench_possession_id,
@ -296,6 +308,7 @@ impl QueueCommandHandler for QueueHandler {
ctx.trans
.delete_item(&item.item_type, &item.item_code)
.await?;
change_stress_considering_cool(&ctx.trans, &mut ctx.item, 1000).await?;
if let Some((sess, _)) = session {
ctx.trans
.queue_for_session(
@ -308,6 +321,7 @@ impl QueueCommandHandler for QueueHandler {
.await?;
}
} else if skill_result <= 0.0 {
change_stress_considering_cool(&ctx.trans, &mut ctx.item, 500).await?;
if let Some((sess, _)) = session {
ctx.trans
.queue_for_session(

View File

@ -660,6 +660,17 @@ impl QueueCommandHandler for QueueHandler {
QueueCommand::Movement { direction, source } => (direction, source),
_ => user_error("Unexpected command".to_owned())?,
};
if ctx.item.urges.as_ref().map(|u| u.stress.value).unwrap_or(0) > 9500 {
user_error(
ansi!(
"You are so tired and stressed you can't move. Maybe try to \
<bold>sit<reset> or <bold>recline<reset> for a bit!"
)
.to_owned(),
)?;
}
let use_location = if ctx.item.death_data.is_some() {
if ctx.item.item_type != "player" {
user_error("Dead players don't move".to_owned())?;

View File

@ -15,7 +15,7 @@ use crate::{
comms::broadcast_to_room,
destroy_container,
skills::{calculate_total_stats_skills_for_user, skill_check_and_grind, skill_check_only},
urges::recalculate_urge_growth,
urges::{change_stress_considering_cool, recalculate_urge_growth},
},
static_content::{
journals::{award_journal_if_needed, check_journal_for_kill},
@ -132,6 +132,36 @@ async fn process_attack(
attack: &WeaponAttackData,
weapon: &WeaponData,
) -> DResult<bool> {
if attacker_item
.urges
.as_ref()
.map(|u| u.stress.value)
.unwrap_or(0)
> 8000
{
let msg_exp = format!(
"{} looks like {} wanted to attack {}, but was too tired and stressed to do it.\n",
attacker_item.display_for_sentence(true, 1, false),
attacker_item.pronouns.subject,
victim_item.display_for_sentence(true, 1, true),
);
let msg_nonexp = format!(
"{} looks like {} wanted to attack {}, but was too tired and stressed to do it.\n",
attacker_item.display_for_sentence(false, 1, false),
attacker_item.pronouns.subject,
victim_item.display_for_sentence(false, 1, true),
);
broadcast_to_room(
ctx.trans,
&attacker_item.location,
None,
&msg_exp,
Some(&msg_nonexp),
)
.await?;
return Ok(false);
}
let attack_skill = *attacker_item
.total_skills
.get(&weapon.uses_skill)
@ -148,6 +178,7 @@ async fn process_attack(
} else {
None
};
let attack_result = if let Some(user) = user_opt {
let raw_skill = *user.raw_skills.get(&weapon.uses_skill).unwrap_or(&0.0);
if raw_skill >= weapon.raw_min_to_learn && raw_skill <= weapon.raw_max_to_learn {
@ -165,6 +196,8 @@ async fn process_attack(
skill_check_only(&attacker_item, &weapon.uses_skill, victim_dodge_skill)
};
change_stress_considering_cool(&ctx.trans, attacker_item, 100).await?;
if dodge_result > attack_result {
let msg_exp = format!(
"{} dodges out of the way of {}'s attack.\n",

View File

@ -345,6 +345,26 @@ pub async fn set_has_urges_if_needed(trans: &DBTrans, player_item: &mut Item) ->
Ok(())
}
pub async fn change_stress_considering_cool(
trans: &DBTrans,
who: &mut Item,
max_magnitude: i64,
) -> DResult<()> {
let cool = who.total_stats.get(&StatType::Cool).unwrap_or(&8.0);
let stress_factor = 1.0 - 1.0 / (1.0 + (-0.7 * (cool - 8.0)).exp());
match who.urges.as_mut() {
None => {}
Some(urges) => {
urges.stress.last_value = urges.stress.value;
urges.stress.value = (urges.stress.value as i64
+ (max_magnitude as f64 * stress_factor) as i64)
.max(0)
.min(10000) as u16;
}
}
stress_changed(trans, who).await
}
pub async fn recalculate_urge_growth(_trans: &DBTrans, item: &mut Item) -> DResult<()> {
let cool = item.total_stats.get(&StatType::Cool).unwrap_or(&8.0);
let relax_action_factor = match item.action_type {