impl grinders, fix mag pbs, fix bank thing, etc #128
@ -1479,44 +1479,52 @@ impl Weapon {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn apply_modifier(&mut self, modifier: &WeaponModifier) {
 | 
			
		||||
        if let WeaponModifier::Tekked{special, percent, grind} = modifier {
 | 
			
		||||
            match special {
 | 
			
		||||
                TekSpecialModifier::Plus => {
 | 
			
		||||
                    self.special = self.special.map(|special| {
 | 
			
		||||
                        special.rank_up()
 | 
			
		||||
                    });
 | 
			
		||||
                },
 | 
			
		||||
                TekSpecialModifier::Minus => {
 | 
			
		||||
                    self.special = self.special.map(|special| {
 | 
			
		||||
                        special.rank_down()
 | 
			
		||||
                    });
 | 
			
		||||
                },
 | 
			
		||||
                TekSpecialModifier::Neutral => {
 | 
			
		||||
                },
 | 
			
		||||
            }
 | 
			
		||||
            for i in 0..3 {
 | 
			
		||||
                self.attrs[i] = self.attrs[i].map(|mut attr| {
 | 
			
		||||
                    match percent {
 | 
			
		||||
                        TekPercentModifier::PlusPlus => {
 | 
			
		||||
                            attr.value += 10;
 | 
			
		||||
                        },
 | 
			
		||||
                        TekPercentModifier::Plus => {
 | 
			
		||||
                            attr.value += 5;
 | 
			
		||||
                        },
 | 
			
		||||
                        TekPercentModifier::MinusMinus => {
 | 
			
		||||
                            attr.value -= 10;
 | 
			
		||||
                        },
 | 
			
		||||
                        TekPercentModifier::Minus => {
 | 
			
		||||
                            attr.value -= 5;
 | 
			
		||||
                        },
 | 
			
		||||
                        TekPercentModifier::Neutral => {
 | 
			
		||||
        match modifier {
 | 
			
		||||
            WeaponModifier::Tekked{special, percent, grind} => {
 | 
			
		||||
                match special {
 | 
			
		||||
                    TekSpecialModifier::Plus => {
 | 
			
		||||
                        self.special = self.special.map(|special| {
 | 
			
		||||
                            special.rank_up()
 | 
			
		||||
                        });
 | 
			
		||||
                    },
 | 
			
		||||
                    TekSpecialModifier::Minus => {
 | 
			
		||||
                        self.special = self.special.map(|special| {
 | 
			
		||||
                            special.rank_down()
 | 
			
		||||
                        });
 | 
			
		||||
                    },
 | 
			
		||||
                    TekSpecialModifier::Neutral => {
 | 
			
		||||
                    },
 | 
			
		||||
                }
 | 
			
		||||
                for i in 0..3 {
 | 
			
		||||
                    self.attrs[i] = self.attrs[i].map(|mut attr| {
 | 
			
		||||
                        match percent {
 | 
			
		||||
                            TekPercentModifier::PlusPlus => {
 | 
			
		||||
                                attr.value += 10;
 | 
			
		||||
                            },
 | 
			
		||||
                            TekPercentModifier::Plus => {
 | 
			
		||||
                                attr.value += 5;
 | 
			
		||||
                            },
 | 
			
		||||
                            TekPercentModifier::MinusMinus => {
 | 
			
		||||
                                attr.value -= 10;
 | 
			
		||||
                            },
 | 
			
		||||
                            TekPercentModifier::Minus => {
 | 
			
		||||
                                attr.value -= 5;
 | 
			
		||||
                            },
 | 
			
		||||
                            TekPercentModifier::Neutral => {
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    attr
 | 
			
		||||
                });
 | 
			
		||||
                        attr
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
                self.grind = std::cmp::max(self.grind as i32 + grind, 0) as u8;
 | 
			
		||||
                self.tekked = true;
 | 
			
		||||
            },
 | 
			
		||||
            WeaponModifier::AddGrind {amount, ..} => {
 | 
			
		||||
                self.grind += *amount as u8;
 | 
			
		||||
            },
 | 
			
		||||
            WeaponModifier::AddPercents {..} => {
 | 
			
		||||
                // TODO
 | 
			
		||||
            }
 | 
			
		||||
            self.grind = std::cmp::max(self.grind as i32 + grind, 0) as u8;
 | 
			
		||||
            self.tekked = true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,7 @@ use crate::entity::item::mag::{MagCell, MagCellError};
 | 
			
		||||
use crate::entity::item::tool::{Tool, ToolType};
 | 
			
		||||
use crate::entity::item::tech::TechniqueDisk;
 | 
			
		||||
use crate::entity::item::{ItemDetail, ItemEntityId};
 | 
			
		||||
use crate::entity::item::weapon::WeaponModifier;
 | 
			
		||||
use crate::ship::items::state::ItemStateProxy;
 | 
			
		||||
use crate::ship::items::inventory::{InventoryItem, InventoryItemDetail};
 | 
			
		||||
 | 
			
		||||
@ -34,7 +35,7 @@ pub enum ApplyItemError {
 | 
			
		||||
pub enum ApplyItemAction {
 | 
			
		||||
    UpdateCharacter(Box<CharacterEntity>),
 | 
			
		||||
    CreateItem(ItemDetail),
 | 
			
		||||
    //TransformItem,
 | 
			
		||||
    //TransformItem(ItemDetail),
 | 
			
		||||
    //RemoveItem,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -241,6 +242,30 @@ fn jack_o_lantern() -> Result<Vec<ApplyItemAction>, anyhow::Error>
 | 
			
		||||
    Ok(vec![ApplyItemAction::CreateItem(ItemDetail::Tool(Tool {tool: mag_type}))])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async fn weapon_grind<'a, EG>(item_state: &mut ItemStateProxy,
 | 
			
		||||
                              entity_gateway: &mut EG,
 | 
			
		||||
                              character: &mut CharacterEntity,
 | 
			
		||||
                              entity_id: ItemEntityId,
 | 
			
		||||
                              grind: u32,)
 | 
			
		||||
                              -> Result<Vec<ApplyItemAction>, anyhow::Error>
 | 
			
		||||
where
 | 
			
		||||
    EG: EntityGateway + ?Sized,
 | 
			
		||||
{
 | 
			
		||||
    let modifier = WeaponModifier::AddGrind {
 | 
			
		||||
        amount: grind,
 | 
			
		||||
        grinder: entity_id,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    let mut inventory = item_state.inventory(&character.id).await?;
 | 
			
		||||
    let (weapon_entity_id, weapon) = inventory.equipped_weapon_mut()
 | 
			
		||||
        .ok_or(ApplyItemError::ItemNotEquipped)?;
 | 
			
		||||
    weapon.apply_modifier(&modifier);
 | 
			
		||||
    entity_gateway.add_weapon_modifier(&weapon_entity_id, &modifier).await?;
 | 
			
		||||
    item_state.set_inventory(inventory).await;
 | 
			
		||||
 | 
			
		||||
    Ok(Vec::new())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async fn apply_tool<'a, EG>(item_state: &mut ItemStateProxy,
 | 
			
		||||
                            entity_gateway: &mut EG,
 | 
			
		||||
                            character: &mut CharacterEntity,
 | 
			
		||||
@ -271,6 +296,9 @@ where
 | 
			
		||||
        ToolType::Antidote => Ok(Vec::new()),
 | 
			
		||||
        ToolType::Antiparalysis => Ok(Vec::new()),
 | 
			
		||||
        ToolType::TrapVision => Ok(Vec::new()),
 | 
			
		||||
        ToolType::Monogrinder => weapon_grind(item_state, entity_gateway, character, entity_id, 1).await,
 | 
			
		||||
        ToolType::Digrinder => weapon_grind(item_state, entity_gateway, character, entity_id, 2).await,
 | 
			
		||||
        ToolType::Trigrinder => weapon_grind(item_state, entity_gateway, character, entity_id, 3).await,
 | 
			
		||||
        ToolType::HuntersReport => Ok(Vec::new()),
 | 
			
		||||
        ToolType::CellOfMag502
 | 
			
		||||
            | ToolType::CellOfMag213
 | 
			
		||||
 | 
			
		||||
@ -7,6 +7,7 @@ use std::future::Future;
 | 
			
		||||
use crate::entity::character::CharacterEntityId;
 | 
			
		||||
use crate::entity::item::tool::ToolType;
 | 
			
		||||
use crate::entity::item::mag::Mag;
 | 
			
		||||
use crate::entity::item::weapon::Weapon;
 | 
			
		||||
use crate::ship::shops::{ShopItem, ArmorShopItem, ToolShopItem, WeaponShopItem};
 | 
			
		||||
use crate::ship::items::state::ItemStateError;
 | 
			
		||||
use crate::ship::items::state::{IndividualItemDetail, StackedItemDetail, AddItemResult};
 | 
			
		||||
@ -453,6 +454,18 @@ impl InventoryState {
 | 
			
		||||
            .find(|(entity_id, _)| *entity_id == mag_id)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn equipped_weapon_mut(&mut self) -> Option<(ItemEntityId, &mut Weapon)> {
 | 
			
		||||
        let weapon_id = self.equipped.weapon?;
 | 
			
		||||
        self.inventory.0
 | 
			
		||||
            .iter_mut()
 | 
			
		||||
            .filter_map(|i| {
 | 
			
		||||
                let individual = i.item.as_individual_mut()?;
 | 
			
		||||
                let entity_id = individual.entity_id;
 | 
			
		||||
                Some((entity_id, individual.as_weapon_mut()?))
 | 
			
		||||
            })
 | 
			
		||||
            .find(|(entity_id, _)| *entity_id == weapon_id)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn sort(&mut self, item_ids: &[ClientItemId]) {
 | 
			
		||||
        self.inventory.0.sort_by(|a, b| {
 | 
			
		||||
            let a_index = item_ids.iter().position(|item_id| *item_id == a.item_id);
 | 
			
		||||
 | 
			
		||||
@ -91,6 +91,14 @@ impl IndividualItemDetail {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn as_weapon_mut(&mut self) -> Option<&mut Weapon> {
 | 
			
		||||
        match &mut self.item {
 | 
			
		||||
            ItemDetail::Weapon(weapon) => Some(weapon),
 | 
			
		||||
            _ => None
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    pub fn as_client_bytes(&self) -> [u8; 16] {
 | 
			
		||||
        match &self.item {
 | 
			
		||||
            ItemDetail::Weapon(w) => w.as_bytes(),
 | 
			
		||||
 | 
			
		||||
@ -312,22 +312,6 @@ async fn test_use_barta_1() {
 | 
			
		||||
 | 
			
		||||
    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 {
 | 
			
		||||
@ -391,6 +375,76 @@ async fn test_use_barta_1() {
 | 
			
		||||
    assert!(char.techs.techs.get(&item::tech::Technique::Barta).is_none());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#[async_std::test]
 | 
			
		||||
async fn test_use_monogrinder() {
 | 
			
		||||
    let mut entity_gateway = InMemoryGateway::default();
 | 
			
		||||
 | 
			
		||||
    let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
 | 
			
		||||
 | 
			
		||||
    let saber = entity_gateway.create_item(
 | 
			
		||||
        item::NewItemEntity {
 | 
			
		||||
            item: item::ItemDetail::Weapon(
 | 
			
		||||
                item::weapon::Weapon {
 | 
			
		||||
                    weapon: item::weapon::WeaponType::Saber,
 | 
			
		||||
                    grind: 0,
 | 
			
		||||
                    special: None,
 | 
			
		||||
                    attrs: [None, None, None],
 | 
			
		||||
                    tekked: true,
 | 
			
		||||
                }
 | 
			
		||||
            ),
 | 
			
		||||
        }).await.unwrap();
 | 
			
		||||
 | 
			
		||||
    let mut grinders = Vec::new();
 | 
			
		||||
    for _ in 0..3usize {
 | 
			
		||||
        grinders.push(entity_gateway.create_item(
 | 
			
		||||
            item::NewItemEntity {
 | 
			
		||||
                item: item::ItemDetail::Tool(
 | 
			
		||||
                    item::tool::Tool {
 | 
			
		||||
                        tool: item::tool::ToolType::Monogrinder,
 | 
			
		||||
                    }
 | 
			
		||||
                ),
 | 
			
		||||
            }).await.unwrap());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let equipped = item::EquippedEntity {
 | 
			
		||||
        weapon: Some(saber.id),
 | 
			
		||||
        armor: None,
 | 
			
		||||
        shield: None,
 | 
			
		||||
        unit: [None; 4],
 | 
			
		||||
        mag: None,
 | 
			
		||||
    };
 | 
			
		||||
    entity_gateway.set_character_equips(&char1.id, &equipped).await.unwrap();
 | 
			
		||||
    entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![item::InventoryItemEntity::Individual(saber),
 | 
			
		||||
                                                                                       item::InventoryItemEntity::Stacked(grinders)])).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: 0x10001,
 | 
			
		||||
    })))).await.unwrap();
 | 
			
		||||
 | 
			
		||||
    ship.handle(ClientId(1), RecvShipPacket::Message(Message::new(GameMessage::PlayerUseItem(PlayerUseItem {
 | 
			
		||||
        client: 0,
 | 
			
		||||
        target: 0,
 | 
			
		||||
        item_id: 0x10001,
 | 
			
		||||
    })))).await.unwrap();
 | 
			
		||||
 | 
			
		||||
    let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
 | 
			
		||||
    assert_eq!(inventory_items.items.len(), 2);
 | 
			
		||||
 | 
			
		||||
    assert!(matches!(inventory_items.items[0], item::InventoryItemEntity::Individual(item::ItemEntity{ item: item::ItemDetail::Weapon(item::weapon::Weapon {grind: 2, ..}), ..})));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// TODO: tests for ALL ITEMS WOW
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user