Implement (almost) proper shopping: now you can buy stuff (but not pay for it yet)

This commit is contained in:
Nobody 2022-03-29 23:35:33 +05:00
parent 5ca48a5693
commit e4ef8a3c36
2 changed files with 41 additions and 4 deletions

View File

@ -12,7 +12,7 @@ use crate::JsonManager;
use crate::LuaManager; use crate::LuaManager;
use crate::server::LoginManager; use crate::server::LoginManager;
use std::sync::Arc; use std::sync::Arc;
use crate::subsystems::{NpcSubsystem, ShopSubsystem}; use crate::subsystems::{InventorySubsystem, NpcSubsystem, ShopSubsystem};
use crate::subsystems::misc::{PauseSubsystem, SceneSubsystem, SocialSubsystem}; use crate::subsystems::misc::{PauseSubsystem, SceneSubsystem, SocialSubsystem};
pub struct GameServer { pub struct GameServer {
@ -27,14 +27,16 @@ pub struct GameServer {
impl GameServer { impl GameServer {
pub fn new(packets_to_process_rx: mpsc::Receiver<IpcMessage>, packets_to_send_tx: mpsc::Sender<IpcMessage>) -> GameServer { pub fn new(packets_to_process_rx: mpsc::Receiver<IpcMessage>, packets_to_send_tx: mpsc::Sender<IpcMessage>) -> GameServer {
let db = Arc::new(DatabaseManager::new("sqlite://./database.db3"));
let jm = Arc::new(JsonManager::new("./data/json")); let jm = Arc::new(JsonManager::new("./data/json"));
let db = Arc::new(DatabaseManager::new("sqlite://./database.db3", jm.clone()));
let lm = LoginManager::new(db.clone(), jm.clone(), packets_to_send_tx.clone()); let lm = LoginManager::new(db.clone(), jm.clone(), packets_to_send_tx.clone());
let lum = Arc::new(LuaManager::new("./data/lua")); let lum = Arc::new(LuaManager::new("./data/lua"));
let inv = Arc::new(InventorySubsystem::new(jm.clone(), db.clone(), packets_to_send_tx.clone()));
let em = EntitySubsystem::new(lum.clone(), jm.clone(), db.clone(), packets_to_send_tx.clone()); let em = EntitySubsystem::new(lum.clone(), jm.clone(), db.clone(), packets_to_send_tx.clone());
let nt = NpcSubsystem::new(packets_to_send_tx.clone()); let nt = NpcSubsystem::new(packets_to_send_tx.clone());
let ss = ShopSubsystem::new(jm.clone(), db.clone(), packets_to_send_tx.clone()); let ss = ShopSubsystem::new(jm.clone(), db.clone(), inv.clone(), packets_to_send_tx.clone());
let scs = SceneSubsystem::new(packets_to_send_tx.clone()); let scs = SceneSubsystem::new(packets_to_send_tx.clone());
let ps = PauseSubsystem::new(packets_to_send_tx.clone()); let ps = PauseSubsystem::new(packets_to_send_tx.clone());
let socs = SocialSubsystem::new(db.clone(), packets_to_send_tx.clone()); let socs = SocialSubsystem::new(db.clone(), packets_to_send_tx.clone());

View File

@ -15,6 +15,7 @@ use packet_processor_macro::*;
use packet_processor::*; use packet_processor::*;
use serde_json::de::Read; use serde_json::de::Read;
use crate::{DatabaseManager, JsonManager, LuaManager}; use crate::{DatabaseManager, JsonManager, LuaManager};
use crate::subsystems::InventorySubsystem;
use crate::utils::{IdManager, TimeManager}; use crate::utils::{IdManager, TimeManager};
#[packet_processor( #[packet_processor(
@ -25,15 +26,17 @@ pub struct ShopSubsystem {
packets_to_send_tx: Sender<IpcMessage>, packets_to_send_tx: Sender<IpcMessage>,
json_manager: Arc<JsonManager>, json_manager: Arc<JsonManager>,
db_manager: Arc<DatabaseManager>, db_manager: Arc<DatabaseManager>,
inventory: Arc<InventorySubsystem>,
} }
impl ShopSubsystem { impl ShopSubsystem {
pub fn new(jm: Arc<JsonManager>, db: Arc<DatabaseManager>, packets_to_send_tx: Sender<IpcMessage>) -> Self { pub fn new(jm: Arc<JsonManager>, db: Arc<DatabaseManager>, inv: Arc<InventorySubsystem>, packets_to_send_tx: Sender<IpcMessage>) -> Self {
let mut ss = Self { let mut ss = Self {
packets_to_send_tx: packets_to_send_tx, packets_to_send_tx: packets_to_send_tx,
packet_callbacks: HashMap::new(), packet_callbacks: HashMap::new(),
json_manager: jm.clone(), json_manager: jm.clone(),
db_manager: db.clone(), db_manager: db.clone(),
inventory: inv.clone(),
}; };
ss.register(); ss.register();
@ -113,7 +116,39 @@ impl ShopSubsystem {
} }
fn process_buy_goods(&self, user_id: u32, metadata: &proto::PacketHead, req: &proto::BuyGoodsReq, rsp: &mut proto::BuyGoodsRsp) { fn process_buy_goods(&self, user_id: u32, metadata: &proto::PacketHead, req: &proto::BuyGoodsReq, rsp: &mut proto::BuyGoodsRsp) {
// Buying goods can produce the following packets:
// 1) Response packet
// 2) AddHintNotify (to show nice graphical image to user)
// 3) StoreItemChangeNotify for this particular item
// 4) StoreItemChangeNotify/StoreItemDelNotify depending on the currency used
// TODO: client performs checks on it's side to make sure player don't buy extra or have enough currency;
// but it's a good idea to check everything too
// Also, we don't have any 'state' yet, so we never gonna run "out of stock"
// Retrieve goods in question
let mut good = req.goods.clone().unwrap();
good.bought_num = req.buy_count;
// First, confirm buying goods
// TODO: in all the packets I've seen so far goods_list only contains one item identical to goods field. Is this always the case?
rsp.shop_type = req.shop_type;
rsp.buy_count = req.buy_count;
rsp.goods = Some(good.clone());
rsp.goods_list = vec![good.clone()];
let goods_item = good.goods_item.as_ref().unwrap();
let total_count = goods_item.count * req.buy_count;
// Ok, now add item to user's inventory and show nice graphical hint
self.inventory.add_item(user_id, metadata, goods_item.item_id, total_count, &proto::ActionReasonType::ActionReasonShop, true);
// Tell the client to update / delete currency used
// TODO!
//self.inventory.sub_item(user_id, metadata, good.goods_item.as_ref().unwrap().item_id, req.buy_count, &proto::ActionReasonType::ActionReasonShop);
} }
fn get_shop_refresh_time(&self, shop_type: u32, item_id: u32) -> u32 { fn get_shop_refresh_time(&self, shop_type: u32, item_id: u32) -> u32 {