mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'zesterer/tiny-fixes' into 'master'
Tiny fixes See merge request veloren/veloren!2791
This commit is contained in:
commit
eed8070e7e
@ -34,6 +34,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Explosions no longer change block colours within safe zones
|
||||
- The 'spot' system, which generates smaller site-like structures and scenarios
|
||||
- Chestnut and cedar tree varieties
|
||||
- Shooting sprites, such as apples and hives, can knock them out of trees
|
||||
|
||||
### Changed
|
||||
|
||||
|
@ -19,6 +19,7 @@ pub enum Effect {
|
||||
Vanish,
|
||||
Stick,
|
||||
Possess,
|
||||
Bonk, // Knock/dislodge/change objects on hit
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
@ -127,7 +128,7 @@ impl ProjectileConstructor {
|
||||
.with_combo_increment();
|
||||
|
||||
Projectile {
|
||||
hit_solid: vec![Effect::Stick],
|
||||
hit_solid: vec![Effect::Stick, Effect::Bonk],
|
||||
hit_entity: vec![Effect::Attack(attack), Effect::Vanish],
|
||||
time_left: Duration::from_secs(15),
|
||||
owner,
|
||||
|
@ -42,6 +42,11 @@ pub enum ServerEvent {
|
||||
explosion: Explosion,
|
||||
owner: Option<Uid>,
|
||||
},
|
||||
Bonk {
|
||||
pos: Vec3<f32>,
|
||||
owner: Option<Uid>,
|
||||
target: Option<Uid>,
|
||||
},
|
||||
Damage {
|
||||
entity: EcsEntity,
|
||||
change: comp::HealthChange,
|
||||
|
@ -259,6 +259,14 @@ impl Block {
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_bonkable(&self) -> bool {
|
||||
match self.get_sprite() {
|
||||
Some(SpriteKind::Apple | SpriteKind::Beehive | SpriteKind::Coconut) => self.is_solid(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// The tool required to mine this block. For blocks that cannot be mined,
|
||||
/// `None` is returned.
|
||||
#[inline]
|
||||
|
@ -238,6 +238,7 @@ impl SpriteKind {
|
||||
| SpriteKind::MedFlatCactus
|
||||
| SpriteKind::ShortFlatCactus
|
||||
| SpriteKind::Apple
|
||||
| SpriteKind::Beehive
|
||||
| SpriteKind::Velorite
|
||||
| SpriteKind::VeloriteFrag
|
||||
| SpriteKind::Coconut
|
||||
|
@ -872,15 +872,14 @@ impl<'a> PhysicsData<'a> {
|
||||
.terrain
|
||||
.get(pos.0.map(|e| e.floor() as i32))
|
||||
.ok()
|
||||
.filter(|b| b.is_filled())
|
||||
// TODO: `is_solid`, when arrows are special-cased
|
||||
.filter(|b| b.is_solid())
|
||||
{
|
||||
(0.0, Some(block))
|
||||
} else {
|
||||
let (dist, block) = read
|
||||
.terrain
|
||||
.ray(pos.0, pos.0 + pos_delta)
|
||||
.until(|block: &Block| block.is_filled())
|
||||
.until(|block: &Block| block.is_solid())
|
||||
.ignore_error()
|
||||
.cast();
|
||||
(dist, block.unwrap()) // Can't fail since we do ignore_error above
|
||||
@ -897,7 +896,7 @@ impl<'a> PhysicsData<'a> {
|
||||
.zip(read.bodies.get(entity).copied())
|
||||
{
|
||||
outcomes.push(Outcome::ProjectileHit {
|
||||
pos: pos.0,
|
||||
pos: pos.0 + pos_delta * dist,
|
||||
body,
|
||||
vel: vel.0,
|
||||
source: projectile.owner,
|
||||
|
@ -181,6 +181,13 @@ impl<'a> System<'a> for Sys {
|
||||
});
|
||||
projectile_vanished = true;
|
||||
},
|
||||
projectile::Effect::Bonk => {
|
||||
server_emitter.emit(ServerEvent::Bonk {
|
||||
pos: pos.0,
|
||||
owner: projectile.owner,
|
||||
target: None,
|
||||
});
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
@ -325,6 +332,15 @@ fn dispatch_hit(
|
||||
owner: owner_uid,
|
||||
});
|
||||
},
|
||||
projectile::Effect::Bonk => {
|
||||
let Pos(pos) = *projectile_info.pos;
|
||||
let owner_uid = projectile_info.owner_uid;
|
||||
server_emitter.emit(ServerEvent::Bonk {
|
||||
pos,
|
||||
owner: owner_uid,
|
||||
target: Some(projectile_target_info.uid),
|
||||
});
|
||||
},
|
||||
projectile::Effect::Vanish => {
|
||||
let entity = projectile_info.entity;
|
||||
server_emitter.emit(ServerEvent::Destroy {
|
||||
|
@ -37,7 +37,7 @@ use common_state::BlockChange;
|
||||
use comp::chat::GenericChatMsg;
|
||||
use hashbrown::HashSet;
|
||||
use rand::Rng;
|
||||
use specs::{join::Join, saveload::MarkerAllocator, Entity as EcsEntity, WorldExt};
|
||||
use specs::{join::Join, saveload::MarkerAllocator, Builder, Entity as EcsEntity, WorldExt};
|
||||
use tracing::error;
|
||||
use vek::{Vec2, Vec3};
|
||||
|
||||
@ -378,7 +378,6 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
|
||||
{
|
||||
// Only drop loot if entity has agency (not a player), and if it is not owned by
|
||||
// another entity (not a pet)
|
||||
use specs::Builder;
|
||||
|
||||
// Decide for a loot drop before turning into a lootbag
|
||||
let old_body = state.ecs().write_storage::<Body>().remove(entity);
|
||||
@ -1021,6 +1020,36 @@ pub fn handle_explosion(server: &Server, pos: Vec3<f32>, explosion: Explosion, o
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_bonk(server: &mut Server, pos: Vec3<f32>, _owner: Option<Uid>, target: Option<Uid>) {
|
||||
let ecs = &server.state.ecs();
|
||||
let terrain = ecs.read_resource::<TerrainGrid>();
|
||||
let mut block_change = ecs.write_resource::<BlockChange>();
|
||||
|
||||
if let Some(_target) = target {
|
||||
// TODO: bonk entities but do no damage?
|
||||
} else {
|
||||
use common::terrain::SpriteKind;
|
||||
let pos = pos.map(|e| e.floor() as i32);
|
||||
if let Some(block) = terrain.get(pos).ok().copied().filter(|b| b.is_bonkable()) {
|
||||
if let Some(item) = comp::Item::try_reclaim_from_block(block) {
|
||||
if block_change
|
||||
.try_set(pos, block.with_sprite(SpriteKind::Empty))
|
||||
.is_some()
|
||||
{
|
||||
drop(terrain);
|
||||
drop(block_change);
|
||||
server
|
||||
.state
|
||||
.create_object(Default::default(), comp::object::Body::Pouch)
|
||||
.with(comp::Pos(pos.map(|e| e as f32) + Vec3::new(0.5, 0.5, 0.0)))
|
||||
.with(item)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_aura(server: &mut Server, entity: EcsEntity, aura_change: aura::AuraChange) {
|
||||
let ecs = &server.state.ecs();
|
||||
let mut auras_all = ecs.write_storage::<comp::Auras>();
|
||||
|
@ -6,9 +6,9 @@ use entity_creation::{
|
||||
handle_initialize_character, handle_loaded_character_data, handle_shockwave, handle_shoot,
|
||||
};
|
||||
use entity_manipulation::{
|
||||
handle_aura, handle_buff, handle_combo_change, handle_damage, handle_delete, handle_destroy,
|
||||
handle_energy_change, handle_explosion, handle_knockback, handle_land_on_ground, handle_poise,
|
||||
handle_respawn, handle_teleport_to,
|
||||
handle_aura, handle_bonk, handle_buff, handle_combo_change, handle_damage, handle_delete,
|
||||
handle_destroy, handle_energy_change, handle_explosion, handle_knockback,
|
||||
handle_land_on_ground, handle_poise, handle_respawn, handle_teleport_to,
|
||||
};
|
||||
use group_manip::handle_group;
|
||||
use information::handle_site_info;
|
||||
@ -67,6 +67,7 @@ impl Server {
|
||||
explosion,
|
||||
owner,
|
||||
} => handle_explosion(self, pos, explosion, owner),
|
||||
ServerEvent::Bonk { pos, owner, target } => handle_bonk(self, pos, owner, target),
|
||||
ServerEvent::Shoot {
|
||||
entity,
|
||||
dir,
|
||||
|
@ -49,6 +49,8 @@ pub struct Camera {
|
||||
dist: f32,
|
||||
tgt_fov: f32,
|
||||
fov: f32,
|
||||
tgt_fixate: f32,
|
||||
fixate: f32,
|
||||
aspect: f32,
|
||||
mode: CameraMode,
|
||||
|
||||
@ -327,6 +329,8 @@ impl Camera {
|
||||
dist: 10.0,
|
||||
tgt_fov: 1.1,
|
||||
fov: 1.1,
|
||||
tgt_fixate: 1.0,
|
||||
fixate: 1.0,
|
||||
aspect,
|
||||
mode,
|
||||
|
||||
@ -466,13 +470,14 @@ impl Camera {
|
||||
* Mat4::translation_3d(-self.focus.map(|e| e.fract()));
|
||||
let view_mat_inv: Mat4<f32> = view_mat.inverted();
|
||||
|
||||
let fov = self.get_effective_fov();
|
||||
// NOTE: We reverse the far and near planes to produce an inverted depth
|
||||
// buffer (1 to 0 z planes).
|
||||
let proj_mat =
|
||||
perspective_rh_zo_general(self.fov, self.aspect, 1.0 / FAR_PLANE, 1.0 / NEAR_PLANE);
|
||||
perspective_rh_zo_general(fov, self.aspect, 1.0 / FAR_PLANE, 1.0 / NEAR_PLANE);
|
||||
// For treeculler, we also produce a version without inverted depth.
|
||||
let proj_mat_treeculler =
|
||||
perspective_rh_zo_general(self.fov, self.aspect, 1.0 / NEAR_PLANE, 1.0 / FAR_PLANE);
|
||||
perspective_rh_zo_general(fov, self.aspect, 1.0 / NEAR_PLANE, 1.0 / FAR_PLANE);
|
||||
|
||||
Dependents {
|
||||
view_mat,
|
||||
@ -501,6 +506,7 @@ impl Camera {
|
||||
/// Rotate the camera about its focus by the given delta, limiting the input
|
||||
/// accordingly.
|
||||
pub fn rotate_by(&mut self, delta: Vec3<f32>) {
|
||||
let delta = delta * self.fixate;
|
||||
// Wrap camera yaw
|
||||
self.tgt_ori.x = (self.tgt_ori.x + delta.x).rem_euclid(2.0 * PI);
|
||||
// Clamp camera pitch to the vertical limits
|
||||
@ -575,6 +581,14 @@ impl Camera {
|
||||
);
|
||||
}
|
||||
|
||||
if (self.fixate - self.tgt_fixate).abs() > 0.01 {
|
||||
self.fixate = vek::Lerp::lerp(
|
||||
self.fixate,
|
||||
self.tgt_fixate,
|
||||
0.65 * (delta as f32) / self.interp_time(),
|
||||
);
|
||||
}
|
||||
|
||||
if (self.focus - self.tgt_focus).magnitude_squared() > 0.001 {
|
||||
let lerped_focus = Lerp::lerp(
|
||||
self.focus,
|
||||
@ -639,12 +653,20 @@ impl Camera {
|
||||
/// Get the orientation of the camera.
|
||||
pub fn get_orientation(&self) -> Vec3<f32> { self.ori }
|
||||
|
||||
/// Get the field of view of the camera in radians.
|
||||
pub fn get_fov(&self) -> f32 { self.fov }
|
||||
/// Get the field of view of the camera in radians, taking into account
|
||||
/// fixation.
|
||||
pub fn get_effective_fov(&self) -> f32 { self.fov * self.fixate }
|
||||
|
||||
// /// Get the field of view of the camera in radians.
|
||||
// pub fn get_fov(&self) -> f32 { self.fov }
|
||||
|
||||
/// Set the field of view of the camera in radians.
|
||||
pub fn set_fov(&mut self, fov: f32) { self.tgt_fov = fov; }
|
||||
|
||||
/// Set the 'fixation' proportion, allowing the camera to focus in with
|
||||
/// precise aiming. Fixation is applied on top of the regular FoV.
|
||||
pub fn set_fixate(&mut self, fixate: f32) { self.tgt_fixate = fixate; }
|
||||
|
||||
/// Set the FOV in degrees
|
||||
pub fn set_fov_deg(&mut self, fov: u16) {
|
||||
//Magic value comes from pi/180; no use recalculating.
|
||||
|
@ -682,7 +682,7 @@ impl Scene {
|
||||
let sun_dir = scene_data.get_sun_dir();
|
||||
let is_daylight = sun_dir.z < 0.0;
|
||||
if renderer.pipeline_modes().shadow.is_map() && (is_daylight || !lights.is_empty()) {
|
||||
let fov = self.camera.get_fov();
|
||||
let fov = self.camera.get_effective_fov();
|
||||
let aspect_ratio = self.camera.get_aspect_ratio();
|
||||
|
||||
let view_dir = ((focus_pos.map(f32::fract)) - cam_pos).normalized();
|
||||
|
@ -77,7 +77,6 @@ pub struct SessionState {
|
||||
target_entity: Option<specs::Entity>,
|
||||
selected_entity: Option<(specs::Entity, std::time::Instant)>,
|
||||
interactable: Option<Interactable>,
|
||||
saved_zoom_dist: Option<f32>,
|
||||
hitboxes: HashMap<specs::Entity, DebugShapeId>,
|
||||
}
|
||||
|
||||
@ -125,7 +124,6 @@ impl SessionState {
|
||||
target_entity: None,
|
||||
selected_entity: None,
|
||||
interactable: None,
|
||||
saved_zoom_dist: None,
|
||||
hitboxes: HashMap::new(),
|
||||
}
|
||||
}
|
||||
@ -328,18 +326,8 @@ impl PlayState for SessionState {
|
||||
if cr.charge_frac() > 0.5 {
|
||||
fov_scaling -= 3.0 * cr.charge_frac() / 5.0;
|
||||
}
|
||||
let max_dist = if let Some(dist) = self.saved_zoom_dist {
|
||||
dist
|
||||
} else {
|
||||
let dist = camera.get_distance();
|
||||
self.saved_zoom_dist = Some(dist);
|
||||
dist
|
||||
};
|
||||
camera.set_distance(Lerp::lerp(max_dist, 2.0, 1.0 - fov_scaling));
|
||||
} else if let Some(dist) = self.saved_zoom_dist.take() {
|
||||
camera.set_distance(dist);
|
||||
}
|
||||
camera.set_fov((global_state.settings.graphics.fov as f32 * fov_scaling).to_radians());
|
||||
camera.set_fixate(fov_scaling);
|
||||
|
||||
// Compute camera data
|
||||
camera.compute_dependents(&*self.client.borrow().state().terrain());
|
||||
|
Loading…
x
Reference in New Issue
Block a user