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