diff --git a/.drone.yml b/.drone.yml index ac685b1..ae267b5 100644 --- a/.drone.yml +++ b/.drone.yml @@ -9,16 +9,31 @@ concurrency: steps: - name: build image: rustlang/rust:nightly + volumes: + - name: cache + path: /usr/local/cargo + - name: target-cache + path: /drone/src/target commands: - cargo build - name: clippy! image: rustlang/rust:nightly + volumes: + - name: cache + path: /usr/local/cargo + - name: target-cache + path: /drone/src/target commands: - cargo clippy -- --deny warnings - name: test image: rustlang/rust:nightly + volumes: + - name: cache + path: /usr/local/cargo + - name: target-cache + path: /drone/src/target commands: - - cargo test --jobs 1 + - cargo test volumes: - name: cache diff --git a/drops/src/lib.rs b/drops/src/lib.rs index bccffd4..c7c76d0 100644 --- a/drops/src/lib.rs +++ b/drops/src/lib.rs @@ -98,7 +98,7 @@ impl ItemDropType { .or_else(|_| mag::MagType::parse_type([data[0],data[1],data[2]]).map(ItemType::Mag)) .or_else(|_| tool::ToolType::parse_type([data[0],data[1],data[2]]).map(ItemType::Tool)) .or_else(|_| esweapon::ESWeaponType::parse_type([data[0],data[1],data[2]]).map(ItemType::ESWeapon)).ok()?; - + match item_type { ItemType::Weapon(_w) => Some(ItemDropType::Weapon(weapon::Weapon::from_bytes(data).ok()?)), ItemType::Armor(_a) => Some(ItemDropType::Armor(armor::Armor::from_bytes(data).ok()?)), @@ -121,7 +121,12 @@ pub struct ItemDrop { } -pub struct DropTable { +pub trait DropTable { + fn get_drop(&mut self, map_area: &MapArea, monster: &MonsterType) -> Option; + fn get_box_drop(&mut self, map_area: &MapArea, object: &MapObject) -> Option; +} + +pub struct StandardDropTable { monster_stats: HashMap, rare_table: RareDropTable, weapon_table: GenericWeaponTable, @@ -133,11 +138,11 @@ pub struct DropTable { rng: rand_chacha::ChaCha20Rng, } -impl DropTable { - pub fn new(episode: Episode, difficulty: Difficulty, section_id: SectionID) -> DropTable { +impl StandardDropTable { + pub fn new(episode: Episode, difficulty: Difficulty, section_id: SectionID) -> Box { let monster_stats: HashMap = load_data_file(episode, difficulty, section_id, "monster_dar.toml"); - - DropTable { + + Box::new(StandardDropTable { monster_stats: monster_stats.into_iter().map(|(m, s)| (m.parse().unwrap(), s)).collect(), rare_table: RareDropTable::new(episode, difficulty, section_id), weapon_table: GenericWeaponTable::new(episode, difficulty, section_id), @@ -147,7 +152,7 @@ impl DropTable { tool_table: ToolTable::new(episode, difficulty, section_id), box_table: BoxDropTable::new(episode, difficulty, section_id), rng: rand_chacha::ChaCha20Rng::from_entropy(), - } + }) } pub fn builder() -> DropTableBuilder { @@ -177,8 +182,10 @@ impl DropTable { MonsterDropType::None => None, } } +} - pub fn get_drop(&mut self, map_area: &MapArea, monster: &MonsterType) -> Option { +impl DropTable for StandardDropTable { + fn get_drop(&mut self, map_area: &MapArea, monster: &MonsterType) -> Option { let monster_stat = *self.monster_stats.get(monster)?; let drop_anything = self.rng.gen_range(0, 100); @@ -191,7 +198,7 @@ impl DropTable { } let drop_type = self.rng.gen_range(0, 3); - + match drop_type { 0 => { self.generate_meseta(&monster_stat) @@ -206,7 +213,7 @@ impl DropTable { } } - pub fn get_box_drop(&mut self, map_area: &MapArea, object: &MapObject) -> Option { + fn get_box_drop(&mut self, map_area: &MapArea, object: &MapObject) -> Option { self.box_table.get_drop(map_area, object, &mut self.rng) } } @@ -253,8 +260,8 @@ impl DropTableBuilder { self } - pub fn build(self, episode: Episode, difficulty: Difficulty, section_id: SectionID) -> DropTable { - DropTable { + pub fn build(self, episode: Episode, difficulty: Difficulty, section_id: SectionID) -> Box { + Box::new(StandardDropTable { monster_stats: self.monster_stats.unwrap_or_else(|| { let monster_stats: HashMap = load_data_file(episode, difficulty, section_id, "monster_dar.toml"); monster_stats.into_iter().map(|(m, s)| (m.parse().unwrap(), s)).collect() @@ -267,10 +274,24 @@ impl DropTableBuilder { tool_table: self.tool_table.unwrap_or_else(|| ToolTable::new(episode, difficulty, section_id)), box_table: self.box_table.unwrap_or_else(|| BoxDropTable::new(episode, difficulty, section_id)), rng: self.rng.unwrap_or_else(rand_chacha::ChaCha20Rng::from_entropy), - } + }) } } +struct NullDropTable; + +impl DropTable for NullDropTable { + fn get_drop(&mut self, _map_area: &MapArea, _monster: &MonsterType) -> Option { + None + } + fn get_box_drop(&mut self, _map_area: &MapArea, _object: &MapObject) -> Option { + None + } +} + +pub fn null_drop_table(_episode: Episode, _difficult: Difficulty, _section_id: SectionID) -> Box { + Box::new(NullDropTable) +} #[cfg(test)] mod test { diff --git a/room/src/lib.rs b/room/src/lib.rs index 3f19b0b..fca3669 100644 --- a/room/src/lib.rs +++ b/room/src/lib.rs @@ -171,7 +171,7 @@ pub struct RoomState { pub name: String, pub password: [u16; 16], pub maps: Maps, - pub drop_table: Box, + pub drop_table: Box, pub section_id: SectionID, pub random_seed: u32, pub bursting: bool, @@ -231,7 +231,7 @@ impl RoomState { password: [u16; 16], event: Holiday, map_builder: Arc Maps + Send + Sync>>, - drop_table_builder: Arc DropTable + Send + Sync>>, + drop_table_builder: Arc Box + Send + Sync>>, standard_quest_builder: Arc Result + Send + Sync>>, government_quest_builder: Arc Result + Send + Sync>>, ) -> Result { @@ -262,7 +262,7 @@ impl RoomState { password, maps: map_builder(mode, event), section_id, - drop_table: Box::new(drop_table_builder(episode, difficulty, section_id)), + drop_table: drop_table_builder(episode, difficulty, section_id), bursting: false, map_areas: MapAreaLookup::new(&episode), quest_group: QuestCategoryType::Standard, diff --git a/src/bin/main.rs b/src/bin/main.rs index a4f0eb0..caebcc5 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -13,6 +13,7 @@ use entity::account::{NewUserAccountEntity, NewUserSettingsEntity}; use entity::character::NewCharacterEntity; use entity::item::{NewItemEntity, ItemDetail, InventoryItemEntity}; use entity::item; +use drops::{DropTable, StandardDropTable}; fn setup_logger() { let colors = fern::colors::ColoredLevelConfig::new() @@ -367,6 +368,7 @@ fn main() { .event(Holiday::Halloween) .standard_quest_builder(Box::new(quests::load_standard_quests)) .government_quest_builder(Box::new(quests::load_government_quests)) + .drop_table_builder(Box::new(StandardDropTable::new)) .gateway(entity_gateway.clone()) .build(); let sub_ship_state = ship_state.clone(); @@ -385,6 +387,7 @@ fn main() { .event(Holiday::Christmas) .standard_quest_builder(Box::new(quests::load_standard_quests)) .government_quest_builder(Box::new(quests::load_government_quests)) + .drop_table_builder(Box::new(StandardDropTable::new)) .gateway(entity_gateway.clone()) .build(); let sub_ship_state = ship_state.clone(); @@ -402,6 +405,7 @@ fn main() { .port(elseware::ship::ship::SHIP_PORT+3000) .standard_quest_builder(Box::new(quests::load_standard_quests)) .government_quest_builder(Box::new(quests::load_government_quests)) + .drop_table_builder(Box::new(StandardDropTable::new)) .gateway(entity_gateway.clone()) .build(); let sub_ship_state = ship_state.clone(); diff --git a/src/bin/ship.rs b/src/bin/ship.rs index f6122f7..f5fff5d 100644 --- a/src/bin/ship.rs +++ b/src/bin/ship.rs @@ -2,6 +2,7 @@ use log::info; use entity::gateway::postgres::PostgresGateway; use elseware::ship::ship::ShipServerStateBuilder; use networking::interserver::AuthToken; +use drops::{DropTable, StandardDropTable}; fn main() { let colors = fern::colors::ColoredLevelConfig::new() @@ -45,6 +46,7 @@ fn main() { .auth_token(AuthToken(shipgate_token)) .standard_quest_builder(Box::new(quests::load_standard_quests)) .government_quest_builder(Box::new(quests::load_government_quests)) + .drop_table_builder(Box::new(StandardDropTable::new)) .build(); let shipgate_ip = std::env::var("SHIPGATE_IP").unwrap().parse().unwrap(); diff --git a/src/ship/packet/handler/room.rs b/src/ship/packet/handler/room.rs index 8ec8e3a..563385d 100644 --- a/src/ship/packet/handler/room.rs +++ b/src/ship/packet/handler/room.rs @@ -31,7 +31,7 @@ pub async fn create_room(id: ClientId, item_state: &mut ItemState, rooms: &Rooms, map_builder: Arc Maps + Send + Sync>>, - drop_table_builder: Arc DropTable + Send + Sync>>, + drop_table_builder: Arc Box + Send + Sync>>, standard_quest_builder: Arc Result + Send + Sync>>, government_quest_builder: Arc Result + Send + Sync>>, event: Holiday) diff --git a/src/ship/ship.rs b/src/ship/ship.rs index 4fb4126..5d8beea 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -22,7 +22,7 @@ use entity::gateway::{EntityGateway, GatewayError}; use entity::character::SectionID; use entity::room::RoomNote; use location::{ClientLocation, RoomLobby, ClientLocationError, RoomId}; -use drops::DropTable; +use drops::{DropTable, null_drop_table}; use items; use room; use maps::room::{RoomMode, Episode, Difficulty}; @@ -331,7 +331,7 @@ pub struct ShipServerStateBuilder { auth_token: Option, event: Option, map_builder: Option Maps + Send + Sync>>, - drop_table_builder: Option DropTable + Send + Sync>>, + drop_table_builder: Option Box + Send + Sync>>, standard_quest_builder: Option Result + Send + Sync>>, government_quest_builder: Option Result + Send + Sync>>, num_blocks: usize, @@ -399,7 +399,7 @@ impl ShipServerStateBuilder { } #[must_use] - pub fn drop_table_builder(mut self, drop_table_builder: Box DropTable + Send + Sync>) -> ShipServerStateBuilder { + pub fn drop_table_builder(mut self, drop_table_builder: Box Box + Send + Sync>) -> ShipServerStateBuilder { self.drop_table_builder = Some(drop_table_builder); self } @@ -435,7 +435,7 @@ impl ShipServerStateBuilder { blocks: Blocks(blocks), event: self.event.unwrap_or(Holiday::None), map_builder: Arc::new(self.map_builder.unwrap_or(Box::new(generate_free_roam_maps))), - drop_table_builder: Arc::new(self.drop_table_builder.unwrap_or(Box::new(DropTable::new))), + drop_table_builder: Arc::new(self.drop_table_builder.unwrap_or(Box::new(null_drop_table))), standard_quest_builder: Arc::new(self.standard_quest_builder.unwrap_or(Box::new(|_| Ok(QuestList::new())))), government_quest_builder: Arc::new(self.government_quest_builder.unwrap_or(Box::new(|_| Ok(QuestList::new())))), @@ -486,7 +486,7 @@ pub struct ShipServerState { shipgate_sender: Option>, trades: TradeState, map_builder: Arc Maps + Send + Sync>>, - drop_table_builder: Arc DropTable + Send + Sync>>, + drop_table_builder: Arc Box + Send + Sync>>, standard_quest_builder: Arc Result + Send + Sync>>, government_quest_builder: Arc Result + Send + Sync>>, } diff --git a/tests/common.rs b/tests/common.rs index 1c11777..77a13c7 100644 --- a/tests/common.rs +++ b/tests/common.rs @@ -3,10 +3,14 @@ use networking::serverstate::{ClientId, ServerState}; use entity::gateway::EntityGateway; use entity::account::{UserAccountEntity, NewUserAccountEntity, NewUserSettingsEntity}; -use entity::character::{CharacterEntity, NewCharacterEntity}; +use entity::character::{CharacterEntity, NewCharacterEntity, SectionID}; use entity::item::{Meseta, BankIdentifier}; use elseware::ship::ship::{ShipServerState, RecvShipPacket}; -use maps::room::Difficulty; +use maps::room::{Difficulty, Episode}; +use drops::{DropTable, ItemDropType}; +use maps::area::MapArea; +use maps::monster::MonsterType; +use maps::object::MapObject; use entity::item; diff --git a/tests/test_item_drop.rs b/tests/test_item_drop.rs index 20b6a98..029e0ef 100644 --- a/tests/test_item_drop.rs +++ b/tests/test_item_drop.rs @@ -2,7 +2,7 @@ use networking::serverstate::{ClientId, ServerState}; use entity::gateway::InMemoryGateway; use elseware::ship::ship::{ShipServerState, SendShipPacket, RecvShipPacket}; use maps::monster::MonsterType; -use drops::{DropTable, MonsterDropStats, MonsterDropType}; +use drops::{StandardDropTable, MonsterDropStats, MonsterDropType}; use drops::rare_drop_table::{RareDropTable, RareDropRate, RareDropItem}; use maps::maps::Maps; use maps::area::MapArea; @@ -32,7 +32,7 @@ async fn test_enemy_drops_item() { ) })) .drop_table_builder(Box::new(|episode, difficulty, section_id| { - DropTable::builder() + StandardDropTable::builder() .monster_stat(MonsterType::Hildebear, MonsterDropStats { dar: 100, drop_type: MonsterDropType::Weapon, @@ -88,7 +88,7 @@ async fn test_enemy_drops_item_for_two_players() { ) })) .drop_table_builder(Box::new(|episode, difficulty, section_id| { - DropTable::builder() + StandardDropTable::builder() .monster_stat(MonsterType::Hildebear, MonsterDropStats { dar: 100, drop_type: MonsterDropType::Weapon, @@ -156,7 +156,7 @@ async fn test_enemy_drops_item_for_two_players_and_pick_up() { ) })) .drop_table_builder(Box::new(|episode, difficulty, section_id| { - DropTable::builder() + StandardDropTable::builder() .monster_stat(MonsterType::Hildebear, MonsterDropStats { dar: 100, drop_type: MonsterDropType::Weapon,