This commit is contained in:
parent
7bd385d580
commit
13c6592438
@ -157,7 +157,7 @@ pub struct CharacterAppearance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct TechLevel(pub u8);
|
pub struct TechLevel(pub u8);
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
@ -167,16 +167,14 @@ pub struct CharacterTechniques {
|
|||||||
|
|
||||||
impl CharacterTechniques {
|
impl CharacterTechniques {
|
||||||
pub fn set_tech(&mut self, tech: Technique, level: TechLevel) {
|
pub fn set_tech(&mut self, tech: Technique, level: TechLevel) {
|
||||||
self.techs.insert(tech, TechLevel(level.0 - 1));
|
self.techs.insert(tech, TechLevel(level.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// from_bytes
|
|
||||||
|
|
||||||
pub fn as_bytes(&self) -> [u8; 20] {
|
pub fn as_bytes(&self) -> [u8; 20] {
|
||||||
self.techs.iter()
|
self.techs.iter()
|
||||||
.fold([0xFF; 20], |mut techlist, (tech, level)| {
|
.fold([0xFF; 20], |mut techlist, (tech, level)| {
|
||||||
let index = tech.as_value();
|
let index = tech.as_value();
|
||||||
techlist[index as usize] = level.0;
|
techlist[index as usize] = level.0 - 1;
|
||||||
techlist
|
techlist
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use futures::future::join_all;
|
use futures::future::join_all;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
use anyhow::Context;
|
||||||
use rand::SeedableRng;
|
use rand::SeedableRng;
|
||||||
use rand::distributions::{WeightedIndex, Distribution};
|
use rand::distributions::{WeightedIndex, Distribution};
|
||||||
use crate::entity::gateway::{EntityGateway, GatewayError};
|
use crate::entity::gateway::{EntityGateway, GatewayError};
|
||||||
use crate::entity::character::CharacterEntity;
|
use crate::entity::character::{CharacterEntity, TechLevel};
|
||||||
use crate::entity::item::mag::{MagCell, MagCellError};
|
use crate::entity::item::mag::{MagCell, MagCellError};
|
||||||
use crate::entity::item::tool::{Tool, ToolType};
|
use crate::entity::item::tool::{Tool, ToolType};
|
||||||
|
use crate::entity::item::tech::{TechniqueDisk, Technique};
|
||||||
use crate::entity::item::{ItemDetail, ItemEntityId};
|
use crate::entity::item::{ItemDetail, ItemEntityId};
|
||||||
use crate::ship::items::state::{ItemStateProxy, ItemStateError};
|
use crate::ship::items::state::{ItemStateProxy, ItemStateError};
|
||||||
use crate::ship::items::inventory::{InventoryItem, InventoryItemDetail};
|
use crate::ship::items::inventory::{InventoryItem, InventoryItemDetail};
|
||||||
@ -18,7 +20,7 @@ pub enum ApplyItemError {
|
|||||||
NoCharacter,
|
NoCharacter,
|
||||||
#[error("item not equipped")]
|
#[error("item not equipped")]
|
||||||
ItemNotEquipped,
|
ItemNotEquipped,
|
||||||
#[error("invalid item")]
|
#[error("could not use item invalid item")]
|
||||||
InvalidItem,
|
InvalidItem,
|
||||||
#[error("gateway error {0}")]
|
#[error("gateway error {0}")]
|
||||||
GatewayError(#[from] GatewayError),
|
GatewayError(#[from] GatewayError),
|
||||||
@ -307,6 +309,21 @@ where
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn apply_tech<'a, EG>(item_state: &mut ItemStateProxy,
|
||||||
|
entity_gateway: &mut EG,
|
||||||
|
character: &mut CharacterEntity,
|
||||||
|
_entity_id: ItemEntityId,
|
||||||
|
tech: TechniqueDisk)
|
||||||
|
-> Result<Vec<ApplyItemAction>, anyhow::Error>
|
||||||
|
where
|
||||||
|
EG: EntityGateway + ?Sized,
|
||||||
|
{
|
||||||
|
// TODO: make sure the class can learn that specific tech
|
||||||
|
character.techs.set_tech(tech.tech, TechLevel(tech.level as u8));
|
||||||
|
entity_gateway.save_character(character).await.unwrap();
|
||||||
|
Ok(vec![ApplyItemAction::UpdateCharacter(Box::new(character.clone()))])
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn apply_item<'a, EG>(item_state: &mut ItemStateProxy,
|
pub async fn apply_item<'a, EG>(item_state: &mut ItemStateProxy,
|
||||||
entity_gateway: &mut EG,
|
entity_gateway: &mut EG,
|
||||||
@ -320,7 +337,11 @@ where
|
|||||||
InventoryItemDetail::Individual(individual_item) => {
|
InventoryItemDetail::Individual(individual_item) => {
|
||||||
match individual_item.item {
|
match individual_item.item {
|
||||||
ItemDetail::Tool(tool) => apply_tool(item_state, entity_gateway, character, individual_item.entity_id, tool.tool).await,
|
ItemDetail::Tool(tool) => apply_tool(item_state, entity_gateway, character, individual_item.entity_id, tool.tool).await,
|
||||||
_ => Err(ApplyItemError::InvalidItem.into())
|
ItemDetail::TechniqueDisk(tech) => apply_tech(item_state, entity_gateway, character, individual_item.entity_id, tech).await,
|
||||||
|
_ => Err(anyhow::Error::from(ApplyItemError::InvalidItem))
|
||||||
|
.with_context(|| {
|
||||||
|
format!("item {:?}", individual_item)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
InventoryItemDetail::Stacked(stacked_item) => {
|
InventoryItemDetail::Stacked(stacked_item) => {
|
||||||
|
@ -2,6 +2,7 @@ use elseware::common::serverstate::{ClientId, ServerState};
|
|||||||
use elseware::entity::gateway::{EntityGateway, InMemoryGateway};
|
use elseware::entity::gateway::{EntityGateway, InMemoryGateway};
|
||||||
use elseware::entity::item;
|
use elseware::entity::item;
|
||||||
use elseware::ship::ship::{ShipServerState, RecvShipPacket};
|
use elseware::ship::ship::{ShipServerState, RecvShipPacket};
|
||||||
|
use elseware::entity::character::TechLevel;
|
||||||
//use elseware::ship::items::{ClientItemId, ActiveItemEntityId, HeldItemType, FloorItemType};
|
//use elseware::ship::items::{ClientItemId, ActiveItemEntityId, HeldItemType, FloorItemType};
|
||||||
|
|
||||||
use libpso::packet::ship::*;
|
use libpso::packet::ship::*;
|
||||||
@ -304,6 +305,92 @@ async fn test_jackolantern() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[async_std::test]
|
||||||
|
async fn test_use_barta_1() {
|
||||||
|
let mut entity_gateway = InMemoryGateway::default();
|
||||||
|
|
||||||
|
let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
|
||||||
|
|
||||||
|
/*
|
||||||
|
let mut p1_inv = Vec::new();
|
||||||
|
for tool in vec![item::tool::ToolType::PowerMaterial, item::tool::ToolType::].into_iter() {
|
||||||
|
let mut item = Vec::new();
|
||||||
|
for _ in 0..5usize {
|
||||||
|
item.push(entity_gateway.create_item(
|
||||||
|
item::NewItemEntity {
|
||||||
|
item: item::ItemDetail::Tool(
|
||||||
|
item::tool::Tool {
|
||||||
|
tool: tool
|
||||||
|
}
|
||||||
|
),
|
||||||
|
}).await.unwrap());
|
||||||
|
}
|
||||||
|
p1_inv.push(item::InventoryItemEntity::Stacked(item));
|
||||||
|
}*/
|
||||||
|
let inv = vec![
|
||||||
|
entity_gateway.create_item(
|
||||||
|
item::NewItemEntity {
|
||||||
|
item: item::ItemDetail::TechniqueDisk(
|
||||||
|
item::tech::TechniqueDisk {
|
||||||
|
tech: item::tech::Technique::Foie,
|
||||||
|
level: 3,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
).await.unwrap(),
|
||||||
|
entity_gateway.create_item(
|
||||||
|
item::NewItemEntity {
|
||||||
|
item: item::ItemDetail::TechniqueDisk(
|
||||||
|
item::tech::TechniqueDisk {
|
||||||
|
tech: item::tech::Technique::Barta,
|
||||||
|
level: 4,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
).await.unwrap(),
|
||||||
|
entity_gateway.create_item(
|
||||||
|
item::NewItemEntity {
|
||||||
|
item: item::ItemDetail::TechniqueDisk(
|
||||||
|
item::tech::TechniqueDisk {
|
||||||
|
tech: item::tech::Technique::Zonde,
|
||||||
|
level: 5,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
).await.unwrap()
|
||||||
|
];
|
||||||
|
|
||||||
|
entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(inv)).await.unwrap();
|
||||||
|
|
||||||
|
let mut ship = Box::new(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: 0x10000,
|
||||||
|
})))).await.unwrap();
|
||||||
|
|
||||||
|
ship.handle(ClientId(1), RecvShipPacket::Message(Message::new(GameMessage::PlayerUseItem(PlayerUseItem {
|
||||||
|
client: 0,
|
||||||
|
target: 0,
|
||||||
|
item_id: 0x10002,
|
||||||
|
})))).await.unwrap();
|
||||||
|
|
||||||
|
let characters = entity_gateway.get_characters_by_user(&user1).await.unwrap();
|
||||||
|
let char = characters[0].as_ref().unwrap();
|
||||||
|
|
||||||
|
assert_eq!(char.techs.techs.len(), 2);
|
||||||
|
assert_eq!(char.techs.techs.get(&item::tech::Technique::Foie).unwrap(), &TechLevel(3));
|
||||||
|
assert_eq!(char.techs.techs.get(&item::tech::Technique::Zonde).unwrap(), &TechLevel(5));
|
||||||
|
assert!(char.techs.techs.get(&item::tech::Technique::Barta).is_none());
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: tests for ALL ITEMS WOW
|
// TODO: tests for ALL ITEMS WOW
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user