Skip to content

Commit

Permalink
Started on lockers. Can put items in but can't take them out
Browse files Browse the repository at this point in the history
  • Loading branch information
sorokya committed Oct 11, 2023
1 parent 2932320 commit a17a59c
Show file tree
Hide file tree
Showing 15 changed files with 295 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/character.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use mysql_async::Conn;

use crate::{player::PlayerHandle, EXP_TABLE, SETTINGS};

mod add_bank_item;
mod add_item;
mod calculate_stats;
mod can_hold;
Expand Down
21 changes: 21 additions & 0 deletions src/character/add_bank_item.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use eo::{
data::{EOInt, EOShort},
protocol::Item,
};

use super::Character;

impl Character {
pub fn add_bank_item(&mut self, item_id: EOShort, amount: EOInt) {
let existing_item = self.bank.iter_mut().find(|item| item.id == item_id);

if let Some(existing_item) = existing_item {
existing_item.amount += amount;
} else {
self.bank.push(Item {
id: item_id,
amount,
});
}
}
}
50 changes: 50 additions & 0 deletions src/character/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@ impl Character {
)
.await?;

let old_bank = conn
.exec_map(
include_str!("../sql/get_character_bank.sql"),
params! {
"character_id" => self.id,
},
|mut row: Row| Item {
id: row.take(0).unwrap(),
amount: row.take(1).unwrap(),
},
)
.await?;

let old_spells = conn
.exec_map(
include_str!("../sql/get_character_spells.sql"),
Expand Down Expand Up @@ -194,6 +207,43 @@ impl Character {
}
}

for item in &old_bank {
if !self.bank.contains(item) {
tx.exec_drop(
include_str!("../sql/delete_bank_item.sql"),
params! {
"character_id" => self.id,
"item_id" => item.id,
},
)
.await?;
}
}

for item in &self.bank {
if !old_bank.contains(item) {
tx.exec_drop(
include_str!("../sql/create_bank_item.sql"),
params! {
"character_id" => self.id,
"item_id" => item.id,
"quantity" => item.amount,
},
)
.await?;
} else {
tx.exec_drop(
include_str!("../sql/update_bank_item.sql"),
params! {
"character_id" => self.id,
"item_id" => item.id,
"quantity" => item.amount,
},
)
.await?;
}
}

tx.commit().await?;

Ok(())
Expand Down
45 changes: 45 additions & 0 deletions src/handlers/locker.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use eo::{
data::{EOShort, StreamReader},
protocol::{Item, PacketAction},
};

use crate::{map::MapHandle, player::PlayerHandle};

fn open(player_id: EOShort, map: MapHandle) {
map.open_locker(player_id);
}

fn add(reader: StreamReader, player_id: EOShort, map: MapHandle) {
reader.seek(2);

let item = Item {
id: reader.get_short(),
amount: reader.get_three(),
};

map.add_locker_item(player_id, item);
}

pub async fn locker(action: PacketAction, reader: StreamReader, player: PlayerHandle) {
let player_id = match player.get_player_id().await {
Ok(player_id) => player_id,
Err(e) => {
error!("Failed to get player id: {}", e);
return;
}
};

let map = match player.get_map().await {
Ok(map) => map,
Err(e) => {
error!("Failed to get map: {}", e);
return;
}
};

match action {
PacketAction::Open => open(player_id, map),
PacketAction::Add => add(reader, player_id, map),
_ => error!("Unhandled packet Locker_{:?}", action),
}
}
3 changes: 3 additions & 0 deletions src/handlers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ pub use init::init;
mod item;
pub use item::item;

mod locker;
pub use locker::locker;

mod login;
pub use login::login;

Expand Down
7 changes: 7 additions & 0 deletions src/map/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ use crate::character::{Character, SpellTarget};

#[derive(Debug)]
pub enum Command {
AddLockerItem {
player_id: EOShort,
item: Item,
},
Attack {
target_player_id: EOShort,
direction: Direction,
Expand Down Expand Up @@ -113,6 +117,9 @@ pub enum Command {
target_player_id: EOShort, // TODO: rename to player_id
door_coords: Coords, // TODO: rename to coords
},
OpenLocker {
player_id: EOShort,
},
OpenShop {
player_id: EOShort,
npc_index: EOChar,
Expand Down
5 changes: 5 additions & 0 deletions src/map/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pub struct Map {
}

mod act_npcs;
mod add_locker_item;
mod attack;
mod attack_npc_replies;
mod buy_item;
Expand Down Expand Up @@ -54,6 +55,7 @@ mod leave;
mod level_stat;
mod open_chest;
mod open_door;
mod open_locker;
mod open_shop;
mod open_skill_master;
mod play_effect;
Expand Down Expand Up @@ -102,6 +104,7 @@ impl Map {

pub async fn handle_command(&mut self, command: Command) {
match command {
Command::AddLockerItem { player_id, item } => self.add_locker_item(player_id, item),
Command::Attack {
target_player_id,
direction,
Expand Down Expand Up @@ -220,6 +223,8 @@ impl Map {
door_coords,
} => self.open_door(target_player_id, door_coords),

Command::OpenLocker { player_id } => self.open_locker(player_id),

Command::OpenShop {
player_id,
npc_index,
Expand Down
77 changes: 77 additions & 0 deletions src/map/map/add_locker_item.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use std::cmp;

use eo::{
data::{EOShort, StreamBuilder},
protocol::{Coords, Item, PacketAction, PacketFamily},
pubs::EmfTileSpec,
};

use super::Map;

impl Map {
pub fn add_locker_item(&mut self, player_id: EOShort, item: Item) {
let character = match self.characters.get(&player_id) {
Some(character) => character,
None => return,
};

let adjacent_tiles = [
self.get_tile(&Coords {
x: character.coords.x,
y: character.coords.y - 1,
}),
self.get_tile(&Coords {
x: character.coords.x,
y: character.coords.y + 1,
}),
self.get_tile(&Coords {
x: character.coords.x - 1,
y: character.coords.y,
}),
self.get_tile(&Coords {
x: character.coords.x + 1,
y: character.coords.y,
}),
];

if !adjacent_tiles.iter().any(|tile| match tile {
Some(tile) => *tile == EmfTileSpec::BankVault,
None => false,
}) {
return;
}

let amount = cmp::min(character.get_item_amount(item.id), item.amount);

if amount == 0 {
return;
}

let character = match self.characters.get_mut(&player_id) {
Some(character) => character,
None => return,
};

character.remove_item(item.id, amount);
character.add_bank_item(item.id, amount);

let mut builder = StreamBuilder::new();
builder.add_short(item.id);
builder.add_int(character.get_item_amount(item.id));

let weight = character.get_weight();
builder.add_char(weight.current);
builder.add_char(weight.max);

for item in &character.bank {
builder.add_short(item.id);
builder.add_three(item.amount);
}

character.player.as_ref().unwrap().send(
PacketAction::Reply,
PacketFamily::Locker,
builder.get(),
);
}
}
10 changes: 7 additions & 3 deletions src/map/map/open_door.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@ use crate::utils::in_client_range;
use super::Map;

impl Map {
pub fn open_door(&self, target_player_id: EOShort, door_coords: Coords) {
let target = self.characters.get(&target_player_id).unwrap();
if in_client_range(&target.coords, &door_coords) {
pub fn open_door(&self, player_id: EOShort, door_coords: Coords) {
let character = match self.characters.get(&player_id) {
Some(character) => character,
None => return,
};

if in_client_range(&character.coords, &door_coords) {
let packet = door::Open {
coords: door_coords,
};
Expand Down
61 changes: 61 additions & 0 deletions src/map/map/open_locker.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
use eo::{
data::{EOShort, Serializeable, StreamBuilder},
protocol::{Coords, PacketAction, PacketFamily, ShortItem},
pubs::EmfTileSpec,
};

use super::Map;

impl Map {
pub fn open_locker(&self, player_id: EOShort) {
let character = match self.characters.get(&player_id) {
Some(character) => character,
None => return,
};

let adjacent_tiles = [
self.get_tile(&Coords {
x: character.coords.x,
y: character.coords.y - 1,
}),
self.get_tile(&Coords {
x: character.coords.x,
y: character.coords.y + 1,
}),
self.get_tile(&Coords {
x: character.coords.x - 1,
y: character.coords.y,
}),
self.get_tile(&Coords {
x: character.coords.x + 1,
y: character.coords.y,
}),
];

if adjacent_tiles.iter().any(|tile| match tile {
Some(tile) => *tile == EmfTileSpec::BankVault,
None => false,
}) {
let packet = eo::protocol::server::locker::Open {
locker_coords: character.coords,
locker_items: character
.bank
.iter()
.map(|item| ShortItem {
id: item.id,
amount: item.amount,
})
.collect(),
};

let mut builder = StreamBuilder::new();
packet.serialize(&mut builder);

character.player.as_ref().unwrap().send(
PacketAction::Open,
PacketFamily::Locker,
builder.get(),
);
}
}
}
8 changes: 8 additions & 0 deletions src/map/map_handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ impl MapHandle {
Self { tx }
}

pub fn add_locker_item(&self, player_id: EOShort, item: Item) {
let _ = self.tx.send(Command::AddLockerItem { player_id, item });
}

pub fn buy_item(&self, player_id: EOShort, item: Item, session_id: EOShort) {
let _ = self.tx.send(Command::BuyItem {
player_id,
Expand Down Expand Up @@ -205,6 +209,10 @@ impl MapHandle {
});
}

pub fn open_locker(&self, player_id: EOShort) {
let _ = self.tx.send(Command::OpenLocker { player_id });
}

pub fn open_shop(&self, player_id: EOShort, npc_index: EOChar) {
let _ = self.tx.send(Command::OpenShop {
player_id,
Expand Down
1 change: 1 addition & 0 deletions src/player/handle_packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ pub async fn handle_packet(
PacketFamily::Global => handlers::global(action, reader, player.clone()).await,
PacketFamily::Init => handlers::init(action, reader, player.clone()).await,
PacketFamily::Item => handlers::item(action, reader, player.clone()).await,
PacketFamily::Locker => handlers::locker(action, reader, player.clone()).await,
PacketFamily::Login => handlers::login(action, reader, player.clone(), world.clone()).await,
PacketFamily::NPCRange => handlers::npc_range(action, reader, player.clone()).await,
PacketFamily::Paperdoll => handlers::paperdoll(action, reader, player.clone()).await,
Expand Down
2 changes: 2 additions & 0 deletions src/sql/create_bank_item.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
INSERT INTO Bank (character_id, item_id, quantity)
VALUES (:character_id, :item_id, :quantity);
3 changes: 3 additions & 0 deletions src/sql/delete_bank_item.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
DELETE FROM Bank
WHERE character_id = :character_id
AND item_id = :item_id;
Loading

0 comments on commit a17a59c

Please sign in to comment.