Implement radiation damage
This commit is contained in:
parent
5a270b50dc
commit
f37baf187e
@ -736,6 +736,7 @@ pub struct Item {
|
||||
pub total_xp: u64,
|
||||
pub urges: Option<Urges>,
|
||||
pub weight: u64,
|
||||
pub raddamage: u64,
|
||||
}
|
||||
|
||||
impl Item {
|
||||
@ -834,6 +835,7 @@ impl Default for Item {
|
||||
presence_target: None,
|
||||
pronouns: Pronouns::default_inanimate(),
|
||||
queue: VecDeque::new(),
|
||||
raddamage: 0,
|
||||
sex: None,
|
||||
special_data: None,
|
||||
static_special_data: None,
|
||||
|
@ -80,10 +80,16 @@ pub enum TaskDetails {
|
||||
ChargeItem {
|
||||
item: String,
|
||||
},
|
||||
// Environment impacting the player hidden variables
|
||||
ApplyEnvironmentalEffects {
|
||||
on_player_type: String,
|
||||
on_player_code: String,
|
||||
},
|
||||
// Player hidden variables from environment impacting health + themselves
|
||||
ApplyEnvironmentalConsequences {
|
||||
on_player_type: String,
|
||||
on_player_code: String,
|
||||
},
|
||||
}
|
||||
impl TaskDetails {
|
||||
pub fn name(self: &Self) -> &'static str {
|
||||
@ -114,6 +120,7 @@ impl TaskDetails {
|
||||
DischargeLight { .. } => "DischargeLight",
|
||||
ChargeItem { .. } => "ChargeItem",
|
||||
ApplyEnvironmentalEffects { .. } => "ApplyEnvironmentalEffects",
|
||||
ApplyEnvironmentalConsequences { .. } => "ApplyEnvironmentalConsequences",
|
||||
// Don't forget to add to TASK_HANDLER_REGISTRY in regular_tasks.rs too.
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,14 @@ fn task_handler_registry(
|
||||
("ExpireBuff", tempbuff::EXPIRE_BUFF_TASK),
|
||||
("DischargeLight", lights::DISCHARGE_TASK),
|
||||
("ChargeItem", charging::TASK_HANDLER),
|
||||
("ApplyEnvironmentalEffects", environment::TASK_HANDLER),
|
||||
(
|
||||
"ApplyEnvironmentalEffects",
|
||||
environment::EFFECT_TASK_HANDLER,
|
||||
),
|
||||
(
|
||||
"ApplyEnvironmentalConsequences",
|
||||
environment::CONSEQUENCE_TASK_HANDLER,
|
||||
),
|
||||
]
|
||||
.into_iter()
|
||||
.collect()
|
||||
|
@ -761,6 +761,7 @@ pub async fn handle_resurrect(trans: &DBTrans, player: &mut Item) -> DResult<boo
|
||||
if player.active_conversation.is_some() {
|
||||
stop_conversation_mut(trans, player, "stops talking on account of being dead").await?;
|
||||
}
|
||||
player.raddamage = 0;
|
||||
player.active_effects = vec![];
|
||||
calculate_total_stats_skills_for_user(player, &user);
|
||||
recalculate_urge_growth(trans, player).await?;
|
||||
|
@ -23,7 +23,8 @@ use crate::{
|
||||
|
||||
use super::{combat::change_health, comms::broadcast_to_room, skills::skill_check_and_grind};
|
||||
|
||||
pub struct EnvironmentHandler;
|
||||
pub struct EffectEnvironmentHandler;
|
||||
pub struct ConsequenceEnvironmentHandler;
|
||||
|
||||
pub async fn ensure_appropriate_environment_handler_after_movement(
|
||||
ctx: &mut QueuedCommandContext<'_>,
|
||||
@ -42,10 +43,12 @@ pub async fn ensure_appropriate_environment_handler_after_movement(
|
||||
None => return Ok(()),
|
||||
Some(r) => r,
|
||||
};
|
||||
match room.material_type {
|
||||
let water_effects = match room.material_type {
|
||||
MaterialType::WaterSurface | MaterialType::Underwater => true,
|
||||
_ => false,
|
||||
}
|
||||
};
|
||||
let env_effects = room.environment.radiation > 0;
|
||||
water_effects || env_effects
|
||||
};
|
||||
|
||||
let existing_task = ctx
|
||||
@ -79,7 +82,7 @@ pub async fn ensure_appropriate_environment_handler_after_movement(
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl TaskHandler for EnvironmentHandler {
|
||||
impl TaskHandler for EffectEnvironmentHandler {
|
||||
async fn do_task(&self, ctx: &mut TaskRunContext) -> DResult<Option<time::Duration>> {
|
||||
let (player_type, player_code) = match &ctx.task.details {
|
||||
TaskDetails::ApplyEnvironmentalEffects {
|
||||
@ -118,7 +121,8 @@ impl TaskHandler for EnvironmentHandler {
|
||||
Some(r) => r,
|
||||
};
|
||||
|
||||
let need_save = water_environment_effects(ctx, &room, &mut player).await?;
|
||||
let need_save = water_environment_effects(ctx, &room, &mut player).await?
|
||||
|| rad_environment_effects(ctx, &room, &mut player).await?;
|
||||
|
||||
if need_save {
|
||||
ctx.trans.save_item_model(&player).await?;
|
||||
@ -128,6 +132,56 @@ impl TaskHandler for EnvironmentHandler {
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl TaskHandler for ConsequenceEnvironmentHandler {
|
||||
async fn do_task(&self, ctx: &mut TaskRunContext) -> DResult<Option<time::Duration>> {
|
||||
let (player_type, player_code) = match &ctx.task.details {
|
||||
TaskDetails::ApplyEnvironmentalConsequences {
|
||||
on_player_type,
|
||||
on_player_code,
|
||||
} => (on_player_type, on_player_code),
|
||||
x => {
|
||||
warn!(
|
||||
"ConsequenceEnvironmentHandler called with bad TaskDetail type: {:#?}",
|
||||
x
|
||||
);
|
||||
return Ok(None);
|
||||
}
|
||||
};
|
||||
|
||||
let player = match ctx
|
||||
.trans
|
||||
.find_item_by_type_code(&player_type, &player_code)
|
||||
.await?
|
||||
{
|
||||
None => return Ok(None),
|
||||
Some(p) => p,
|
||||
};
|
||||
let mut player = (*player).clone();
|
||||
|
||||
let mut anything_left = false;
|
||||
if player.raddamage > 0 {
|
||||
if player.raddamage <= 100 {
|
||||
player.raddamage = 0;
|
||||
} else {
|
||||
anything_left = true;
|
||||
if player.raddamage > 2000 {
|
||||
let damage = (player.raddamage - 1000) / 1000;
|
||||
let msg = format!("{} feels unwell", &player.display_for_sentence(1, true));
|
||||
change_health(ctx.trans, -(damage as i64), &mut player, &msg).await?;
|
||||
}
|
||||
player.raddamage -= 100;
|
||||
}
|
||||
}
|
||||
ctx.trans.save_item_model(&player).await?;
|
||||
Ok(if anything_left {
|
||||
Some(time::Duration::from_secs(60))
|
||||
} else {
|
||||
None
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn water_environment_effects(
|
||||
ctx: &mut TaskRunContext<'_>,
|
||||
room: &Room,
|
||||
@ -194,4 +248,40 @@ pub async fn water_environment_effects(
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
pub static TASK_HANDLER: &'static (dyn TaskHandler + Sync + Send) = &EnvironmentHandler;
|
||||
pub async fn rad_environment_effects(
|
||||
ctx: &mut TaskRunContext<'_>,
|
||||
room: &Room,
|
||||
player_item: &mut Item,
|
||||
) -> DResult<bool> {
|
||||
if room.environment.radiation == 0 {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
player_item.raddamage += room.environment.radiation;
|
||||
let existing_task = ctx
|
||||
.trans
|
||||
.fetch_specific_task("ApplyEnvironmentalConsequences", &player_item.refstr())
|
||||
.await?;
|
||||
if existing_task.is_none() {
|
||||
ctx.trans
|
||||
.upsert_task(&Task {
|
||||
meta: TaskMeta {
|
||||
task_code: player_item.refstr(),
|
||||
next_scheduled: Utc::now() + chrono::TimeDelta::try_seconds(60).unwrap(),
|
||||
..Default::default()
|
||||
},
|
||||
details: TaskDetails::ApplyEnvironmentalConsequences {
|
||||
on_player_type: player_item.item_type.clone(),
|
||||
on_player_code: player_item.item_code.clone(),
|
||||
},
|
||||
})
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
pub static EFFECT_TASK_HANDLER: &'static (dyn TaskHandler + Sync + Send) =
|
||||
&EffectEnvironmentHandler;
|
||||
pub static CONSEQUENCE_TASK_HANDLER: &'static (dyn TaskHandler + Sync + Send) =
|
||||
&ConsequenceEnvironmentHandler;
|
||||
|
@ -51,6 +51,7 @@ fn room_to_simpleroom(room: &Room) -> Option<SimpleRoom<()>> {
|
||||
scavtable: room.scavtable.clone(),
|
||||
scan_code: room.scan_code.clone(),
|
||||
effects: None,
|
||||
environment: room.environment.clone(),
|
||||
extra: (),
|
||||
})
|
||||
}
|
||||
|
@ -542,6 +542,7 @@ pub struct Room {
|
||||
pub exit_trigger: Option<Box<dyn RoomExitTrigger + Sync + Send>>,
|
||||
pub sell_trigger: Option<Box<dyn RoomSellTrigger + Sync + Send>>,
|
||||
pub scavtable: ScavtableType,
|
||||
pub environment: RoomEnvironment,
|
||||
}
|
||||
|
||||
impl Default for Room {
|
||||
@ -570,10 +571,23 @@ impl Default for Room {
|
||||
exit_trigger: None,
|
||||
sell_trigger: None,
|
||||
scavtable: ScavtableType::Nothing,
|
||||
environment: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
#[serde(default)]
|
||||
pub struct RoomEnvironment {
|
||||
pub radiation: u64, // mSv/10s tick
|
||||
}
|
||||
|
||||
impl Default for RoomEnvironment {
|
||||
fn default() -> Self {
|
||||
Self { radiation: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(default)]
|
||||
pub struct SimpleRoom<T> {
|
||||
@ -601,6 +615,7 @@ pub struct SimpleRoom<T> {
|
||||
pub journal: Option<JournalType>,
|
||||
pub scavtable: ScavtableType,
|
||||
pub effects: Option<Vec<SimpleEffect>>,
|
||||
pub environment: RoomEnvironment,
|
||||
pub extra: T,
|
||||
}
|
||||
|
||||
@ -645,6 +660,7 @@ impl<T> Into<Room> for SimpleRoom<T> {
|
||||
}),
|
||||
sell_trigger: None,
|
||||
scavtable: self.scavtable,
|
||||
environment: self.environment,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -674,6 +690,7 @@ impl<'a, T: Default> Default for SimpleRoom<T> {
|
||||
scavtable: ScavtableType::Nothing,
|
||||
effects: None,
|
||||
extra: Default::default(),
|
||||
environment: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1682,6 +1682,21 @@
|
||||
stock_list:
|
||||
- possession_type: !RadSafetyTest
|
||||
list_price: 1000
|
||||
- zone: oorans
|
||||
code: oorans_gift
|
||||
name: OORANS Gift Shop
|
||||
description: |-
|
||||
A brightly coloured room, each wall a different primary colour. Rows of merchandise hang neatly on racks, while a shop keeper stands near the front, his hands clasped in anticipation of a sale
|
||||
short: <bgred><green>G$<reset>
|
||||
grid_coords:
|
||||
x: 1
|
||||
y: 1
|
||||
z: 0
|
||||
exits:
|
||||
- direction: north
|
||||
stock_list:
|
||||
- possession_type: !RadSafetyTest
|
||||
list_price: 1000
|
||||
- zone: melbs
|
||||
code: melbs_williamsst_collinsst
|
||||
name: Williams St & Collins St
|
||||
|
@ -34,6 +34,8 @@
|
||||
exits:
|
||||
- direction: north
|
||||
- direction: south
|
||||
environment:
|
||||
radiation: 50
|
||||
- zone: northern_radfields
|
||||
code: northrad_r6
|
||||
name: Outside the abandoned windfarm
|
||||
@ -46,6 +48,8 @@
|
||||
exits:
|
||||
- direction: north
|
||||
- direction: south
|
||||
environment:
|
||||
radiation: 150
|
||||
- zone: northern_radfields
|
||||
code: northrad_q6
|
||||
name: Crystal clear pond
|
||||
@ -58,6 +62,8 @@
|
||||
exits:
|
||||
- direction: northwest
|
||||
- direction: south
|
||||
environment:
|
||||
radiation: 300
|
||||
- zone: northern_radfields
|
||||
code: northrad_p5
|
||||
name: The Bend Community Hall
|
||||
@ -70,6 +76,8 @@
|
||||
exits:
|
||||
- direction: north
|
||||
- direction: southeast
|
||||
environment:
|
||||
radiation: 205
|
||||
- zone: northern_radfields
|
||||
code: northrad_o5
|
||||
name: Gorge Southbank
|
||||
@ -85,6 +93,8 @@
|
||||
height: -10
|
||||
difficulty: 10
|
||||
- direction: south
|
||||
environment:
|
||||
radiation: 150
|
||||
- zone: northern_radfields
|
||||
code: northrad_n5
|
||||
name: Gorge River
|
||||
@ -113,4 +123,3 @@
|
||||
material_type: !Underwater
|
||||
exits:
|
||||
- direction: up
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user