jake
4 years ago
18 changed files with 1571 additions and 84 deletions
-
1Cargo.toml
-
32data/item_stats/mag_stats.toml
-
4src/entity/character.rs
-
12src/entity/gateway/entitygateway.rs
-
61src/entity/gateway/inmemory.rs
-
804src/entity/item/mag.rs
-
3src/entity/item/mod.rs
-
36src/entity/item/tool.rs
-
2src/lib.rs
-
16src/login/character.rs
-
13src/ship/drops/rare_drop_table.rs
-
53src/ship/items/inventory.rs
-
163src/ship/items/manager.rs
-
1src/ship/items/mod.rs
-
175src/ship/items/use_tool.rs
-
66src/ship/packet/handler/message.rs
-
3src/ship/ship.rs
-
210tests/test_mags.rs
@ -0,0 +1,175 @@ |
|||
use thiserror::Error;
|
|||
use crate::entity::gateway::EntityGateway;
|
|||
use crate::entity::character::CharacterEntity;
|
|||
use crate::entity::item::{ItemEntityId, ItemDetail};
|
|||
use crate::entity::item::tool::ToolType;
|
|||
use crate::entity::item::mag::MagCell;
|
|||
use crate::ship::items::{ItemManager, ClientItemId, CharacterInventory, ConsumedItem};
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
#[derive(Error, Debug)]
|
|||
#[error("")]
|
|||
pub enum UseItemError {
|
|||
NoCharacter,
|
|||
ItemNotEquipped,
|
|||
InvalidItem,
|
|||
}
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
//pub fn use_tool()
|
|||
|
|||
pub async fn power_material<EG: EntityGateway>(entity_gateway: &mut EG, character: &mut CharacterEntity) {
|
|||
character.materials.power += 1;
|
|||
entity_gateway.save_character(character).await;
|
|||
}
|
|||
|
|||
pub async fn mind_material<EG: EntityGateway>(entity_gateway: &mut EG, character: &mut CharacterEntity) {
|
|||
character.materials.mind += 1;
|
|||
entity_gateway.save_character(character).await;
|
|||
}
|
|||
|
|||
pub async fn evade_material<EG: EntityGateway>(entity_gateway: &mut EG, character: &mut CharacterEntity) {
|
|||
character.materials.evade += 1;
|
|||
entity_gateway.save_character(character).await;
|
|||
}
|
|||
|
|||
pub async fn def_material<EG: EntityGateway>(entity_gateway: &mut EG, character: &mut CharacterEntity) {
|
|||
character.materials.def += 1;
|
|||
entity_gateway.save_character(character).await;
|
|||
}
|
|||
|
|||
pub async fn luck_material<EG: EntityGateway>(entity_gateway: &mut EG, character: &mut CharacterEntity) {
|
|||
character.materials.luck += 1;
|
|||
entity_gateway.save_character(character).await;
|
|||
}
|
|||
|
|||
pub async fn hp_material<EG: EntityGateway>(entity_gateway: &mut EG, character: &mut CharacterEntity) {
|
|||
character.materials.hp += 1;
|
|||
entity_gateway.save_character(character).await;
|
|||
}
|
|||
|
|||
pub async fn tp_material<EG: EntityGateway>(entity_gateway: &mut EG, character: &mut CharacterEntity) {
|
|||
character.materials.tp += 1;
|
|||
entity_gateway.save_character(character).await;
|
|||
}
|
|||
|
|||
async fn mag_cell<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory, mag_cell_type: MagCell) -> Result<(), UseItemError> {
|
|||
let mut mag_handle = inventory.get_equipped_mag_handle().ok_or(UseItemError::ItemNotEquipped)?;
|
|||
let mag_item = mag_handle.item_mut()
|
|||
.ok_or(UseItemError::InvalidItem)?;
|
|||
let actual_mag = mag_item
|
|||
.individual()
|
|||
.ok_or(UseItemError::InvalidItem)?
|
|||
.mag_mut()
|
|||
.ok_or(UseItemError::InvalidItem)?;
|
|||
actual_mag.apply_mag_cell(mag_cell_type);
|
|||
for mag_entity_id in mag_item.entity_ids() {
|
|||
for cell_entity_id in used_cell.entity_ids() {
|
|||
entity_gateway.use_mag_cell(&mag_entity_id, &cell_entity_id).await;
|
|||
}
|
|||
}
|
|||
|
|||
Ok(())
|
|||
}
|
|||
|
|||
pub async fn cell_of_mag_502<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> {
|
|||
mag_cell(entity_gateway, used_cell, inventory, MagCell::CellOfMag502).await
|
|||
}
|
|||
|
|||
pub async fn cell_of_mag_213<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> {
|
|||
mag_cell(entity_gateway, used_cell, inventory, MagCell::CellOfMag213).await
|
|||
}
|
|||
|
|||
pub async fn parts_of_robochao<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> {
|
|||
mag_cell(entity_gateway, used_cell, inventory, MagCell::PartsOfRobochao).await
|
|||
}
|
|||
|
|||
pub async fn heart_of_opaopa<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> {
|
|||
mag_cell(entity_gateway, used_cell, inventory, MagCell::HeartOfOpaOpa).await
|
|||
}
|
|||
|
|||
pub async fn heart_of_pian<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> {
|
|||
mag_cell(entity_gateway, used_cell, inventory, MagCell::HeartOfPian).await
|
|||
}
|
|||
|
|||
pub async fn heart_of_chao<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> {
|
|||
mag_cell(entity_gateway, used_cell, inventory, MagCell::HeartOfChao).await
|
|||
}
|
|||
|
|||
pub async fn heart_of_angel<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> {
|
|||
mag_cell(entity_gateway, used_cell, inventory, MagCell::HeartOfAngel).await
|
|||
}
|
|||
|
|||
pub async fn kit_of_hamburger<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> {
|
|||
mag_cell(entity_gateway, used_cell, inventory, MagCell::KitOfHamburger).await
|
|||
}
|
|||
|
|||
pub async fn panthers_spirit<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> {
|
|||
mag_cell(entity_gateway, used_cell, inventory, MagCell::PanthersSpirit).await
|
|||
}
|
|||
|
|||
pub async fn kit_of_mark3<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> {
|
|||
mag_cell(entity_gateway, used_cell, inventory, MagCell::KitOfMark3).await
|
|||
}
|
|||
|
|||
pub async fn kit_of_master_system<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> {
|
|||
mag_cell(entity_gateway, used_cell, inventory, MagCell::KitOfMasterSystem).await
|
|||
}
|
|||
|
|||
pub async fn kit_of_genesis<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> {
|
|||
mag_cell(entity_gateway, used_cell, inventory, MagCell::KitOfGenesis).await
|
|||
}
|
|||
|
|||
pub async fn kit_of_sega_saturn<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> {
|
|||
mag_cell(entity_gateway, used_cell, inventory, MagCell::KitOfSegaSaturn).await
|
|||
}
|
|||
|
|||
pub async fn kit_of_dreamcast<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> {
|
|||
mag_cell(entity_gateway, used_cell, inventory, MagCell::KitOfDreamcast).await
|
|||
}
|
|||
|
|||
pub async fn tablet<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> {
|
|||
mag_cell(entity_gateway, used_cell, inventory, MagCell::Tablet).await
|
|||
}
|
|||
|
|||
pub async fn dragon_scale<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> {
|
|||
mag_cell(entity_gateway, used_cell, inventory, MagCell::DragonScale).await
|
|||
}
|
|||
|
|||
pub async fn heaven_striker_coat<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> {
|
|||
mag_cell(entity_gateway, used_cell, inventory, MagCell::HeavenStrikerCoat).await
|
|||
}
|
|||
|
|||
pub async fn pioneer_parts<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> {
|
|||
mag_cell(entity_gateway, used_cell, inventory, MagCell::PioneerParts).await
|
|||
}
|
|||
|
|||
pub async fn amities_memo<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> {
|
|||
mag_cell(entity_gateway, used_cell, inventory, MagCell::AmitiesMemo).await
|
|||
}
|
|||
|
|||
pub async fn heart_of_morolian<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> {
|
|||
mag_cell(entity_gateway, used_cell, inventory, MagCell::HeartOfMorolian).await
|
|||
}
|
|||
|
|||
pub async fn rappys_beak<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> {
|
|||
mag_cell(entity_gateway, used_cell, inventory, MagCell::RappysBeak).await
|
|||
}
|
|||
|
|||
pub async fn yahoos_engine<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> {
|
|||
mag_cell(entity_gateway, used_cell, inventory, MagCell::YahoosEngine).await
|
|||
}
|
|||
|
|||
pub async fn d_photon_core<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> {
|
|||
mag_cell(entity_gateway, used_cell, inventory, MagCell::DPhotonCore).await
|
|||
}
|
|||
|
|||
pub async fn liberta_kit<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> {
|
|||
mag_cell(entity_gateway, used_cell, inventory, MagCell::LibertaKit).await
|
|||
}
|
@ -0,0 +1,210 @@ |
|||
use elseware::common::serverstate::{ClientId, ServerState};
|
|||
use elseware::entity::gateway::{EntityGateway, InMemoryGateway};
|
|||
use elseware::entity::item;
|
|||
use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket};
|
|||
use elseware::entity::character::{CharacterClass, SectionID};
|
|||
|
|||
use libpso::packet::ship::*;
|
|||
use libpso::packet::messages::*;
|
|||
|
|||
#[path = "common.rs"]
|
|||
mod common;
|
|||
use common::*;
|
|||
|
|||
#[async_std::test]
|
|||
async fn test_mag_feed() {
|
|||
let mut entity_gateway = InMemoryGateway::new();
|
|||
|
|||
let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
|
|||
|
|||
entity_gateway.create_item(
|
|||
item::NewItemEntity {
|
|||
item: item::ItemDetail::Mag(
|
|||
item::mag::Mag::baby_mag(0)
|
|||
),
|
|||
location: item::ItemLocation::Inventory {
|
|||
character_id: char1.id,
|
|||
slot: 0,
|
|||
equipped: true,
|
|||
}
|
|||
}).await;
|
|||
for _ in 0..7 {
|
|||
entity_gateway.create_item(
|
|||
item::NewItemEntity {
|
|||
item: item::ItemDetail::Tool(
|
|||
item::tool::Tool {
|
|||
tool: item::tool::ToolType::Monomate,
|
|||
}
|
|||
),
|
|||
location: item::ItemLocation::Inventory {
|
|||
character_id: char1.id,
|
|||
slot: 1,
|
|||
equipped: false,
|
|||
}
|
|||
}).await;
|
|||
}
|
|||
|
|||
let mut ship = ShipServerState::builder()
|
|||
.gateway(entity_gateway.clone())
|
|||
.build();
|
|||
log_in_char(&mut ship, ClientId(1), "a1", "a").await;
|
|||
join_lobby(&mut ship, ClientId(1)).await;
|
|||
create_room(&mut ship, ClientId(1), "room", "").await;
|
|||
|
|||
for _ in 0..7 {
|
|||
ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerFeedMag(PlayerFeedMag {
|
|||
client: 0,
|
|||
target: 0,
|
|||
mag_id: 0x10000,
|
|||
item_id: 0x10001,
|
|||
})))).await.unwrap().for_each(drop);
|
|||
}
|
|||
|
|||
let p1_items = entity_gateway.get_items_by_character(&char1).await;
|
|||
let mag = p1_items.get(0).unwrap();
|
|||
match &mag.item {
|
|||
item::ItemDetail::Mag(mag) => {
|
|||
assert!(mag.level() == 7);
|
|||
assert!(mag.def() == 5);
|
|||
assert!(mag.pow() == 2);
|
|||
assert!(mag.dex() == 0);
|
|||
assert!(mag.mind() == 0);
|
|||
}
|
|||
_ => panic!()
|
|||
}
|
|||
}
|
|||
|
|||
#[async_std::test]
|
|||
async fn test_mag_change_owner() {
|
|||
let mut entity_gateway = InMemoryGateway::new();
|
|||
|
|||
let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
|
|||
let (_user2, mut char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
|
|||
char1.char_class = CharacterClass::RAmarl;
|
|||
char1.section_id = SectionID::Redria;
|
|||
entity_gateway.save_character(&char1).await;
|
|||
char2.char_class = CharacterClass::FOmarl;
|
|||
char2.section_id = SectionID::Whitill;
|
|||
entity_gateway.save_character(&char2).await;
|
|||
|
|||
entity_gateway.create_item(
|
|||
item::NewItemEntity {
|
|||
item: item::ItemDetail::Mag(
|
|||
item::mag::Mag::baby_mag(0)
|
|||
),
|
|||
location: item::ItemLocation::Inventory {
|
|||
character_id: char1.id,
|
|||
slot: 0,
|
|||
equipped: true,
|
|||
}
|
|||
}).await;
|
|||
|
|||
let mut ship = ShipServerState::builder()
|
|||
.gateway(entity_gateway.clone())
|
|||
.build();
|
|||
log_in_char(&mut ship, ClientId(1), "a1", "a").await;
|
|||
log_in_char(&mut ship, ClientId(2), "a2", "a").await;
|
|||
join_lobby(&mut ship, ClientId(1)).await;
|
|||
join_lobby(&mut ship, ClientId(2)).await;
|
|||
create_room(&mut ship, ClientId(1), "room", "").await;
|
|||
join_room(&mut ship, ClientId(2), 0).await;
|
|||
|
|||
ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem {
|
|||
client: 0,
|
|||
target: 0,
|
|||
unknown1: 0,
|
|||
map_area: 0,
|
|||
item_id: 0x10000,
|
|||
x: 0.0,
|
|||
y: 0.0,
|
|||
z: 0.0,
|
|||
})))).await.unwrap().for_each(drop);
|
|||
|
|||
ship.handle(ClientId(2), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
|
|||
client: 0,
|
|||
target: 0,
|
|||
item_id: 0x10000,
|
|||
map_area: 0,
|
|||
unknown: [0; 3]
|
|||
})))).await.unwrap().for_each(drop);
|
|||
|
|||
let p2_items = entity_gateway.get_items_by_character(&char2).await;
|
|||
let mag = p2_items.get(0).unwrap();
|
|||
match &mag.item {
|
|||
item::ItemDetail::Mag(mag) => {
|
|||
assert!(mag.class == CharacterClass::FOmarl);
|
|||
assert!(mag.id == SectionID::Whitill);
|
|||
},
|
|||
_ => panic!()
|
|||
}
|
|||
}
|
|||
|
|||
|
|||
#[async_std::test]
|
|||
async fn test_mag_cell() {
|
|||
let mut entity_gateway = InMemoryGateway::new();
|
|||
|
|||
let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
|
|||
|
|||
let mag = entity_gateway.create_item(
|
|||
item::NewItemEntity {
|
|||
item: item::ItemDetail::Mag(
|
|||
item::mag::Mag::baby_mag(0)
|
|||
),
|
|||
location: item::ItemLocation::Inventory {
|
|||
character_id: char1.id,
|
|||
slot: 0,
|
|||
equipped: true,
|
|||
}
|
|||
}).await.unwrap();
|
|||
|
|||
for _ in 0..1000 {
|
|||
let fed_tool = entity_gateway.create_item(
|
|||
item::NewItemEntity {
|
|||
item: item::ItemDetail::Tool (
|
|||
item::tool::Tool {
|
|||
tool: item::tool::ToolType::Monomate,
|
|||
}
|
|||
),
|
|||
location: item::ItemLocation::FedToMag {
|
|||
mag: mag.id,
|
|||
}
|
|||
}).await.unwrap();
|
|||
entity_gateway.feed_mag(&mag.id, &fed_tool.id).await;
|
|||
}
|
|||
entity_gateway.create_item(
|
|||
item::NewItemEntity {
|
|||
item: item::ItemDetail::Tool(
|
|||
item::tool::Tool {
|
|||
tool: item::tool::ToolType::CellOfMag502,
|
|||
}
|
|||
),
|
|||
location: item::ItemLocation::Inventory {
|
|||
character_id: char1.id,
|
|||
slot: 1,
|
|||
equipped: false,
|
|||
}
|
|||
}).await;
|
|||
|
|||
let mut ship = ShipServerState::builder()
|
|||
.gateway(entity_gateway.clone())
|
|||
.build();
|
|||
log_in_char(&mut ship, ClientId(1), "a1", "a").await;
|
|||
join_lobby(&mut ship, ClientId(1)).await;
|
|||
create_room(&mut ship, ClientId(1), "room", "").await;
|
|||
|
|||
ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerUseItem(PlayerUseItem {
|
|||
client: 0,
|
|||
target: 0,
|
|||
item_id: 0x10001,
|
|||
})))).await.unwrap().for_each(drop);
|
|||
|
|||
let p1_items = entity_gateway.get_items_by_character(&char1).await;
|
|||
let mag = p1_items.get(0).unwrap();
|
|||
match &mag.item {
|
|||
item::ItemDetail::Mag(mag) => {
|
|||
assert!(mag.mag == item::mag::MagType::Soniti);
|
|||
}
|
|||
_ => panic!()
|
|||
}
|
|||
}
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue