diff --git a/assets/voxygen/voxel/object/Human_Airship.vox b/assets/voxygen/voxel/object/Human_Airship.vox index 9995596018..36e3758d03 120000 --- a/assets/voxygen/voxel/object/Human_Airship.vox +++ b/assets/voxygen/voxel/object/Human_Airship.vox @@ -1 +1,3 @@ -../../../server/voxel/Human_Airship.vox \ No newline at end of file +version https://git-lfs.github.com/spec/v1 +oid sha256:ba02746d73ebf853c0511b673510c09bd47e3ab0fff13d936feb181a8378ebd9 +size 78024 diff --git a/assets/voxygen/voxel/object/airship.vox b/assets/voxygen/voxel/object/airship.vox index 3479493953..06bebaa938 120000 --- a/assets/voxygen/voxel/object/airship.vox +++ b/assets/voxygen/voxel/object/airship.vox @@ -1 +1,3 @@ -../../../server/voxel/airship.vox \ No newline at end of file +version https://git-lfs.github.com/spec/v1 +oid sha256:86f317298900ea98f95c6a33192b25fbbcbd3ce5f105cad58ad3c595a7a7d9ee +size 70176 diff --git a/assets/voxygen/voxel/object/propeller-l.vox b/assets/voxygen/voxel/object/propeller-l.vox index a8105d8b1b..a193fa89ee 120000 --- a/assets/voxygen/voxel/object/propeller-l.vox +++ b/assets/voxygen/voxel/object/propeller-l.vox @@ -1 +1,3 @@ -../../../server/voxel/propeller-l.vox \ No newline at end of file +version https://git-lfs.github.com/spec/v1 +oid sha256:09ef4bad2557abcc5a2b938f21053babc7770ebe2333039aef9b98ba930b7ec7 +size 1584 diff --git a/assets/voxygen/voxel/object/propeller-r.vox b/assets/voxygen/voxel/object/propeller-r.vox index 647f3f66d0..5b940751e6 120000 --- a/assets/voxygen/voxel/object/propeller-r.vox +++ b/assets/voxygen/voxel/object/propeller-r.vox @@ -1 +1,3 @@ -../../../server/voxel/propeller-r.vox \ No newline at end of file +version https://git-lfs.github.com/spec/v1 +oid sha256:e4947977524b88bc5adfa934d9061a3499e94b960abb3bcf0a3e2aca482096dc +size 1584 diff --git a/common/src/cmd.rs b/common/src/cmd.rs index a74f0cab09..9aee158547 100644 --- a/common/src/cmd.rs +++ b/common/src/cmd.rs @@ -224,7 +224,7 @@ impl ChatCommand { "Temporarily gives a player admin permissions or removes them", Admin, ), - ChatCommand::Airship => cmd(vec![], "Spawns an airship", Admin), + ChatCommand::Airship => cmd(vec![Boolean("moving", "true".to_string(), Optional)], "Spawns an airship", Admin), ChatCommand::Alias => cmd(vec![Any("name", Required)], "Change your alias", NoAdmin), ChatCommand::Ban => cmd( vec![Any("username", Required), Message(Optional)], diff --git a/common/src/comp/agent.rs b/common/src/comp/agent.rs index 7110c56b70..39af9ab5fb 100644 --- a/common/src/comp/agent.rs +++ b/common/src/comp/agent.rs @@ -205,6 +205,15 @@ impl Agent { self } + pub fn with_destination() -> Self { + Self { + can_speak: false, + psyche: Psyche { aggro: 1.0 }, + rtsim_controller: RtSimController::zero(), + ..Default::default() + } + } + pub fn new( patrol_origin: Option>, can_speak: bool, diff --git a/common/src/rtsim.rs b/common/src/rtsim.rs index e5c1268d2e..809a505b1f 100644 --- a/common/src/rtsim.rs +++ b/common/src/rtsim.rs @@ -46,4 +46,10 @@ impl Default for RtSimController { impl RtSimController { pub fn reset(&mut self) { *self = Self::default(); } + pub fn zero() -> Self { + Self { + travel_to: Some((Vec3::new(0.0, 0.0, 500.0), "".to_string())), + speed_factor: 0.05, + } + } } diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 787f53cf1d..2991fbdbd4 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -962,15 +962,16 @@ fn handle_spawn_airship( server: &mut Server, client: EcsEntity, target: EcsEntity, - _args: String, - _action: &ChatCommand, + args: String, + action: &ChatCommand, ) { + let moving = scan_fmt_some!(&args, &action.arg_fmt(), String).unwrap_or_else(|| "false".to_string()) == "true"; match server.state.read_component_copied::(target) { Some(mut pos) => { pos.0.z += 50.0; server .state - .create_ship(pos, comp::ship::Body::DefaultAirship, 1) + .create_ship(pos, comp::ship::Body::DefaultAirship, 1, moving) .with(comp::Scale(11.0 / 0.8)) .with(LightEmitter { col: Rgb::new(1.0, 0.65, 0.2), diff --git a/server/src/rtsim/entity.rs b/server/src/rtsim/entity.rs index cfd29f9a3e..60ac8fd832 100644 --- a/server/src/rtsim/entity.rs +++ b/server/src/rtsim/entity.rs @@ -28,6 +28,9 @@ impl Entity { pub fn get_body(&self) -> comp::Body { match self.rng(PERM_GENUS).gen::() { //we want 50% birds, 50% humans for now + x if x < 0.05 => { + comp::Body::Ship(comp::ship::Body::DefaultAirship) + }, x if x < 0.50 => { let species = *(&comp::bird_medium::ALL_SPECIES) .choose(&mut self.rng(PERM_SPECIES)) @@ -53,6 +56,7 @@ impl Entity { comp::Body::BirdSmall(_) => "Warbler".to_string(), comp::Body::Dragon(b) => get_npc_name(&npc_names.dragon, b.species).to_string(), comp::Body::Humanoid(b) => get_npc_name(&npc_names.humanoid, b.species).to_string(), + comp::Body::Ship(_) => "Veloren Air".to_string(), //TODO: finish match as necessary _ => unimplemented!(), } @@ -131,6 +135,7 @@ impl Entity { .iter() .filter(|s| match self.get_body() { comp::Body::Humanoid(_) => s.1.is_settlement() | s.1.is_castle(), + comp::Body::Ship(_) => s.1.is_castle(), _ => s.1.is_dungeon(), }) .filter(|_| thread_rng().gen_range(0i32..4) == 0) diff --git a/server/src/state_ext.rs b/server/src/state_ext.rs index fbb03fae5c..67a20432cb 100644 --- a/server/src/state_ext.rs +++ b/server/src/state_ext.rs @@ -41,7 +41,7 @@ pub trait StateExt { ) -> EcsEntityBuilder; /// Build a static object entity fn create_object(&mut self, pos: comp::Pos, object: comp::object::Body) -> EcsEntityBuilder; - fn create_ship(&mut self, pos: comp::Pos, object: comp::ship::Body, level: u16) -> EcsEntityBuilder; + fn create_ship(&mut self, pos: comp::Pos, ship: comp::ship::Body, level: u16, moving: bool) -> EcsEntityBuilder; /// Build a projectile fn create_projectile( &mut self, @@ -203,24 +203,45 @@ impl StateExt for State { .with(comp::Gravity(1.0)) } - fn create_ship(&mut self, pos: comp::Pos, ship: comp::ship::Body, level: u16) -> EcsEntityBuilder { - self.ecs_mut() - .create_entity_synced() - .with(pos) - .with(comp::Vel(Vec3::zero())) - .with(comp::Ori::default()) - .with(comp::Mass(50.0)) - .with(comp::Collider::Voxel { id: ship.manifest_entry().to_string() }) - .with(comp::Body::Ship(ship)) - .with(comp::Gravity(1.0)) - .with(comp::Controller::default()) - .with(comp::inventory::Inventory::new_empty()) - .with(comp::CharacterState::default()) - .with(comp::Energy::new(ship.into(), level)) - .with(comp::Health::new(ship.into(), level)) - .with(comp::Stats::new("Airship".to_string())) - .with(comp::Buffs::default()) - .with(comp::Combo::default()) + fn create_ship(&mut self, pos: comp::Pos, ship: comp::ship::Body, level: u16, moving: bool) -> EcsEntityBuilder { + if moving { + self.ecs_mut() + .create_entity_synced() + .with(pos) + .with(comp::Vel(Vec3::zero())) + .with(comp::Ori::default()) + .with(comp::Mass(50.0)) + .with(comp::Collider::Voxel { id: ship.manifest_entry().to_string() }) + .with(comp::Body::Ship(ship)) + .with(comp::Gravity(1.0)) + .with(comp::Controller::default()) + .with(comp::inventory::Inventory::new_empty()) + .with(comp::CharacterState::default()) + .with(comp::Energy::new(ship.into(), level)) + .with(comp::Health::new(ship.into(), level)) + .with(comp::Stats::new("Airship".to_string())) + .with(comp::Buffs::default()) + .with(comp::Combo::default()) + .with(comp::Agent::with_destination()) + } else { + self.ecs_mut() + .create_entity_synced() + .with(pos) + .with(comp::Vel(Vec3::zero())) + .with(comp::Ori::default()) + .with(comp::Mass(50.0)) + .with(comp::Collider::Voxel { id: ship.manifest_entry().to_string() }) + .with(comp::Body::Ship(ship)) + .with(comp::Gravity(1.0)) + .with(comp::Controller::default()) + .with(comp::inventory::Inventory::new_empty()) + .with(comp::CharacterState::default()) + .with(comp::Energy::new(ship.into(), level)) + .with(comp::Health::new(ship.into(), level)) + .with(comp::Stats::new("Airship".to_string())) + .with(comp::Buffs::default()) + .with(comp::Combo::default()) + } } fn create_projectile( diff --git a/server/src/sys/agent.rs b/server/src/sys/agent.rs index dd029b3546..622ef1b0a4 100644 --- a/server/src/sys/agent.rs +++ b/server/src/sys/agent.rs @@ -596,7 +596,7 @@ impl<'a> AgentData<'a> { .ray( self.pos.0 + Vec3::unit_z(), self.pos.0 - + bearing.try_normalized().unwrap_or_else(Vec3::unit_y) * 60.0 + + bearing.try_normalized().unwrap_or_else(Vec3::unit_y) * 80.0 + Vec3::unit_z(), ) .until(Block::is_solid)