Bugfixes + don't get to keep items when you die.

This commit is contained in:
Condorra 2023-01-25 23:59:19 +11:00
parent e6e712e255
commit 2d9fcf9850
4 changed files with 35 additions and 13 deletions

View File

@ -164,14 +164,14 @@ impl DBPool {
pub async fn delete_static_items_by_type(self: &Self, item_type: &str) -> DResult<()> {
self.get_conn().await?.query(
"DELETE FROM items WHERE details->>'is_static' = 'true' AND details->>'item_type' = {}",
"DELETE FROM items WHERE details->>'is_static' = 'true' AND details->>'item_type' = $1",
&[&item_type]).await?;
Ok(())
}
pub async fn delete_static_tasks_by_type(self: &Self, task_type: &str) -> DResult<()> {
self.get_conn().await?.query(
"DELETE FROM tasks WHERE details->>'is_static' = 'true' AND details->>'task_type' = {}",
"DELETE FROM tasks WHERE details->>'is_static' = 'true' AND details->>'task_type' = $1",
&[&task_type]).await?;
Ok(())
}
@ -418,6 +418,21 @@ impl DBTrans {
Ok(None)
}
pub async fn transfer_all_possessions_code(self: &Self, src_loc: &str, dst_loc: &str) -> DResult<()> {
self.pg_trans()?.execute(
"UPDATE items SET details=JSONB_SET(details, '{location}', $1) \
WHERE details->>'location' = $2",
&[&serde_json::to_value(dst_loc)?, &src_loc]).await?;
Ok(())
}
pub async fn transfer_all_possessions(self: &Self, source: &Item, dest: &Item) -> DResult<()> {
let src_loc = format!("{}/{}", &source.item_type, &source.item_code);
let dst_loc = format!("{}/{}", &dest.item_type, &dest.item_code);
self.transfer_all_possessions_code(&src_loc, &dst_loc).await?;
Ok(())
}
pub async fn find_items_by_location(self: &Self, location: &str) -> DResult<Vec<Arc<Item>>> {
Ok(self.pg_trans()?.query(
"SELECT details FROM items WHERE details->>'location' = $1 \
@ -432,19 +447,19 @@ impl DBTrans {
pub async fn save_item_model(self: &Self, details: &Item)
-> DResult<()> {
self.pg_trans()?
.execute("UPDATE items SET details = $1 WHERE \
details->>'item_type' = $2 AND \
details->>'item_code' = $3",
&[&serde_json::to_value(details)?,
&details.item_type, &details.item_code]).await?;
.execute("INSERT INTO items (details) VALUES ($1) \
ON CONFLICT ((details->>'item_type'), \
(details->>'item_code')) DO UPDATE SET \
details = EXCLUDED.details",
&[&serde_json::to_value(details)?]).await?;
Ok(())
}
pub async fn delete_item(self: &Self, item_type: &str, item_code: &str) -> DResult<()> {
self.pg_trans()?
.execute("DELETE FROM items WHERE \
details->>'item_type' = $2 AND \
details->>'item_code' = $3",
details->>'item_type' = $1 AND \
details->>'item_code' = $2",
&[&item_type, &item_code]).await?;
Ok(())
}
@ -574,7 +589,7 @@ impl DBTrans {
}
pub async fn alloc_item_code(&self) -> DResult<i64> {
Ok(self.pg_trans()?.query_one("SELECT NEXTVAL('item_seq')", &[]).await?.get(1))
Ok(self.pg_trans()?.query_one("SELECT NEXTVAL('item_seq')", &[]).await?.get(0))
}
pub async fn commit(mut self: Self) -> DResult<()> {

View File

@ -113,8 +113,8 @@ impl TaskHandler for AttackTaskHandler {
broadcast_to_room(ctx.trans, &attacker_item.location, None, &msg_exp, Some(&msg_nonexp)).await?;
victim_item.health = new_health;
if new_health == 0 {
handle_death(ctx.trans, &mut victim_item).await?;
ctx.trans.save_item_model(&attacker_item).await?;
handle_death(ctx.trans, &mut victim_item).await?;
ctx.trans.save_item_model(&victim_item).await?;
return Ok(None);
}
@ -306,6 +306,7 @@ pub async fn corpsify_item(trans: &DBTrans, base_item: &Item) -> DResult<()> {
let mut new_item = base_item.clone();
new_item.item_type = "corpse".to_owned();
new_item.item_code = format!("{}", trans.alloc_item_code().await?);
new_item.is_static = false;
trans.save_item_model(&new_item).await?;
trans.upsert_task(&Task {
meta: TaskMeta {
@ -315,6 +316,8 @@ pub async fn corpsify_item(trans: &DBTrans, base_item: &Item) -> DResult<()> {
},
details: TaskDetails::RotCorpse { corpse_code: new_item.item_code.clone() }
}).await?;
trans.transfer_all_possessions(base_item, &new_item).await?;
Ok(())
}
@ -367,6 +370,9 @@ impl TaskHandler for RotCorpseTaskHandler {
corpse.display_for_sentence(true, 1, true));
let msg_nonexp = format!("{} rots away to nothing.\n",
corpse.display_for_sentence(false, 1, true));
ctx.trans.transfer_all_possessions_code(
&format!("{}/{}", &corpse.item_type, &corpse.item_code),
&corpse.location).await?;
broadcast_to_room(ctx.trans, &corpse.location, None, &msg_exp, Some(&msg_nonexp)).await?;
Ok(None)
}

View File

@ -203,7 +203,7 @@ pub async fn skill_check_and_grind(trans: &DBTrans, who: &mut Item, skill: &Skil
return Ok(result)
}
user.raw_skills.entry(skill.clone()).and_modify(|raw| *raw += 0.01).or_insert(0.01);
user.last_skill_improve.insert(skill.clone(), Utc::now());
trans.queue_for_session(&sess,
Some(&format!("Your raw {} is now {:.2}\n",
skill.display(), user.raw_skills

View File

@ -82,7 +82,7 @@ impl Default for NPC {
message_handler: None,
aliases: vec!(),
says: vec!(),
total_skills: SkillType::values().into_iter().map(|sk| (sk, 8.0)).collect(),
total_skills: SkillType::values().into_iter().map(|sk| (sk, 10.0)).collect(),
attackable: false,
intrinsic_weapon: None,
species: SpeciesType::Human,
@ -144,6 +144,7 @@ pub fn npc_static_items() -> Box<dyn Iterator<Item = StaticItem>> {
pronouns: c.pronouns.clone(),
is_challenge_attack_only: !c.attackable,
total_skills: c.total_skills.clone(),
species: c.species.clone(),
aliases: c.aliases.iter().map(|a| (*a).to_owned()).collect::<Vec<String>>(),
..Item::default()
})