mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Improved commands, fixed tether orientation
This commit is contained in:
parent
2d4278e94a
commit
1ac1c900c9
@ -688,12 +688,12 @@ impl ServerChatCommand {
|
||||
.collect(),
|
||||
Optional,
|
||||
),
|
||||
Float("destination_degrees_ccw_of_east", 90.0, Optional),
|
||||
Boolean(
|
||||
"Whether the ship should be tethered to the target (or its mount)",
|
||||
"false".to_string(),
|
||||
Optional,
|
||||
),
|
||||
Float("destination_degrees_ccw_of_east", 90.0, Optional),
|
||||
],
|
||||
"Spawns a ship",
|
||||
Some(Admin),
|
||||
|
@ -88,7 +88,7 @@ impl Body {
|
||||
Body::Skiff => Vec3::new(7.0, 15.0, 10.0),
|
||||
Body::Submarine => Vec3::new(2.0, 15.0, 8.0),
|
||||
Body::Carriage => Vec3::new(5.0, 12.0, 2.0),
|
||||
Body::Cart => Vec3::new(5.0, 8.0, 5.0),
|
||||
Body::Cart => Vec3::new(3.0, 6.0, 1.0),
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,14 +122,21 @@ impl Body {
|
||||
match self {
|
||||
Body::DefaultAirship | Body::AirBalloon | Body::Volume => Density(AIR_DENSITY),
|
||||
Body::Submarine => Density(WATER_DENSITY), // Neutrally buoyant
|
||||
Body::Carriage => Density(AIR_DENSITY * 1.5),
|
||||
Body::Cart => Density(AIR_DENSITY * 1.2),
|
||||
Body::Carriage => Density(WATER_DENSITY * 0.5),
|
||||
Body::Cart => Density(500.0 / self.dimensions().product()), /* Carts get a constant
|
||||
* mass */
|
||||
_ => Density(AIR_DENSITY * 0.95 + WATER_DENSITY * 0.05), /* Most boats should be very
|
||||
* buoyant */
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mass(&self) -> Mass { Mass((self.hull_vol() + self.balloon_vol()) * self.density().0) }
|
||||
pub fn mass(&self) -> Mass {
|
||||
if self.can_fly() {
|
||||
Mass((self.hull_vol() + self.balloon_vol()) * self.density().0)
|
||||
} else {
|
||||
Mass(self.density().0 * self.dimensions().product())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn can_fly(&self) -> bool {
|
||||
matches!(self, Body::DefaultAirship | Body::AirBalloon | Body::Volume)
|
||||
|
@ -150,7 +150,7 @@ impl Body {
|
||||
quadruped_low::Species::Driggle => 120.0,
|
||||
quadruped_low::Species::HermitAlligator => 120.0,
|
||||
},
|
||||
Body::Ship(ship::Body::Carriage) => 35.0,
|
||||
Body::Ship(ship::Body::Carriage) => 40.0,
|
||||
Body::Ship(_) => 0.0,
|
||||
Body::Arthropod(arthropod) => match arthropod.species {
|
||||
arthropod::Species::Tarantula => 135.0,
|
||||
|
@ -1,14 +1,11 @@
|
||||
use crate::{
|
||||
comp,
|
||||
link::{Is, Link, LinkHandle, Role},
|
||||
mounting::{Mount, Rider, VolumeRider},
|
||||
mounting::{Rider, VolumeRider},
|
||||
uid::{Uid, UidAllocator},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specs::{
|
||||
saveload::MarkerAllocator, storage::GenericWriteStorage, Component, DenseVecStorage, Entities,
|
||||
Entity, Read, ReadExpect, ReadStorage, Write, WriteStorage,
|
||||
};
|
||||
use specs::{saveload::MarkerAllocator, Entities, Read, ReadStorage, WriteStorage};
|
||||
use vek::*;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
@ -44,25 +41,20 @@ impl Link for Tethered {
|
||||
WriteStorage<'a, Is<Leader>>,
|
||||
WriteStorage<'a, Is<Follower>>,
|
||||
ReadStorage<'a, Is<Rider>>,
|
||||
ReadStorage<'a, Is<Mount>>,
|
||||
ReadStorage<'a, Is<VolumeRider>>,
|
||||
);
|
||||
type DeleteData<'a> = (
|
||||
Read<'a, UidAllocator>,
|
||||
WriteStorage<'a, Is<Leader>>,
|
||||
WriteStorage<'a, Is<Follower>>,
|
||||
WriteStorage<'a, comp::Pos>,
|
||||
WriteStorage<'a, comp::ForceUpdate>,
|
||||
);
|
||||
type Error = TetherError;
|
||||
type PersistData<'a> = (
|
||||
Read<'a, UidAllocator>,
|
||||
Entities<'a>,
|
||||
ReadStorage<'a, comp::Health>,
|
||||
ReadStorage<'a, comp::Body>,
|
||||
ReadStorage<'a, Is<Leader>>,
|
||||
ReadStorage<'a, Is<Follower>>,
|
||||
ReadStorage<'a, comp::CharacterState>,
|
||||
);
|
||||
|
||||
fn create(
|
||||
@ -72,7 +64,6 @@ impl Link for Tethered {
|
||||
is_leaders,
|
||||
is_followers,
|
||||
is_riders,
|
||||
is_mounts,
|
||||
is_volume_rider,
|
||||
): &mut Self::CreateData<'_>,
|
||||
) -> Result<(), Self::Error> {
|
||||
@ -103,7 +94,7 @@ impl Link for Tethered {
|
||||
|
||||
fn persist(
|
||||
this: &LinkHandle<Self>,
|
||||
(uid_allocator, entities, healths, bodies, is_leaders, is_followers, character_states): &mut Self::PersistData<'_>,
|
||||
(uid_allocator, entities, healths, is_leaders, is_followers): &mut Self::PersistData<'_>,
|
||||
) -> bool {
|
||||
let entity = |uid: Uid| uid_allocator.retrieve_entity_internal(uid.into());
|
||||
|
||||
@ -124,9 +115,7 @@ impl Link for Tethered {
|
||||
|
||||
fn delete(
|
||||
this: &LinkHandle<Self>,
|
||||
(uid_allocator, is_leaders, is_followers, positions, force_update): &mut Self::DeleteData<
|
||||
'_,
|
||||
>,
|
||||
(uid_allocator, is_leaders, is_followers): &mut Self::DeleteData<'_>,
|
||||
) {
|
||||
let entity = |uid: Uid| uid_allocator.retrieve_entity_internal(uid.into());
|
||||
|
||||
|
@ -1,17 +1,16 @@
|
||||
use common::{
|
||||
comp::{Body, Collider, InputKind, Mass, Ori, Pos, Scale, Vel},
|
||||
comp::{Body, Mass, Ori, Pos, Scale, Vel},
|
||||
link::Is,
|
||||
resources::DeltaTime,
|
||||
tether::{Follower, Leader},
|
||||
tether::Follower,
|
||||
uid::UidAllocator,
|
||||
util::Dir,
|
||||
};
|
||||
use common_ecs::{Job, Origin, Phase, System};
|
||||
use specs::{
|
||||
saveload::{Marker, MarkerAllocator},
|
||||
Entities, Join, Read, ReadExpect, ReadStorage, WriteStorage,
|
||||
Entities, Join, Read, ReadStorage, WriteStorage,
|
||||
};
|
||||
use tracing::error;
|
||||
use vek::*;
|
||||
|
||||
/// This system is responsible for controlling mounts
|
||||
@ -22,14 +21,12 @@ impl<'a> System<'a> for Sys {
|
||||
Read<'a, UidAllocator>,
|
||||
Entities<'a>,
|
||||
Read<'a, DeltaTime>,
|
||||
ReadStorage<'a, Is<Leader>>,
|
||||
ReadStorage<'a, Is<Follower>>,
|
||||
WriteStorage<'a, Pos>,
|
||||
WriteStorage<'a, Vel>,
|
||||
WriteStorage<'a, Ori>,
|
||||
ReadStorage<'a, Body>,
|
||||
ReadStorage<'a, Scale>,
|
||||
ReadStorage<'a, Collider>,
|
||||
ReadStorage<'a, Mass>,
|
||||
);
|
||||
|
||||
@ -43,19 +40,17 @@ impl<'a> System<'a> for Sys {
|
||||
uid_allocator,
|
||||
entities,
|
||||
dt,
|
||||
is_leaders,
|
||||
is_followers,
|
||||
mut positions,
|
||||
positions,
|
||||
mut velocities,
|
||||
mut orientations,
|
||||
bodies,
|
||||
scales,
|
||||
colliders,
|
||||
masses,
|
||||
): Self::SystemData,
|
||||
) {
|
||||
for (follower, is_follower, follower_body) in
|
||||
(&entities, &is_followers, bodies.maybe()).join()
|
||||
for (follower, is_follower, follower_body, scale) in
|
||||
(&entities, &is_followers, bodies.maybe(), scales.maybe()).join()
|
||||
{
|
||||
let Some(leader) = uid_allocator
|
||||
.retrieve_entity_internal(is_follower.leader.id())
|
||||
@ -75,13 +70,15 @@ impl<'a> System<'a> for Sys {
|
||||
let tether_offset = orientations
|
||||
.get(follower)
|
||||
.map(|ori| {
|
||||
ori.to_quat() * follower_body.map(|b| b.tether_offset()).unwrap_or_default()
|
||||
ori.to_quat()
|
||||
* follower_body
|
||||
.map(|b| b.tether_offset() * scale.copied().unwrap_or(Scale(1.0)).0)
|
||||
.unwrap_or_default()
|
||||
})
|
||||
.unwrap_or_default();
|
||||
let tether_pos = follower_pos.0 + tether_offset;
|
||||
let pull_factor = (leader_pos.0.distance(tether_pos) - is_follower.tether_length)
|
||||
.clamp(0.0, 1.0)
|
||||
.powf(2.0);
|
||||
let pull_factor =
|
||||
(leader_pos.0.distance(tether_pos) - is_follower.tether_length).max(0.0);
|
||||
let strength = pull_factor * 50000.0;
|
||||
let pull_dir = (leader_pos.0 - follower_pos.0)
|
||||
.try_normalized()
|
||||
@ -93,9 +90,10 @@ impl<'a> System<'a> for Sys {
|
||||
velocities.get_mut(leader).unwrap().0 -= impulse / leader_mass.0;
|
||||
|
||||
if let Some(follower_ori) = orientations.get_mut(follower) {
|
||||
let turn_strength = pull_factor.min(0.2)
|
||||
// * (tether_offset.magnitude() - tether_offset.dot(pull_dir).abs())
|
||||
* 50.0;
|
||||
let turn_strength = pull_factor
|
||||
* (tether_offset.magnitude() * (leader_pos.0 - tether_pos).magnitude()
|
||||
- tether_offset.dot(leader_pos.0 - tether_pos).abs())
|
||||
* 2.0;
|
||||
let target_ori = follower_ori.yawed_towards(Dir::new(pull_dir));
|
||||
*follower_ori = follower_ori.slerped_towards(target_ori, turn_strength * dt.0);
|
||||
}
|
||||
|
@ -1778,7 +1778,7 @@ fn handle_spawn_ship(
|
||||
args: Vec<String>,
|
||||
_action: &ServerChatCommand,
|
||||
) -> CmdResult<()> {
|
||||
let (body_name, angle, tethered) = parse_cmd_args!(args, String, f32, bool);
|
||||
let (body_name, tethered, angle) = parse_cmd_args!(args, String, bool, f32);
|
||||
let mut pos = position(server, target, "target")?;
|
||||
pos.0.z += 2.0;
|
||||
const DESTINATION_RADIUS: f32 = 2000.0;
|
||||
@ -1798,15 +1798,15 @@ fn handle_spawn_ship(
|
||||
.state
|
||||
.create_ship(pos, ori, ship, |ship| ship.make_collider());
|
||||
|
||||
// if let Some(pos) = destination {
|
||||
// let (kp, ki, kd) =
|
||||
// comp::agent::pid_coefficients(&comp::Body::Ship(ship)).unwrap_or((1.
|
||||
// 0, 0.0, 0.0)); fn pure_z(sp: Vec3<f32>, pv: Vec3<f32>) -> f32 { (sp -
|
||||
// pv).z } let agent = comp::Agent::from_body(&comp::Body::Ship(ship))
|
||||
// .with_destination(pos)
|
||||
// .with_position_pid_controller(comp::PidController::new(kp, ki, kd,
|
||||
// pos, 0.0, pure_z)); builder = builder.with(agent);
|
||||
// }
|
||||
if let Some(pos) = destination {
|
||||
let (kp, ki, kd) =
|
||||
comp::agent::pid_coefficients(&comp::Body::Ship(ship)).unwrap_or((1.0, 0.0, 0.0));
|
||||
fn pure_z(sp: Vec3<f32>, pv: Vec3<f32>) -> f32 { (sp - pv).z }
|
||||
let agent = comp::Agent::from_body(&comp::Body::Ship(ship))
|
||||
.with_destination(pos)
|
||||
.with_position_pid_controller(comp::PidController::new(kp, ki, kd, pos, 0.0, pure_z));
|
||||
builder = builder.with(agent);
|
||||
}
|
||||
|
||||
let new_entity = builder.build();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user