Let items become something else on exhaustion.
This commit is contained in:
parent
caa3d84081
commit
73d92e3074
@ -213,13 +213,35 @@ impl QueueCommandHandler for QueueHandler {
|
||||
}
|
||||
ctx.trans.save_item_model(&player_mut).await?;
|
||||
|
||||
let mut item_mut = (*item).clone();
|
||||
let mut save_item = false;
|
||||
if item.possession_type.as_ref()
|
||||
.and_then(|poss_type| possession_data().get(&poss_type))
|
||||
.and_then(|poss_data| poss_data.charge_data.as_ref()).is_some() {
|
||||
let mut item_mut = (*item).clone();
|
||||
item_mut.charges -= 1;
|
||||
ctx.trans.save_item_model(&item_mut).await?;
|
||||
save_item = true;
|
||||
}
|
||||
if item_mut.charges == 0 {
|
||||
if let Some((new_poss, new_poss_dat)) = item.possession_type.as_ref()
|
||||
.and_then(|pt| possession_data().get(pt))
|
||||
.and_then(|poss_data| poss_data.becomes_on_spent.as_ref())
|
||||
.and_then(|poss_type| possession_data().get(&poss_type)
|
||||
.map(|poss_dat| (poss_type, poss_dat)))
|
||||
{
|
||||
item_mut.possession_type = Some(new_poss.clone());
|
||||
item_mut.display = new_poss_dat.display.to_owned();
|
||||
item_mut.display_less_explicit = new_poss_dat.display_less_explicit.map(|d| d.to_owned());
|
||||
item_mut.details = Some(new_poss_dat.details.to_owned());
|
||||
item_mut.details_less_explicit = new_poss_dat.details_less_explicit.map(|d| d.to_owned());
|
||||
item_mut.aliases = new_poss_dat.aliases.iter().map(|al| (*al).to_owned()).collect();
|
||||
item_mut.health = new_poss_dat.max_health;
|
||||
item_mut.weight = new_poss_dat.weight;
|
||||
save_item = true;
|
||||
}
|
||||
}
|
||||
if save_item {
|
||||
ctx.trans.save_item_model(&item_mut).await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -2,3 +2,4 @@ pub mod session;
|
||||
pub mod user;
|
||||
pub mod item;
|
||||
pub mod task;
|
||||
pub mod consent;
|
||||
|
36
blastmud_game/src/models/consent.rs
Normal file
36
blastmud_game/src/models/consent.rs
Normal file
@ -0,0 +1,36 @@
|
||||
use serde::{Serialize, Deserialize};
|
||||
use chrono::{DateTime, Utc};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub enum ConsentType {
|
||||
Fight,
|
||||
Medicine,
|
||||
Gifts,
|
||||
Visit,
|
||||
Sex
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub enum ConsentStatus {
|
||||
PendingAdd, // Added but awaiting other party to ratify by giving matching consent.
|
||||
Active, // Consent in force, no delete pending.
|
||||
PendingDelete, // Pending cancellation but other party has to also disallow to ratify.
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct FightConsent {
|
||||
status: ConsentStatus,
|
||||
pending_change: Option<Box<Consent>>,
|
||||
allow_pick: bool,
|
||||
freely_revoke: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Consent {
|
||||
consent_type: ConsentType,
|
||||
fight_consent: Option<FightConsent>,
|
||||
expires: Option<DateTime<Utc>>,
|
||||
only_in: Vec<String>,
|
||||
allow_private: bool,
|
||||
until_death: bool,
|
||||
}
|
10
blastmud_game/src/models/corp.rs
Normal file
10
blastmud_game/src/models/corp.rs
Normal file
@ -0,0 +1,10 @@
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Corp {
|
||||
pub name: String,
|
||||
// If true, new members get allow_combat on, and members cannot turn
|
||||
// allow_combat off. This will allow duly authorised corp members to
|
||||
// consent to combat with other corps, and have it apply to members.
|
||||
pub allow_combat_required: bool,
|
||||
}
|
@ -286,6 +286,11 @@ impl Default for ActiveCombat {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, PartialOrd)]
|
||||
pub enum ItemSpecialData {
|
||||
ItemWriting { text: String }
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, PartialOrd)]
|
||||
#[serde(default)]
|
||||
pub struct Item {
|
||||
@ -314,7 +319,8 @@ pub struct Item {
|
||||
pub sex: Option<Sex>,
|
||||
pub active_combat: Option<ActiveCombat>,
|
||||
pub weight: u64,
|
||||
pub charges: u8
|
||||
pub charges: u8,
|
||||
pub special_data: Option<ItemSpecialData>,
|
||||
}
|
||||
|
||||
impl Item {
|
||||
@ -392,6 +398,7 @@ impl Default for Item {
|
||||
active_combat: Some(Default::default()),
|
||||
weight: 0,
|
||||
charges: 0,
|
||||
special_data: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
use serde::{Serialize, Deserialize};
|
||||
use crate::{
|
||||
models::item::{SkillType, Item, Pronouns}
|
||||
models::item::{SkillType, Item, ItemSpecialData, Pronouns}
|
||||
};
|
||||
use once_cell::sync::OnceCell;
|
||||
use std::collections::BTreeMap;
|
||||
use rand::seq::SliceRandom;
|
||||
use super::species::BodyPart;
|
||||
use ansi::ansi;
|
||||
|
||||
pub type AttackMessageChoice = Vec<Box<dyn Fn(&Item, &Item, bool) -> String + 'static + Sync + Send>>;
|
||||
pub type AttackMessageChoicePart = Vec<Box<dyn Fn(&Item, &Item, &BodyPart, bool) -> String + 'static + Sync + Send>>;
|
||||
@ -111,6 +112,7 @@ pub struct PossessionData {
|
||||
pub max_health: u64,
|
||||
pub charge_data: Option<ChargeData>,
|
||||
pub use_data: Option<UseData>,
|
||||
pub becomes_on_spent: Option<PossessionType>,
|
||||
pub weight: u64,
|
||||
}
|
||||
|
||||
@ -126,6 +128,7 @@ impl Default for PossessionData {
|
||||
max_health: 10,
|
||||
weight: 100,
|
||||
charge_data: None,
|
||||
becomes_on_spent: None,
|
||||
use_data: None,
|
||||
}
|
||||
}
|
||||
@ -161,6 +164,9 @@ pub enum PossessionType {
|
||||
// Real possessions from here on:
|
||||
AntennaWhip,
|
||||
MediumTraumaKit,
|
||||
EmptyMedicalBox,
|
||||
NewCorpLicence,
|
||||
CertificateOfIncorporation,
|
||||
}
|
||||
|
||||
impl Into<Item> for PossessionType {
|
||||
@ -496,6 +502,52 @@ pub fn possession_data() -> &'static BTreeMap<PossessionType, PossessionData> {
|
||||
}),
|
||||
..Default::default()
|
||||
}),
|
||||
becomes_on_spent: Some(EmptyMedicalBox),
|
||||
..Default::default()
|
||||
}),
|
||||
(EmptyMedicalBox, PossessionData {
|
||||
display: "empty medical box",
|
||||
details: "An empty box that looks like it once had something medical in it.",
|
||||
aliases: vec!("box"),
|
||||
..Default::default()
|
||||
}),
|
||||
(NewCorpLicence, PossessionData {
|
||||
display: "new corp licence",
|
||||
details: ansi!("A blank form that you can <bold>use<reset> to establish a new corp. It rests on a clipboard with a pencil attached by a chain. There is a space to <bold>write<reset> on it [try <bold>write Blah on licence<reset> followed by <bold>use licence<reset> to create a corp named Blah]"),
|
||||
aliases: vec!("form", "license", "licence", "new"),
|
||||
use_data: Some(UseData {
|
||||
uses_skill: SkillType::Persuade,
|
||||
diff_level: 4.0,
|
||||
crit_fail_effects: vec!(),
|
||||
fail_effects: vec!(),
|
||||
success_effects: vec!(
|
||||
UseEffect::BroadcastMessage {
|
||||
messagef: Box::new(|player, _item, _target| (
|
||||
format!(
|
||||
"{} signs a contract establishing Blah as a corp\n",
|
||||
&player.display_for_sentence(true, 1, true),
|
||||
),
|
||||
format!("{} signs a contract establishing Blah as a corp\n",
|
||||
&player.display_for_sentence(false, 1, true),
|
||||
)))
|
||||
},
|
||||
),
|
||||
errorf: Box::new(
|
||||
|item, _target|
|
||||
match item.special_data {
|
||||
Some(ItemSpecialData::ItemWriting { .. }) => None,
|
||||
_ => Some("You have to your corp's name on it first!".to_owned())
|
||||
}),
|
||||
..Default::default()
|
||||
}),
|
||||
weight: 10,
|
||||
becomes_on_spent: Some(CertificateOfIncorporation),
|
||||
..Default::default()
|
||||
}),
|
||||
(CertificateOfIncorporation, PossessionData {
|
||||
display: "certificate of incorporation",
|
||||
details: "A certificate recording the formation of a corp.",
|
||||
weight: 10,
|
||||
..Default::default()
|
||||
}),
|
||||
).into_iter().collect()
|
||||
|
@ -2312,10 +2312,41 @@ pub fn room_list() -> Vec<Room> {
|
||||
target: ExitTarget::UseGPS,
|
||||
exit_type: ExitType::Free
|
||||
},
|
||||
Exit {
|
||||
direction: Direction::EAST,
|
||||
target: ExitTarget::UseGPS,
|
||||
exit_type: ExitType::Free
|
||||
},
|
||||
),
|
||||
should_caption: false,
|
||||
..Default::default()
|
||||
},
|
||||
Room {
|
||||
zone: "melbs",
|
||||
secondary_zones: vec!(),
|
||||
code: "kings_office",
|
||||
name: "Kings Office",
|
||||
short: ansi!("<bgyellow><white>KO<reset>"),
|
||||
description: ansi!("A dilapidated office that clearly was once a grand governor's office under the empire. It is now barely maintained. The self-styled king slouches behind a desk in the corner, shuffling paperwork around his desk. [Use <bold>list<reset> to see contracts for sale here]"),
|
||||
description_less_explicit: None,
|
||||
grid_coords: GridCoords { x: 6, y: 5, z: 0 },
|
||||
exits: vec!(
|
||||
Exit {
|
||||
direction: Direction::WEST,
|
||||
target: ExitTarget::UseGPS,
|
||||
exit_type: ExitType::Free
|
||||
},
|
||||
),
|
||||
should_caption: true,
|
||||
stock_list: vec!(
|
||||
RoomStock {
|
||||
possession_type: PossessionType::NewCorpLicence,
|
||||
list_price: 5000,
|
||||
..Default::default()
|
||||
}
|
||||
),
|
||||
..Default::default()
|
||||
},
|
||||
Room {
|
||||
zone: "melbs",
|
||||
secondary_zones: vec!(),
|
||||
|
@ -53,3 +53,31 @@ CREATE TABLE tasks (
|
||||
CREATE UNIQUE INDEX tasks_by_code_type ON tasks((details->>'task_code'), (details->>'task_type'));
|
||||
CREATE INDEX tasks_by_static ON tasks((cast(details->>'is_static' as boolean)));
|
||||
CREATE INDEX tasks_by_scheduled ON tasks((details->>'next_scheduled'));
|
||||
|
||||
CREATE TABLE corps (
|
||||
corp_id BIGSERIAL NOT NULL PRIMARY KEY,
|
||||
details JSONB NOT NULL
|
||||
);
|
||||
CREATE INDEX corp_by_name ON corps((details->>'name'));
|
||||
CREATE TABLE corp_membership (
|
||||
corp_id BIGSERIAL NOT NULL REFERENCES corps(corp_id),
|
||||
member_username TEXT NOT NULL REFERENCES users(username),
|
||||
details JSONB NOT NULL,
|
||||
PRIMARY KEY (corp_id, member_username)
|
||||
);
|
||||
|
||||
CREATE TABLE user_consent (
|
||||
consenting_user TEXT NOT NULL REFERENCES users(username),
|
||||
consented_user TEXT NOT NULL REFERENCES users(username),
|
||||
details JSONB NOT NULL,
|
||||
PRIMARY KEY (consenting_user, consented_user)
|
||||
);
|
||||
CREATE INDEX user_consent_by_consented ON user_consent (consented_user);
|
||||
|
||||
CREATE TABLE corp_consent (
|
||||
consenting_corp BIGINT NOT NULL REFERENCES corps(corp_id),
|
||||
consented_corp BIGINT NOT NULL REFERENCES corps(corp_id),
|
||||
details JSONB NOT NULL,
|
||||
PRIMARY KEY (consenting_corp, consented_corp)
|
||||
);
|
||||
CREATE INDEX corp_consent_by_consented ON corp_consent (consented_corp);
|
||||
|
Loading…
Reference in New Issue
Block a user