208 lines
4.8 KiB
Rust
208 lines
4.8 KiB
Rust
use serde_cbor::{from_slice, to_vec};
|
|
use uuid::Uuid;
|
|
|
|
use postgres::transaction::Transaction;
|
|
use failure::Error;
|
|
use failure::err_msg;
|
|
|
|
// drops
|
|
use rand::prelude::*;
|
|
use rand::{thread_rng, Rng};
|
|
use rand::distributions::{WeightedIndex};
|
|
|
|
use account::Account;
|
|
use rpc::{ItemUseParams};
|
|
use cryp::{cryp_get, cryp_write};
|
|
|
|
|
|
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
|
|
pub enum ItemAction {
|
|
RerollPhysDamage,
|
|
RerollSpellDamage,
|
|
RerollStamina,
|
|
}
|
|
|
|
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
|
|
pub struct Item {
|
|
// mods: Vec<Mod>,
|
|
id: Uuid,
|
|
account: Uuid,
|
|
action: ItemAction,
|
|
}
|
|
|
|
impl Item {
|
|
pub fn new(action: ItemAction, account_id: Uuid) -> Item {
|
|
let id = Uuid::new_v4();
|
|
return Item {
|
|
id,
|
|
account: account_id,
|
|
action,
|
|
};
|
|
}
|
|
|
|
fn apply(&mut self, tx: &mut Transaction, target: Uuid) -> Result<(), Error> {
|
|
match self.action {
|
|
ItemAction::RerollStamina => revive(self, tx, target),
|
|
ItemAction::RerollPhysDamage => revive(self, tx, target),
|
|
ItemAction::RerollSpellDamage => revive(self, tx, target),
|
|
}
|
|
}
|
|
}
|
|
|
|
fn revive(item: &mut Item, tx: &mut Transaction, target: Uuid) -> Result<(), Error> {
|
|
let mut cryp = cryp_get(tx, target, item.account)?;
|
|
cryp.rez();
|
|
cryp_write(cryp, tx)?;
|
|
return Ok(());
|
|
}
|
|
|
|
pub fn item_drop(tx: &mut Transaction, account_id: Uuid) -> Result<Item, Error> {
|
|
let mut rng = thread_rng();
|
|
|
|
let actions = [
|
|
(ItemAction::RerollStamina, 1),
|
|
(ItemAction::RerollPhysDamage, 1),
|
|
(ItemAction::RerollSpellDamage, 1)
|
|
];
|
|
|
|
let dist = WeightedIndex::new(actions.iter().map(|item| item.1)).unwrap();
|
|
let kind = actions[dist.sample(&mut rng)].0;
|
|
let item = Item::new(kind, account_id);
|
|
|
|
println!("{:?} dropped {:?}", account_id, item);
|
|
|
|
return item_create(item, tx, account_id);
|
|
}
|
|
|
|
|
|
pub fn item_create(item: Item, tx: &mut Transaction, account_id: Uuid) -> Result<Item, Error> {
|
|
let item_bytes = to_vec(&item)?;
|
|
|
|
let query = "
|
|
INSERT INTO items (id, account, data)
|
|
VALUES ($1, $2, $3)
|
|
RETURNING id, account, data;
|
|
";
|
|
|
|
let result = tx
|
|
.query(query, &[&item.id, &account_id, &item_bytes])?;
|
|
|
|
result.iter().next().expect("no row returned");
|
|
|
|
println!("{:?} wrote item {:}", account_id, item.id);
|
|
|
|
return Ok(item);
|
|
}
|
|
|
|
pub fn item_use(params: ItemUseParams, tx: &mut Transaction, account: &Account) -> Result<(), Error> {
|
|
let query = "
|
|
SELECT data
|
|
FROM items
|
|
WHERE id = $1
|
|
AND account = $2
|
|
FOR UPDATE;
|
|
";
|
|
|
|
let result = tx
|
|
.query(query, &[¶ms.item, &account.id])?;
|
|
|
|
let returned = result.iter().next().expect("no row returned");
|
|
|
|
let item_bytes: Vec<u8> = returned.get(0);
|
|
let mut item = from_slice::<Item>(&item_bytes)?;
|
|
|
|
item.apply(tx, params.target)?;
|
|
item_delete(tx, params.item)?;
|
|
|
|
return Ok(());
|
|
}
|
|
|
|
pub fn item_delete(tx: &mut Transaction, id: Uuid) -> Result<(), Error> {
|
|
let query = "
|
|
DELETE
|
|
FROM items
|
|
WHERE id = $1;
|
|
";
|
|
|
|
let result = tx
|
|
.execute(query, &[&id])?;
|
|
|
|
if result != 1 {
|
|
return Err(format_err!("unable to delete item {:?}", id));
|
|
}
|
|
|
|
println!("invalid item deleted {:?}", id);
|
|
|
|
return Ok(());
|
|
}
|
|
|
|
pub fn items_list(tx: &mut Transaction, account: &Account) -> Result<Vec<Item>, Error> {
|
|
let query = "
|
|
SELECT data, id
|
|
FROM items
|
|
WHERE account = $1;
|
|
";
|
|
|
|
let result = tx
|
|
.query(query, &[&account.id])?;
|
|
|
|
let mut items = vec![];
|
|
|
|
for row in result.into_iter() {
|
|
let item_bytes: Vec<u8> = row.get(0);
|
|
let id = row.get(1);
|
|
|
|
match from_slice::<Item>(&item_bytes) {
|
|
Ok(i) => items.push(i),
|
|
Err(_e) => {
|
|
item_delete(tx, id)?;
|
|
}
|
|
};
|
|
}
|
|
|
|
return Ok(items);
|
|
}
|
|
|
|
// # max damage potion
|
|
// name
|
|
|
|
// "MapMonstersCurseEffectOnSelfFinal3": {
|
|
// "adds_tags": [],
|
|
// "domain": "area",
|
|
// "generation_type": "prefix",
|
|
// "generation_weights": [],
|
|
// "grants_buff": {},
|
|
// "grants_effect": {},
|
|
// "group": "MapHexproof",
|
|
// "is_essence_only": false,
|
|
// "name": "Hexwarded",
|
|
// "required_level": 1,
|
|
// "spawn_weights": [
|
|
// {
|
|
// "tag": "top_tier_map",
|
|
// "weight": 0
|
|
// },
|
|
// {
|
|
// "tag": "default",
|
|
// "weight": 0
|
|
// }
|
|
// ],
|
|
// "stats": [
|
|
// {
|
|
// "id": "map_item_drop_quantity_+%",
|
|
// "max": 15,
|
|
// "min": 15
|
|
// },
|
|
// {
|
|
// "id": "map_item_drop_rarity_+%",
|
|
// "max": 8,
|
|
// "min": 8
|
|
// },
|
|
// {
|
|
// "id": "map_monsters_curse_effect_on_self_+%_final",
|
|
// "max": -60,
|
|
// "min": -60
|
|
// }
|
|
// ]
|
|
// },
|