Implement radiation damage
This commit is contained in:
parent
5a270b50dc
commit
f37baf187e
@ -736,6 +736,7 @@ pub struct Item {
|
|||||||
pub total_xp: u64,
|
pub total_xp: u64,
|
||||||
pub urges: Option<Urges>,
|
pub urges: Option<Urges>,
|
||||||
pub weight: u64,
|
pub weight: u64,
|
||||||
|
pub raddamage: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Item {
|
impl Item {
|
||||||
@ -834,6 +835,7 @@ impl Default for Item {
|
|||||||
presence_target: None,
|
presence_target: None,
|
||||||
pronouns: Pronouns::default_inanimate(),
|
pronouns: Pronouns::default_inanimate(),
|
||||||
queue: VecDeque::new(),
|
queue: VecDeque::new(),
|
||||||
|
raddamage: 0,
|
||||||
sex: None,
|
sex: None,
|
||||||
special_data: None,
|
special_data: None,
|
||||||
static_special_data: None,
|
static_special_data: None,
|
||||||
|
@ -80,10 +80,16 @@ pub enum TaskDetails {
|
|||||||
ChargeItem {
|
ChargeItem {
|
||||||
item: String,
|
item: String,
|
||||||
},
|
},
|
||||||
|
// Environment impacting the player hidden variables
|
||||||
ApplyEnvironmentalEffects {
|
ApplyEnvironmentalEffects {
|
||||||
on_player_type: String,
|
on_player_type: String,
|
||||||
on_player_code: String,
|
on_player_code: String,
|
||||||
},
|
},
|
||||||
|
// Player hidden variables from environment impacting health + themselves
|
||||||
|
ApplyEnvironmentalConsequences {
|
||||||
|
on_player_type: String,
|
||||||
|
on_player_code: String,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
impl TaskDetails {
|
impl TaskDetails {
|
||||||
pub fn name(self: &Self) -> &'static str {
|
pub fn name(self: &Self) -> &'static str {
|
||||||
@ -114,6 +120,7 @@ impl TaskDetails {
|
|||||||
DischargeLight { .. } => "DischargeLight",
|
DischargeLight { .. } => "DischargeLight",
|
||||||
ChargeItem { .. } => "ChargeItem",
|
ChargeItem { .. } => "ChargeItem",
|
||||||
ApplyEnvironmentalEffects { .. } => "ApplyEnvironmentalEffects",
|
ApplyEnvironmentalEffects { .. } => "ApplyEnvironmentalEffects",
|
||||||
|
ApplyEnvironmentalConsequences { .. } => "ApplyEnvironmentalConsequences",
|
||||||
// Don't forget to add to TASK_HANDLER_REGISTRY in regular_tasks.rs too.
|
// 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),
|
("ExpireBuff", tempbuff::EXPIRE_BUFF_TASK),
|
||||||
("DischargeLight", lights::DISCHARGE_TASK),
|
("DischargeLight", lights::DISCHARGE_TASK),
|
||||||
("ChargeItem", charging::TASK_HANDLER),
|
("ChargeItem", charging::TASK_HANDLER),
|
||||||
("ApplyEnvironmentalEffects", environment::TASK_HANDLER),
|
(
|
||||||
|
"ApplyEnvironmentalEffects",
|
||||||
|
environment::EFFECT_TASK_HANDLER,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"ApplyEnvironmentalConsequences",
|
||||||
|
environment::CONSEQUENCE_TASK_HANDLER,
|
||||||
|
),
|
||||||
]
|
]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.collect()
|
.collect()
|
||||||
|
@ -761,6 +761,7 @@ pub async fn handle_resurrect(trans: &DBTrans, player: &mut Item) -> DResult<boo
|
|||||||
if player.active_conversation.is_some() {
|
if player.active_conversation.is_some() {
|
||||||
stop_conversation_mut(trans, player, "stops talking on account of being dead").await?;
|
stop_conversation_mut(trans, player, "stops talking on account of being dead").await?;
|
||||||
}
|
}
|
||||||
|
player.raddamage = 0;
|
||||||
player.active_effects = vec![];
|
player.active_effects = vec![];
|
||||||
calculate_total_stats_skills_for_user(player, &user);
|
calculate_total_stats_skills_for_user(player, &user);
|
||||||
recalculate_urge_growth(trans, player).await?;
|
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};
|
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(
|
pub async fn ensure_appropriate_environment_handler_after_movement(
|
||||||
ctx: &mut QueuedCommandContext<'_>,
|
ctx: &mut QueuedCommandContext<'_>,
|
||||||
@ -42,10 +43,12 @@ pub async fn ensure_appropriate_environment_handler_after_movement(
|
|||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
Some(r) => r,
|
Some(r) => r,
|
||||||
};
|
};
|
||||||
match room.material_type {
|
let water_effects = match room.material_type {
|
||||||
MaterialType::WaterSurface | MaterialType::Underwater => true,
|
MaterialType::WaterSurface | MaterialType::Underwater => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
};
|
||||||
|
let env_effects = room.environment.radiation > 0;
|
||||||
|
water_effects || env_effects
|
||||||
};
|
};
|
||||||
|
|
||||||
let existing_task = ctx
|
let existing_task = ctx
|
||||||
@ -79,7 +82,7 @@ pub async fn ensure_appropriate_environment_handler_after_movement(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl TaskHandler for EnvironmentHandler {
|
impl TaskHandler for EffectEnvironmentHandler {
|
||||||
async fn do_task(&self, ctx: &mut TaskRunContext) -> DResult<Option<time::Duration>> {
|
async fn do_task(&self, ctx: &mut TaskRunContext) -> DResult<Option<time::Duration>> {
|
||||||
let (player_type, player_code) = match &ctx.task.details {
|
let (player_type, player_code) = match &ctx.task.details {
|
||||||
TaskDetails::ApplyEnvironmentalEffects {
|
TaskDetails::ApplyEnvironmentalEffects {
|
||||||
@ -118,7 +121,8 @@ impl TaskHandler for EnvironmentHandler {
|
|||||||
Some(r) => r,
|
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 {
|
if need_save {
|
||||||
ctx.trans.save_item_model(&player).await?;
|
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(
|
pub async fn water_environment_effects(
|
||||||
ctx: &mut TaskRunContext<'_>,
|
ctx: &mut TaskRunContext<'_>,
|
||||||
room: &Room,
|
room: &Room,
|
||||||
@ -194,4 +248,40 @@ pub async fn water_environment_effects(
|
|||||||
Ok(true)
|
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(),
|
scavtable: room.scavtable.clone(),
|
||||||
scan_code: room.scan_code.clone(),
|
scan_code: room.scan_code.clone(),
|
||||||
effects: None,
|
effects: None,
|
||||||
|
environment: room.environment.clone(),
|
||||||
extra: (),
|
extra: (),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -542,6 +542,7 @@ pub struct Room {
|
|||||||
pub exit_trigger: Option<Box<dyn RoomExitTrigger + Sync + Send>>,
|
pub exit_trigger: Option<Box<dyn RoomExitTrigger + Sync + Send>>,
|
||||||
pub sell_trigger: Option<Box<dyn RoomSellTrigger + Sync + Send>>,
|
pub sell_trigger: Option<Box<dyn RoomSellTrigger + Sync + Send>>,
|
||||||
pub scavtable: ScavtableType,
|
pub scavtable: ScavtableType,
|
||||||
|
pub environment: RoomEnvironment,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Room {
|
impl Default for Room {
|
||||||
@ -570,10 +571,23 @@ impl Default for Room {
|
|||||||
exit_trigger: None,
|
exit_trigger: None,
|
||||||
sell_trigger: None,
|
sell_trigger: None,
|
||||||
scavtable: ScavtableType::Nothing,
|
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)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub struct SimpleRoom<T> {
|
pub struct SimpleRoom<T> {
|
||||||
@ -601,6 +615,7 @@ pub struct SimpleRoom<T> {
|
|||||||
pub journal: Option<JournalType>,
|
pub journal: Option<JournalType>,
|
||||||
pub scavtable: ScavtableType,
|
pub scavtable: ScavtableType,
|
||||||
pub effects: Option<Vec<SimpleEffect>>,
|
pub effects: Option<Vec<SimpleEffect>>,
|
||||||
|
pub environment: RoomEnvironment,
|
||||||
pub extra: T,
|
pub extra: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -645,6 +660,7 @@ impl<T> Into<Room> for SimpleRoom<T> {
|
|||||||
}),
|
}),
|
||||||
sell_trigger: None,
|
sell_trigger: None,
|
||||||
scavtable: self.scavtable,
|
scavtable: self.scavtable,
|
||||||
|
environment: self.environment,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -674,6 +690,7 @@ impl<'a, T: Default> Default for SimpleRoom<T> {
|
|||||||
scavtable: ScavtableType::Nothing,
|
scavtable: ScavtableType::Nothing,
|
||||||
effects: None,
|
effects: None,
|
||||||
extra: Default::default(),
|
extra: Default::default(),
|
||||||
|
environment: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1682,6 +1682,21 @@
|
|||||||
stock_list:
|
stock_list:
|
||||||
- possession_type: !RadSafetyTest
|
- possession_type: !RadSafetyTest
|
||||||
list_price: 1000
|
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
|
- zone: melbs
|
||||||
code: melbs_williamsst_collinsst
|
code: melbs_williamsst_collinsst
|
||||||
name: Williams St & Collins St
|
name: Williams St & Collins St
|
||||||
|
@ -34,6 +34,8 @@
|
|||||||
exits:
|
exits:
|
||||||
- direction: north
|
- direction: north
|
||||||
- direction: south
|
- direction: south
|
||||||
|
environment:
|
||||||
|
radiation: 50
|
||||||
- zone: northern_radfields
|
- zone: northern_radfields
|
||||||
code: northrad_r6
|
code: northrad_r6
|
||||||
name: Outside the abandoned windfarm
|
name: Outside the abandoned windfarm
|
||||||
@ -46,6 +48,8 @@
|
|||||||
exits:
|
exits:
|
||||||
- direction: north
|
- direction: north
|
||||||
- direction: south
|
- direction: south
|
||||||
|
environment:
|
||||||
|
radiation: 150
|
||||||
- zone: northern_radfields
|
- zone: northern_radfields
|
||||||
code: northrad_q6
|
code: northrad_q6
|
||||||
name: Crystal clear pond
|
name: Crystal clear pond
|
||||||
@ -58,6 +62,8 @@
|
|||||||
exits:
|
exits:
|
||||||
- direction: northwest
|
- direction: northwest
|
||||||
- direction: south
|
- direction: south
|
||||||
|
environment:
|
||||||
|
radiation: 300
|
||||||
- zone: northern_radfields
|
- zone: northern_radfields
|
||||||
code: northrad_p5
|
code: northrad_p5
|
||||||
name: The Bend Community Hall
|
name: The Bend Community Hall
|
||||||
@ -70,6 +76,8 @@
|
|||||||
exits:
|
exits:
|
||||||
- direction: north
|
- direction: north
|
||||||
- direction: southeast
|
- direction: southeast
|
||||||
|
environment:
|
||||||
|
radiation: 205
|
||||||
- zone: northern_radfields
|
- zone: northern_radfields
|
||||||
code: northrad_o5
|
code: northrad_o5
|
||||||
name: Gorge Southbank
|
name: Gorge Southbank
|
||||||
@ -85,6 +93,8 @@
|
|||||||
height: -10
|
height: -10
|
||||||
difficulty: 10
|
difficulty: 10
|
||||||
- direction: south
|
- direction: south
|
||||||
|
environment:
|
||||||
|
radiation: 150
|
||||||
- zone: northern_radfields
|
- zone: northern_radfields
|
||||||
code: northrad_n5
|
code: northrad_n5
|
||||||
name: Gorge River
|
name: Gorge River
|
||||||
@ -113,4 +123,3 @@
|
|||||||
material_type: !Underwater
|
material_type: !Underwater
|
||||||
exits:
|
exits:
|
||||||
- direction: up
|
- direction: up
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user