mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
update toolchain to nightly-2024-01-17
This commit is contained in:
parent
6743386c4e
commit
6ebbb89d4d
@ -235,7 +235,7 @@ impl BotClient {
|
||||
continue;
|
||||
}
|
||||
|
||||
let c = list.characters.get(0).unwrap();
|
||||
let c = list.characters.first().unwrap();
|
||||
if let Some(id) = c.character.id {
|
||||
client.request_character(id, common::ViewDistances {
|
||||
terrain: 5,
|
||||
|
@ -15,6 +15,7 @@ pub struct PathEntry<S> {
|
||||
}
|
||||
|
||||
impl<S: Eq> PartialEq for PathEntry<S> {
|
||||
#[allow(clippy::unconditional_recursion)] // false positive as we use .node
|
||||
fn eq(&self, other: &PathEntry<S>) -> bool { self.node.eq(&other.node) }
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ where
|
||||
// Grab all comments from old file
|
||||
let source = fs::File::open(from.join(&path))?;
|
||||
let mut comments = Vec::new();
|
||||
for line in BufReader::new(source).lines().flatten() {
|
||||
for line in BufReader::new(source).lines().map_while(Result::ok) {
|
||||
if let Some(idx) = line.find("//") {
|
||||
let comment = &line[idx..line.len()];
|
||||
comments.push(comment.to_owned());
|
||||
|
@ -307,7 +307,9 @@ pub mod figuredata {
|
||||
let dyna = base_structure.vol.map_into(|cell| {
|
||||
if let Some(i) = cell {
|
||||
let color = base_structure.palette[u8::from(i) as usize];
|
||||
if let Some(block) = spec.custom_indices.get(&i.get()) && index == 0 {
|
||||
if let Some(block) = spec.custom_indices.get(&i.get())
|
||||
&& index == 0
|
||||
{
|
||||
block.to_block(color)
|
||||
} else {
|
||||
Block::new(BlockKind::Misc, color)
|
||||
|
@ -943,7 +943,6 @@ impl Inventory {
|
||||
/// account whether there will be free space in the inventory for the
|
||||
/// loadout item once any slots that were provided by it have been
|
||||
/// removed.
|
||||
#[allow(clippy::blocks_in_if_conditions)]
|
||||
pub fn can_swap(&self, inv_slot_id: InvSlotId, equip_slot: EquipSlot) -> bool {
|
||||
// Check if loadout slot can hold item
|
||||
if !self.get(inv_slot_id).map_or(true, |item| {
|
||||
@ -1004,10 +1003,11 @@ impl Inventory {
|
||||
let (slots_mut, recently_unequipped_items) =
|
||||
self.slots_mut_with_mutable_recently_unequipped_items();
|
||||
slots_mut.filter_map(|slot| slot.as_mut()).for_each(|item| {
|
||||
if item.durability_lost()
|
||||
.map_or(false, |dur| dur < Item::MAX_DURABILITY)
|
||||
if item
|
||||
.durability_lost()
|
||||
.map_or(false, |dur| dur < Item::MAX_DURABILITY)
|
||||
&& let Some((_unequip_time, count)) =
|
||||
recently_unequipped_items.get_mut(&item.item_definition_id())
|
||||
recently_unequipped_items.get_mut(&item.item_definition_id())
|
||||
&& *count > 0
|
||||
{
|
||||
*count -= 1;
|
||||
|
@ -506,8 +506,8 @@ impl SkillSet {
|
||||
let prerequisites_met = this.prerequisites_met(skill);
|
||||
// Check that skill is not yet at max level
|
||||
if !matches!(this.skills.get(&skill), Some(level) if *level == skill.max_level()) {
|
||||
if let Some(skill_group) = this.skill_groups.get(&skill_group_kind) &&
|
||||
this.skill_group_accessible_if_exists(skill_group_kind)
|
||||
if let Some(skill_group) = this.skill_groups.get(&skill_group_kind)
|
||||
&& this.skill_group_accessible_if_exists(skill_group_kind)
|
||||
{
|
||||
if prerequisites_met {
|
||||
if let Some(new_available_sp) = skill_group
|
||||
@ -521,8 +521,9 @@ impl SkillSet {
|
||||
// NOTE: Verified to exist previously when we accessed
|
||||
// this.skill_groups (assuming a non-pathological implementation of
|
||||
// ToOwned).
|
||||
let skill_group = this.skill_groups.get_mut(&skill_group_kind)
|
||||
.expect("Verified to exist when we previously accessed this.skill_groups");
|
||||
let skill_group = this.skill_groups.get_mut(&skill_group_kind).expect(
|
||||
"Verified to exist when we previously accessed this.skill_groups",
|
||||
);
|
||||
skill_group.available_sp = new_available_sp;
|
||||
skill_group.ordered_skills.push(skill);
|
||||
match skill {
|
||||
|
@ -605,24 +605,36 @@ pub fn handle_orientation(
|
||||
(a.to_quat().into_vec4() - b.to_quat().into_vec4()).reduce(|a, b| a.abs() + b.abs())
|
||||
}
|
||||
|
||||
let (tilt_ori, efficiency) = if let Body::Ship(ship) = data.body && ship.has_wheels() {
|
||||
let height_at = |rpos| data
|
||||
.terrain
|
||||
.ray(
|
||||
data.pos.0 + rpos + Vec3::unit_z() * 4.0,
|
||||
data.pos.0 + rpos - Vec3::unit_z() * 4.0,
|
||||
)
|
||||
.until(Block::is_solid)
|
||||
.cast()
|
||||
.0;
|
||||
let (tilt_ori, efficiency) = if let Body::Ship(ship) = data.body
|
||||
&& ship.has_wheels()
|
||||
{
|
||||
let height_at = |rpos| {
|
||||
data.terrain
|
||||
.ray(
|
||||
data.pos.0 + rpos + Vec3::unit_z() * 4.0,
|
||||
data.pos.0 + rpos - Vec3::unit_z() * 4.0,
|
||||
)
|
||||
.until(Block::is_solid)
|
||||
.cast()
|
||||
.0
|
||||
};
|
||||
|
||||
// Do some cheap raycasting with the ground to determine the appropriate orientation for the vehicle
|
||||
let x_diff = (height_at(data.ori.to_horizontal().right().to_vec() * 3.0) - height_at(data.ori.to_horizontal().right().to_vec() * -3.0)) / 10.0;
|
||||
let y_diff = (height_at(data.ori.to_horizontal().look_dir().to_vec() * -4.5) - height_at(data.ori.to_horizontal().look_dir().to_vec() * 4.5)) / 10.0;
|
||||
// Do some cheap raycasting with the ground to determine the appropriate
|
||||
// orientation for the vehicle
|
||||
let x_diff = (height_at(data.ori.to_horizontal().right().to_vec() * 3.0)
|
||||
- height_at(data.ori.to_horizontal().right().to_vec() * -3.0))
|
||||
/ 10.0;
|
||||
let y_diff = (height_at(data.ori.to_horizontal().look_dir().to_vec() * -4.5)
|
||||
- height_at(data.ori.to_horizontal().look_dir().to_vec() * 4.5))
|
||||
/ 10.0;
|
||||
|
||||
(
|
||||
Quaternion::rotation_y(x_diff.atan()) * Quaternion::rotation_x(y_diff.atan()),
|
||||
(data.vel.0 - data.physics.ground_vel).xy().magnitude().max(3.0) * efficiency,
|
||||
(data.vel.0 - data.physics.ground_vel)
|
||||
.xy()
|
||||
.magnitude()
|
||||
.max(3.0)
|
||||
* efficiency,
|
||||
)
|
||||
} else {
|
||||
(Quaternion::identity(), efficiency)
|
||||
|
@ -161,7 +161,7 @@ pub(crate) fn load_base_structure<B: Default>(
|
||||
mut to_block: impl FnMut(Rgb<u8>) -> B,
|
||||
) -> BaseStructure<B> {
|
||||
let mut palette = std::array::from_fn(|_| B::default());
|
||||
if let Some(model) = dot_vox_data.models.get(0) {
|
||||
if let Some(model) = dot_vox_data.models.first() {
|
||||
for (i, col) in dot_vox_data
|
||||
.palette
|
||||
.iter()
|
||||
|
@ -864,15 +864,18 @@ impl<'a> PhysicsData<'a> {
|
||||
character_state.map_or(false, |cs| matches!(cs, CharacterState::Climb(_)));
|
||||
|
||||
let friction_factor = |vel: Vec3<f32>| {
|
||||
if let Some(Body::Ship(ship)) = body && ship.has_wheels() {
|
||||
vel
|
||||
.try_normalized()
|
||||
.and_then(|dir| Some(orientations.get(entity)?.right().dot(dir).abs()))
|
||||
.unwrap_or(1.0)
|
||||
.max(0.2)
|
||||
} else {
|
||||
1.0
|
||||
}
|
||||
if let Some(Body::Ship(ship)) = body
|
||||
&& ship.has_wheels()
|
||||
{
|
||||
vel.try_normalized()
|
||||
.and_then(|dir| {
|
||||
Some(orientations.get(entity)?.right().dot(dir).abs())
|
||||
})
|
||||
.unwrap_or(1.0)
|
||||
.max(0.2)
|
||||
} else {
|
||||
1.0
|
||||
}
|
||||
};
|
||||
|
||||
match &collider {
|
||||
|
@ -7,8 +7,6 @@ pub use retrieve::*;
|
||||
|
||||
use std::convert::TryInto;
|
||||
|
||||
pub use retrieve::*;
|
||||
|
||||
pub use plugin_api as api;
|
||||
pub use plugin_derive::*;
|
||||
|
||||
|
@ -110,11 +110,7 @@ fn rugged_ser_enum_map<
|
||||
map: &EnumMap<K, V>,
|
||||
ser: S,
|
||||
) -> Result<S::Ok, S::Error> {
|
||||
ser.collect_map(
|
||||
map.iter()
|
||||
.filter(|(_, v)| v != &&V::from(DEFAULT))
|
||||
.map(|(k, v)| (k, v)),
|
||||
)
|
||||
ser.collect_map(map.iter().filter(|(_, v)| v != &&V::from(DEFAULT)))
|
||||
}
|
||||
|
||||
fn rugged_de_enum_map<
|
||||
|
@ -337,8 +337,10 @@ impl NpcLinks {
|
||||
if Actor::Npc(mount) == rider {
|
||||
return Err(MountingError::MountSelf);
|
||||
}
|
||||
if let Actor::Npc(rider) = rider && self.mount_map.contains_key(rider) {
|
||||
return Err(MountingError::RiderIsMounted);
|
||||
if let Actor::Npc(rider) = rider
|
||||
&& self.mount_map.contains_key(rider)
|
||||
{
|
||||
return Err(MountingError::RiderIsMounted);
|
||||
}
|
||||
if self.rider_map.contains_key(&Actor::Npc(mount)) {
|
||||
return Err(MountingError::MountIsRiding);
|
||||
|
@ -1,10 +1,7 @@
|
||||
#![feature(
|
||||
never_type,
|
||||
try_blocks,
|
||||
generator_trait,
|
||||
generators,
|
||||
trait_alias,
|
||||
trait_upcasting,
|
||||
control_flow_enum,
|
||||
let_chains,
|
||||
binary_heap_drain_sorted,
|
||||
|
@ -61,23 +61,33 @@ impl Rule for Migrate {
|
||||
}
|
||||
}
|
||||
|
||||
// Reassign NPCs to sites if their old one was deleted. If they were already homeless, no need to do anything.
|
||||
// Reassign NPCs to sites if their old one was deleted. If they were already
|
||||
// homeless, no need to do anything.
|
||||
for npc in data.npcs.values_mut() {
|
||||
if let Some(home) = npc.home
|
||||
&& !data.sites.contains_key(home)
|
||||
{
|
||||
// Choose the closest habitable site as the new home for the NPC
|
||||
npc.home = data.sites.sites
|
||||
npc.home = data
|
||||
.sites
|
||||
.sites
|
||||
.iter()
|
||||
.filter(|(_, site)| {
|
||||
// TODO: This is a bit silly, but needs to wait on the removal of site1
|
||||
site.world_site.map_or(false, |ws| matches!(&ctx.index.sites.get(ws).kind, SiteKind::Refactor(_)
|
||||
| SiteKind::CliffTown(_)
|
||||
| SiteKind::SavannahPit(_)
|
||||
| SiteKind::CoastalTown(_)
|
||||
| SiteKind::DesertCity(_)))
|
||||
site.world_site.map_or(false, |ws| {
|
||||
matches!(
|
||||
&ctx.index.sites.get(ws).kind,
|
||||
SiteKind::Refactor(_)
|
||||
| SiteKind::CliffTown(_)
|
||||
| SiteKind::SavannahPit(_)
|
||||
| SiteKind::CoastalTown(_)
|
||||
| SiteKind::DesertCity(_)
|
||||
)
|
||||
})
|
||||
})
|
||||
.min_by_key(|(_, site)| {
|
||||
site.wpos.as_().distance_squared(npc.wpos.xy()) as i32
|
||||
})
|
||||
.min_by_key(|(_, site)| site.wpos.as_().distance_squared(npc.wpos.xy()) as i32)
|
||||
.map(|(site_id, _)| site_id);
|
||||
}
|
||||
}
|
||||
|
@ -594,25 +594,46 @@ fn talk_to<S: State>(tgt: Actor, _subject: Option<Subject>) -> impl Action<S> +
|
||||
&& let Some(current_site) = ctx.state.data().sites.get(current_site)
|
||||
&& let Some(mention_site) = current_site.nearby_sites_by_size.choose(&mut ctx.rng)
|
||||
&& let Some(mention_site) = ctx.state.data().sites.get(*mention_site)
|
||||
&& let Some(mention_site_name) = mention_site.world_site
|
||||
&& let Some(mention_site_name) = mention_site
|
||||
.world_site
|
||||
.map(|ws| ctx.index.sites.get(ws).name().to_string())
|
||||
{
|
||||
Content::localized_with_args("npc-speech-tell_site", [
|
||||
("site", Content::Plain(mention_site_name)),
|
||||
("dir", Direction::from_dir(mention_site.wpos.as_() - ctx.npc.wpos.xy()).localize_npc()),
|
||||
("dist", Distance::from_length(mention_site.wpos.as_().distance(ctx.npc.wpos.xy()) as i32).localize_npc()),
|
||||
(
|
||||
"dir",
|
||||
Direction::from_dir(mention_site.wpos.as_() - ctx.npc.wpos.xy())
|
||||
.localize_npc(),
|
||||
),
|
||||
(
|
||||
"dist",
|
||||
Distance::from_length(
|
||||
mention_site.wpos.as_().distance(ctx.npc.wpos.xy()) as i32
|
||||
)
|
||||
.localize_npc(),
|
||||
),
|
||||
])
|
||||
// Mention nearby monsters
|
||||
} else if ctx.rng.gen_bool(0.3)
|
||||
&& let Some(monster) = ctx.state.data().npcs
|
||||
&& let Some(monster) = ctx
|
||||
.state
|
||||
.data()
|
||||
.npcs
|
||||
.values()
|
||||
.filter(|other| matches!(&other.role, Role::Monster))
|
||||
.min_by_key(|other| other.wpos.xy().distance(ctx.npc.wpos.xy()) as i32)
|
||||
{
|
||||
Content::localized_with_args("npc-speech-tell_monster", [
|
||||
("body", monster.body.localize_npc()),
|
||||
("dir", Direction::from_dir(monster.wpos.xy() - ctx.npc.wpos.xy()).localize_npc()),
|
||||
("dist", Distance::from_length(monster.wpos.xy().distance(ctx.npc.wpos.xy()) as i32).localize_npc()),
|
||||
(
|
||||
"dir",
|
||||
Direction::from_dir(monster.wpos.xy() - ctx.npc.wpos.xy()).localize_npc(),
|
||||
),
|
||||
(
|
||||
"dist",
|
||||
Distance::from_length(monster.wpos.xy().distance(ctx.npc.wpos.xy()) as i32)
|
||||
.localize_npc(),
|
||||
),
|
||||
])
|
||||
} else {
|
||||
ctx.npc.personality.get_generic_comment(&mut ctx.rng)
|
||||
|
@ -33,11 +33,18 @@ fn on_mount_volume(ctx: EventCtx<SimulateNpcs, OnMountVolume>) {
|
||||
let data = &mut *ctx.state.data_mut();
|
||||
|
||||
// TODO: Add actor to riders.
|
||||
if let VolumePos { kind: Volume::Entity(vehicle), .. } = ctx.event.pos
|
||||
if let VolumePos {
|
||||
kind: Volume::Entity(vehicle),
|
||||
..
|
||||
} = ctx.event.pos
|
||||
&& let Some(link) = data.npcs.mounts.get_steerer_link(vehicle)
|
||||
&& let Actor::Npc(driver) = link.rider
|
||||
&& let Some(driver) = data.npcs.get_mut(driver) {
|
||||
driver.controller.actions.push(NpcAction::Say(Some(ctx.event.actor), comp::Content::localized("npc-speech-welcome-aboard")))
|
||||
&& let Some(driver) = data.npcs.get_mut(driver)
|
||||
{
|
||||
driver.controller.actions.push(NpcAction::Say(
|
||||
Some(ctx.event.actor),
|
||||
comp::Content::localized("npc-speech-welcome-aboard"),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,14 +104,14 @@ fn on_tick(ctx: EventCtx<SyncNpcs, OnTick>) {
|
||||
{
|
||||
if let Some(site) = data.sites.get_mut(current_site) {
|
||||
// TODO: Sites should have an inbox and their own AI code
|
||||
site.known_reports.extend(npc.known_reports
|
||||
.iter()
|
||||
.copied());
|
||||
npc.inbox.extend(site.known_reports
|
||||
.iter()
|
||||
.copied()
|
||||
.filter(|report| !npc.known_reports.contains(report))
|
||||
.map(NpcInput::Report));
|
||||
site.known_reports.extend(npc.known_reports.iter().copied());
|
||||
npc.inbox.extend(
|
||||
site.known_reports
|
||||
.iter()
|
||||
.copied()
|
||||
.filter(|report| !npc.known_reports.contains(report))
|
||||
.map(NpcInput::Report),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1 +1 @@
|
||||
nightly-2023-09-28
|
||||
nightly-2024-01-17
|
||||
|
@ -221,7 +221,9 @@ impl ChatForwarder {
|
||||
while let Some(msg) = self.chat_r.recv().await {
|
||||
let drop_older_than = msg.time.sub(self.keep_duration);
|
||||
let mut messages = self.messages.lock().await;
|
||||
while let Some(msg) = messages.front() && msg.time < drop_older_than {
|
||||
while let Some(msg) = messages.front()
|
||||
&& msg.time < drop_older_than
|
||||
{
|
||||
messages.pop_front();
|
||||
}
|
||||
messages.push_back(msg);
|
||||
|
@ -549,7 +549,9 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, last_change: Healt
|
||||
|
||||
// TODO: Do we need to do this if `should_delete` is true?
|
||||
// Modify durability on all equipped items
|
||||
if !resists_durability && let Some(mut inventory) = state.ecs().write_storage::<Inventory>().get_mut(entity) {
|
||||
if !resists_durability
|
||||
&& let Some(mut inventory) = state.ecs().write_storage::<Inventory>().get_mut(entity)
|
||||
{
|
||||
let ecs = state.ecs();
|
||||
let ability_map = ecs.read_resource::<AbilityMap>();
|
||||
let msm = ecs.read_resource::<MaterialStatManifest>();
|
||||
@ -1406,7 +1408,9 @@ pub fn handle_parry_hook(
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(attacker) = attacker && matches!(source, AttackSource::Melee){
|
||||
if let Some(attacker) = attacker
|
||||
&& matches!(source, AttackSource::Melee)
|
||||
{
|
||||
// When attacker is parried, add the parried debuff for 2 seconds, which slows
|
||||
// them
|
||||
let data = buff::BuffData::new(1.0, Some(Secs(2.0)));
|
||||
|
@ -99,10 +99,12 @@ pub fn handle_npc_interaction(
|
||||
})
|
||||
};
|
||||
|
||||
if within_range && let Some(agent) = state
|
||||
.ecs()
|
||||
.write_storage::<comp::Agent>()
|
||||
.get_mut(npc_entity) && agent.target.is_none()
|
||||
if within_range
|
||||
&& let Some(agent) = state
|
||||
.ecs()
|
||||
.write_storage::<comp::Agent>()
|
||||
.get_mut(npc_entity)
|
||||
&& agent.target.is_none()
|
||||
{
|
||||
if let Some(interactor_uid) = state.ecs().uid_from_entity(interactor) {
|
||||
agent
|
||||
@ -179,21 +181,28 @@ pub fn handle_mount_volume(server: &mut Server, rider: EcsEntity, volume_pos: Vo
|
||||
);
|
||||
|
||||
if let Some((mat, _, block)) = block_transform
|
||||
&& let Some(mount_offset) = block.mount_offset() {
|
||||
&& let Some(mount_offset) = block.mount_offset()
|
||||
{
|
||||
let mount_pos = (mat * mount_offset.0.with_w(1.0)).xyz();
|
||||
let within_range = {
|
||||
let positions = state.ecs().read_storage::<Pos>();
|
||||
positions.get(rider).map_or(false, |pos| pos.0.distance_squared(mount_pos) < MAX_SPRITE_MOUNT_RANGE.powi(2))
|
||||
positions.get(rider).map_or(false, |pos| {
|
||||
pos.0.distance_squared(mount_pos) < MAX_SPRITE_MOUNT_RANGE.powi(2)
|
||||
})
|
||||
};
|
||||
|
||||
let maybe_uid = state.ecs().read_storage::<Uid>().get(rider).copied();
|
||||
|
||||
if let Some(rider) = maybe_uid && within_range {
|
||||
let _link_successful = state.link(VolumeMounting {
|
||||
pos: volume_pos,
|
||||
block,
|
||||
rider,
|
||||
}).is_ok();
|
||||
if let Some(rider) = maybe_uid
|
||||
&& within_range
|
||||
{
|
||||
let _link_successful = state
|
||||
.link(VolumeMounting {
|
||||
pos: volume_pos,
|
||||
block,
|
||||
rider,
|
||||
})
|
||||
.is_ok();
|
||||
#[cfg(feature = "worldgen")]
|
||||
if _link_successful {
|
||||
let uid_allocator = state.ecs().read_resource::<IdMaps>();
|
||||
@ -202,13 +211,20 @@ pub fn handle_mount_volume(server: &mut Server, rider: EcsEntity, volume_pos: Vo
|
||||
&& let Some(volume_pos) = volume_pos.try_map_entity(|uid| {
|
||||
let entity = uid_allocator.uid_entity(uid)?;
|
||||
state.read_storage::<RtSimEntity>().get(entity).map(|v| v.0)
|
||||
}) {
|
||||
state.ecs().write_resource::<RtSim>().hook_character_mount_volume(
|
||||
})
|
||||
{
|
||||
state
|
||||
.ecs()
|
||||
.write_resource::<RtSim>()
|
||||
.hook_character_mount_volume(
|
||||
&state.ecs().read_resource::<Arc<world::World>>(),
|
||||
state.ecs().read_resource::<world::IndexOwned>().as_index_ref(),
|
||||
state
|
||||
.ecs()
|
||||
.read_resource::<world::IndexOwned>()
|
||||
.as_index_ref(),
|
||||
volume_pos,
|
||||
rider_actor,
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ pub fn snuff_lantern(storage: &mut WriteStorage<LightEmitter>, entity: EcsEntity
|
||||
storage.remove(entity);
|
||||
}
|
||||
|
||||
#[allow(clippy::blocks_in_if_conditions)]
|
||||
#[allow(clippy::blocks_in_conditions)]
|
||||
pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::InventoryManip) {
|
||||
let state = server.state_mut();
|
||||
|
||||
|
@ -101,8 +101,8 @@ pub fn handle_exit_ingame(server: &mut Server, entity: EcsEntity, skip_persisten
|
||||
state.mut_resource::<IdMaps>().remap_entity(uid, new_entity);
|
||||
|
||||
let ecs = state.ecs();
|
||||
// Note, we use `delete_entity_common` directly to avoid `delete_entity_recorded` from
|
||||
// making any changes to the group.
|
||||
// Note, we use `delete_entity_common` directly to avoid
|
||||
// `delete_entity_recorded` from making any changes to the group.
|
||||
if let Some(group) = maybe_group {
|
||||
let mut group_manager = ecs.write_resource::<group::GroupManager>();
|
||||
if group_manager
|
||||
|
@ -1,6 +1,7 @@
|
||||
#![deny(unsafe_code)]
|
||||
#![allow(
|
||||
clippy::option_map_unit_fn,
|
||||
clippy::blocks_in_conditions,
|
||||
clippy::needless_pass_by_ref_mut //until we find a better way for specs
|
||||
)]
|
||||
#![deny(clippy::clone_on_ref_ptr)]
|
||||
|
@ -89,15 +89,13 @@ pub fn handle_inbox_talk(bdata: &mut BehaviorData) -> bool {
|
||||
let by_entity = get_entity_by_id(by, read_data);
|
||||
|
||||
if let Some(rtsim_outbox) = &mut agent.rtsim_outbox {
|
||||
if let Subject::Regular
|
||||
| Subject::Mood
|
||||
| Subject::Work = subject
|
||||
if let Subject::Regular | Subject::Mood | Subject::Work = subject
|
||||
&& let Some(by_entity) = by_entity
|
||||
&& let Some(actor) = read_data.presences
|
||||
&& let Some(actor) = read_data
|
||||
.presences
|
||||
.get(by_entity)
|
||||
.and_then(|p| p.kind.character_id().map(Actor::Character))
|
||||
.or_else(|| Some(Actor::Npc(read_data.rtsim_entities
|
||||
.get(by_entity)?.0)))
|
||||
.or_else(|| Some(Actor::Npc(read_data.rtsim_entities.get(by_entity)?.0)))
|
||||
{
|
||||
rtsim_outbox.push_back(NpcInput::Interaction(actor, subject));
|
||||
return false;
|
||||
|
@ -334,8 +334,22 @@ impl<'a> System<'a> for Sys {
|
||||
);
|
||||
|
||||
if include_all_comps && let Some(&pos) = maybe_pos {
|
||||
let send_now = should_sync_client_physics(entity, &player_physics_settings, &players, &force_updates, is_rider);
|
||||
add_physics_components(send_now, &mut comp_sync_package, uid, pos, last_pos, ori, vel);
|
||||
let send_now = should_sync_client_physics(
|
||||
entity,
|
||||
&player_physics_settings,
|
||||
&players,
|
||||
&force_updates,
|
||||
is_rider,
|
||||
);
|
||||
add_physics_components(
|
||||
send_now,
|
||||
&mut comp_sync_package,
|
||||
uid,
|
||||
pos,
|
||||
last_pos,
|
||||
ori,
|
||||
vel,
|
||||
);
|
||||
}
|
||||
|
||||
if !comp_sync_package.is_empty() {
|
||||
|
@ -77,11 +77,13 @@ impl Sys {
|
||||
match msg {
|
||||
// Request spectator state
|
||||
ClientGeneral::Spectate(requested_view_distances) => {
|
||||
if let Some(admin) = admins.get(entity) && admin.0 >= AdminRole::Moderator {
|
||||
if let Some(admin) = admins.get(entity)
|
||||
&& admin.0 >= AdminRole::Moderator
|
||||
{
|
||||
send_join_messages()?;
|
||||
|
||||
server_emitter.emit(ServerEvent::InitSpectator(entity, requested_view_distances));
|
||||
|
||||
server_emitter
|
||||
.emit(ServerEvent::InitSpectator(entity, requested_view_distances));
|
||||
} else {
|
||||
debug!("dropped Spectate msg from unprivileged client")
|
||||
}
|
||||
@ -96,8 +98,7 @@ impl Sys {
|
||||
// this.
|
||||
if presences.contains(entity) {
|
||||
debug!("player already ingame, aborting");
|
||||
} else if character_updater.has_pending_database_action(character_id)
|
||||
{
|
||||
} else if character_updater.has_pending_database_action(character_id) {
|
||||
debug!("player recently logged out pending persistence, aborting");
|
||||
client.send(ServerGeneral::CharacterDataLoadResult(Err(
|
||||
"You have recently logged out, please wait a few seconds and try again"
|
||||
@ -171,19 +172,35 @@ impl Sys {
|
||||
body,
|
||||
character_updater,
|
||||
start_site.and_then(|site_idx| {
|
||||
// TODO: This corresponds to the ID generation logic in `world/src/lib.rs`
|
||||
// Really, we should have a way to consistently refer to sites, but that's a job for rtsim2
|
||||
// and the site changes that it will require. Until then, this code is very hacky.
|
||||
world.civs().sites.iter()
|
||||
// TODO: This corresponds to the ID generation logic in
|
||||
// `world/src/lib.rs`. Really, we should have
|
||||
// a way to consistently refer to sites, but that's a job for rtsim2
|
||||
// and the site changes that it will require. Until then, this code is
|
||||
// very hacky.
|
||||
world
|
||||
.civs()
|
||||
.sites
|
||||
.iter()
|
||||
.find(|(_, site)| site.site_tmp.map(|i| i.id()) == Some(site_idx))
|
||||
.map(Some)
|
||||
.unwrap_or_else(|| {
|
||||
error!("Tried to create character with starting site index {}, but such a site does not exist", site_idx);
|
||||
error!(
|
||||
"Tried to create character with starting site index {}, \
|
||||
but such a site does not exist",
|
||||
site_idx
|
||||
);
|
||||
None
|
||||
})
|
||||
.map(|(_, site)| {
|
||||
let wpos2d = TerrainChunkSize::center_wpos(site.center);
|
||||
Waypoint::new(world.find_accessible_pos(index.as_index_ref(), wpos2d, false), time)
|
||||
Waypoint::new(
|
||||
world.find_accessible_pos(
|
||||
index.as_index_ref(),
|
||||
wpos2d,
|
||||
false,
|
||||
),
|
||||
time,
|
||||
)
|
||||
})
|
||||
}),
|
||||
) {
|
||||
|
@ -85,8 +85,12 @@ impl Sys {
|
||||
ClientGeneral::SetViewDistance(view_distances) => {
|
||||
let clamped_vds = view_distances.clamp(settings.max_view_distance);
|
||||
|
||||
presence.terrain_view_distance.set_target(clamped_vds.terrain, time_for_vd_changes);
|
||||
presence.entity_view_distance.set_target(clamped_vds.entity, time_for_vd_changes);
|
||||
presence
|
||||
.terrain_view_distance
|
||||
.set_target(clamped_vds.terrain, time_for_vd_changes);
|
||||
presence
|
||||
.entity_view_distance
|
||||
.set_target(clamped_vds.entity, time_for_vd_changes);
|
||||
|
||||
// Correct client if its requested VD is too high.
|
||||
if view_distances.terrain != clamped_vds.terrain {
|
||||
@ -101,7 +105,9 @@ impl Sys {
|
||||
}
|
||||
},
|
||||
ClientGeneral::ControlEvent(event) => {
|
||||
if presence.kind.controlling_char() && let Some(controller) = controller {
|
||||
if presence.kind.controlling_char()
|
||||
&& let Some(controller) = controller
|
||||
{
|
||||
// Skip respawn if client entity is alive
|
||||
let skip_respawn = matches!(event, ControlEvent::Respawn)
|
||||
&& healths.get(entity).map_or(true, |h| !h.is_dead);
|
||||
@ -118,9 +124,15 @@ impl Sys {
|
||||
}
|
||||
}
|
||||
},
|
||||
ClientGeneral::PlayerPhysics { pos, vel, ori, force_counter } => {
|
||||
ClientGeneral::PlayerPhysics {
|
||||
pos,
|
||||
vel,
|
||||
ori,
|
||||
force_counter,
|
||||
} => {
|
||||
if presence.kind.controlling_char()
|
||||
&& force_update.map_or(true, |force_update| force_update.counter() == force_counter)
|
||||
&& force_update
|
||||
.map_or(true, |force_update| force_update.counter() == force_counter)
|
||||
&& healths.get(entity).map_or(true, |h| !h.is_dead)
|
||||
&& is_rider.get(entity).is_none()
|
||||
&& is_volume_rider.get(entity).is_none()
|
||||
@ -146,10 +158,12 @@ impl Sys {
|
||||
let new_block = old_block.into_vacant();
|
||||
// Take the rare writes lock as briefly as possible.
|
||||
let mut guard = rare_writes.lock();
|
||||
let _was_set = guard.block_changes.try_set(pos, new_block).is_some();
|
||||
let _was_set =
|
||||
guard.block_changes.try_set(pos, new_block).is_some();
|
||||
#[cfg(feature = "persistent_world")]
|
||||
if _was_set {
|
||||
if let Some(terrain_persistence) = guard._terrain_persistence.as_mut()
|
||||
if let Some(terrain_persistence) =
|
||||
guard._terrain_persistence.as_mut()
|
||||
{
|
||||
terrain_persistence.set_block(pos, new_block);
|
||||
}
|
||||
@ -173,10 +187,12 @@ impl Sys {
|
||||
{
|
||||
// Take the rare writes lock as briefly as possible.
|
||||
let mut guard = rare_writes.lock();
|
||||
let _was_set = guard.block_changes.try_set(pos, new_block).is_some();
|
||||
let _was_set =
|
||||
guard.block_changes.try_set(pos, new_block).is_some();
|
||||
#[cfg(feature = "persistent_world")]
|
||||
if _was_set {
|
||||
if let Some(terrain_persistence) = guard._terrain_persistence.as_mut()
|
||||
if let Some(terrain_persistence) =
|
||||
guard._terrain_persistence.as_mut()
|
||||
{
|
||||
terrain_persistence.set_block(pos, new_block);
|
||||
}
|
||||
@ -188,9 +204,12 @@ impl Sys {
|
||||
},
|
||||
ClientGeneral::UnlockSkill(skill) => {
|
||||
// FIXME: How do we want to handle the error? Probably not by swallowing it.
|
||||
let _ = skill_set.as_mut().map(|skill_set| {
|
||||
SkillSet::unlock_skill_cow(skill_set, skill, |skill_set| skill_set.to_mut())
|
||||
}).transpose();
|
||||
let _ = skill_set
|
||||
.as_mut()
|
||||
.map(|skill_set| {
|
||||
SkillSet::unlock_skill_cow(skill_set, skill, |skill_set| skill_set.to_mut())
|
||||
})
|
||||
.transpose();
|
||||
},
|
||||
ClientGeneral::RequestSiteInfo(id) => {
|
||||
server_emitter.emit(ServerEvent::RequestSiteInfo { entity, id });
|
||||
@ -211,7 +230,10 @@ impl Sys {
|
||||
server_emitter.emit(ServerEvent::UpdateMapMarker { entity, update });
|
||||
},
|
||||
ClientGeneral::SpectatePosition(pos) => {
|
||||
if let Some(admin) = maybe_admin && admin.0 >= AdminRole::Moderator && presence.kind == PresenceKind::Spectator {
|
||||
if let Some(admin) = maybe_admin
|
||||
&& admin.0 >= AdminRole::Moderator
|
||||
&& presence.kind == PresenceKind::Spectator
|
||||
{
|
||||
if let Some(position) = position {
|
||||
position.0 = pos;
|
||||
}
|
||||
|
@ -59,7 +59,9 @@ impl<'a> System<'a> for Sys {
|
||||
|
||||
for (pet_entity, owner_pos) in lost_pets.iter() {
|
||||
let stay = agn.get(*pet_entity).and_then(|x| x.stay_pos).is_some();
|
||||
if let Some(pet_pos) = positions.get_mut(*pet_entity) && !stay{
|
||||
if let Some(pet_pos) = positions.get_mut(*pet_entity)
|
||||
&& !stay
|
||||
{
|
||||
// Move the pets to their owner's position
|
||||
// TODO: Create a teleportation event to handle this instead of
|
||||
// processing the entity position move here
|
||||
|
@ -41,7 +41,7 @@ impl<'a> System<'a> for Sys {
|
||||
const ORIGIN: Origin = Origin::Server;
|
||||
const PHASE: Phase = Phase::Create;
|
||||
|
||||
#[allow(clippy::blocks_in_if_conditions)] // TODO: Pending review in #587
|
||||
#[allow(clippy::blocks_in_conditions)] // TODO: Pending review in #587
|
||||
fn run(
|
||||
_job: &mut Job<Self>,
|
||||
(
|
||||
|
@ -22,6 +22,7 @@ use super::{
|
||||
};
|
||||
|
||||
enum WeatherJobState {
|
||||
#[allow(dead_code)]
|
||||
Working(SlowJob),
|
||||
Idle(WeatherSim),
|
||||
None,
|
||||
@ -108,7 +109,8 @@ impl<'a> System<'a> for Sys {
|
||||
|
||||
if let Some(weather_job) = to_update {
|
||||
if matches!(weather_job.state, WeatherJobState::Working(_))
|
||||
&& let Ok((new_grid, new_lightning_cells, sim)) = weather_job.weather_rx.try_recv() {
|
||||
&& let Ok((new_grid, new_lightning_cells, sim)) = weather_job.weather_rx.try_recv()
|
||||
{
|
||||
*grid = new_grid;
|
||||
*lightning_cells = new_lightning_cells;
|
||||
let mut lazy_msg = None;
|
||||
@ -121,7 +123,6 @@ impl<'a> System<'a> for Sys {
|
||||
lazy_msg.as_ref().map(|msg| client.send_prepared(msg));
|
||||
}
|
||||
weather_job.state = WeatherJobState::Idle(sim);
|
||||
|
||||
}
|
||||
|
||||
if matches!(weather_job.state, WeatherJobState::Idle(_)) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
pub use ::vek::{
|
||||
bezier::repr_simd::*, geom::repr_simd::*, mat::repr_simd::column_major::Mat4, ops::*,
|
||||
quaternion::repr_simd::*, transform::repr_simd::*, transition::*, vec::repr_simd::*,
|
||||
geom::repr_simd::*, mat::repr_simd::column_major::Mat4, ops::*, quaternion::repr_simd::*,
|
||||
transform::repr_simd::*, transition::*, vec::repr_simd::*,
|
||||
};
|
||||
/*pub use ::vek::{
|
||||
bezier::repr_c::*, geom::repr_c::*, mat::repr_c::column_major::Mat4, ops::*,
|
||||
|
@ -134,7 +134,9 @@ pub fn localize_chat_message(
|
||||
let message_format = |from: &Uid, content: &Content, group: Option<&String>| {
|
||||
let alias = name_format_or_complex(true, from);
|
||||
|
||||
let name = if let Some(pi) = info.player_info.get(from).cloned() && show_char_name {
|
||||
let name = if let Some(pi) = info.player_info.get(from).cloned()
|
||||
&& show_char_name
|
||||
{
|
||||
pi.character.map(|c| c.name)
|
||||
} else {
|
||||
None
|
||||
|
@ -36,6 +36,7 @@ impl OggSound {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::implied_bounds_in_impls)]
|
||||
pub fn load_ogg(specifier: &str) -> impl Source + Iterator<Item = i16> {
|
||||
OggSound::load_or_insert_with(specifier, |error| {
|
||||
warn!(?specifier, ?error, "Failed to load sound");
|
||||
|
@ -27,7 +27,7 @@ impl<'a> System<'a> for Sys {
|
||||
const ORIGIN: Origin = Origin::Frontend("voxygen");
|
||||
const PHASE: Phase = Phase::Create;
|
||||
|
||||
#[allow(clippy::blocks_in_if_conditions)] // TODO: Pending review in #587
|
||||
#[allow(clippy::blocks_in_conditions)] // TODO: Pending review in #587
|
||||
fn run(
|
||||
_job: &mut Job<Self>,
|
||||
(entities, my_entity, dt, pos, healths, mut hp_floater_lists): Self::SystemData,
|
||||
|
@ -719,7 +719,7 @@ impl<'a> Widget for Chat<'a> {
|
||||
// Update the history
|
||||
// Don't add if this is identical to the last message in the history
|
||||
s.history_pos = 0;
|
||||
if s.history.get(0).map_or(true, |h| h != &msg) {
|
||||
if s.history.front().map_or(true, |h| h != &msg) {
|
||||
s.history.push_front(msg.clone());
|
||||
s.history.truncate(self.history_max);
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ impl<'a> Widget for Group<'a> {
|
||||
//TODO: Disband groups when there's only one member in them
|
||||
//TODO: Always send health, energy, level and position of group members to the
|
||||
// client
|
||||
#[allow(clippy::blocks_in_if_conditions)] // TODO: Pending review in #587
|
||||
#[allow(clippy::blocks_in_conditions)] // TODO: Pending review in #587
|
||||
fn update(self, args: widget::UpdateArgs<Self>) -> Self::Event {
|
||||
common_base::prof_span!("Group::update");
|
||||
let widget::UpdateArgs { state, ui, .. } = args;
|
||||
|
@ -2042,9 +2042,14 @@ impl Hud {
|
||||
&& let Some((mat, _, _)) = pos.get_block_and_transform(
|
||||
&ecs.read_resource(),
|
||||
&ecs.read_resource(),
|
||||
|e| ecs.read_storage::<vcomp::Interpolated>().get(e).map(|interpolated| (comp::Pos(interpolated.pos), interpolated.ori)),
|
||||
|e| {
|
||||
ecs.read_storage::<vcomp::Interpolated>()
|
||||
.get(e)
|
||||
.map(|interpolated| (comp::Pos(interpolated.pos), interpolated.ori))
|
||||
},
|
||||
&ecs.read_storage(),
|
||||
) {
|
||||
)
|
||||
{
|
||||
let overitem_id = overitem_walker.next(
|
||||
&mut self.ids.overitems,
|
||||
&mut ui_widgets.widget_id_generator(),
|
||||
@ -2129,7 +2134,12 @@ impl Hud {
|
||||
BlockInteraction::Mount => {
|
||||
let key = match block.get_sprite() {
|
||||
Some(SpriteKind::Helm) => "hud-steer",
|
||||
Some(SpriteKind::Bed | SpriteKind::Bedroll | SpriteKind::BedrollSnow | SpriteKind::BedrollPirate) => "hud-lay",
|
||||
Some(
|
||||
SpriteKind::Bed
|
||||
| SpriteKind::Bedroll
|
||||
| SpriteKind::BedrollSnow
|
||||
| SpriteKind::BedrollPirate,
|
||||
) => "hud-lay",
|
||||
_ => "hud-sit",
|
||||
};
|
||||
vec![(Some(GameInput::Mount), i18n.get_msg(key).to_string())]
|
||||
@ -2141,7 +2151,12 @@ impl Hud {
|
||||
// TODO: change to turn on/turn off?
|
||||
BlockInteraction::LightToggle(enable) => vec![(
|
||||
Some(GameInput::Interact),
|
||||
i18n.get_msg(if *enable { "hud-activate" } else { "hud-deactivate" }).to_string(),
|
||||
i18n.get_msg(if *enable {
|
||||
"hud-activate"
|
||||
} else {
|
||||
"hud-deactivate"
|
||||
})
|
||||
.to_string(),
|
||||
)],
|
||||
};
|
||||
|
||||
@ -2170,7 +2185,11 @@ impl Hud {
|
||||
// TODO: Handle this better. The items returned from `try_reclaim_from_block`
|
||||
// are based on rng. We probably want some function to get only gauranteed items
|
||||
// from `LootSpec`.
|
||||
else if let Some((amount, mut item)) = Item::try_reclaim_from_block(*block).into_iter().flatten().next() {
|
||||
else if let Some((amount, mut item)) = Item::try_reclaim_from_block(*block)
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.next()
|
||||
{
|
||||
item.set_amount(amount.clamp(1, item.max_amount()))
|
||||
.expect("amount >= 1 and <= max_amount is always a valid amount");
|
||||
make_overitem(
|
||||
@ -2250,7 +2269,8 @@ impl Hud {
|
||||
"hud-activate"
|
||||
} else {
|
||||
"hud-use"
|
||||
}).to_string(),
|
||||
})
|
||||
.to_string(),
|
||||
)],
|
||||
)
|
||||
.x_y(0.0, 100.0)
|
||||
|
@ -7,7 +7,6 @@
|
||||
)]
|
||||
#![deny(clippy::clone_on_ref_ptr)]
|
||||
#![feature(
|
||||
array_methods,
|
||||
extract_if,
|
||||
trait_alias,
|
||||
option_get_or_insert_default,
|
||||
|
@ -498,7 +498,7 @@ impl Controls {
|
||||
self.selected = client
|
||||
.character_list()
|
||||
.characters
|
||||
.get(0)
|
||||
.first()
|
||||
.and_then(|i| i.character.id);
|
||||
},
|
||||
}
|
||||
|
@ -76,6 +76,7 @@ impl ClientInit {
|
||||
break;
|
||||
}
|
||||
let mut mismatched_server_info = None;
|
||||
#[allow(clippy::blocks_in_conditions)]
|
||||
match Client::new(
|
||||
connection_args.clone(),
|
||||
Arc::clone(&runtime2),
|
||||
|
@ -63,7 +63,7 @@ where
|
||||
|vol: &mut V, pos: Vec3<i32>| vol.get(pos).map_or(true, |vox| !vox.is_filled());
|
||||
let should_draw = |vol: &mut V, pos: Vec3<i32>, delta: Vec3<i32>, uv| {
|
||||
should_draw_greedy(pos, delta, uv, |vox| {
|
||||
vol.get(vox).map(|vox| *vox).unwrap_or_else(|_| Cell::Empty)
|
||||
vol.get(vox).copied().unwrap_or(Cell::Empty)
|
||||
})
|
||||
};
|
||||
let create_opaque = |atlas_pos, pos, norm| {
|
||||
@ -167,9 +167,7 @@ where
|
||||
let get_opacity = |vol: &mut V, pos: Vec3<i32>| vol.get(pos).map_or(true, |vox| vox.is_fluid());
|
||||
let should_draw = |vol: &mut V, pos: Vec3<i32>, delta: Vec3<i32>, _uv| {
|
||||
super::terrain::should_draw_greedy(pos, delta, |vox| {
|
||||
vol.get(vox)
|
||||
.map(|vox| *vox)
|
||||
.unwrap_or_else(|_| Block::empty())
|
||||
vol.get(vox).copied().unwrap_or_else(|_| Block::empty())
|
||||
})
|
||||
};
|
||||
|
||||
@ -271,7 +269,7 @@ where
|
||||
for y in -1..greedy_size.y + 1 {
|
||||
for z in -1..greedy_size.z + 1 {
|
||||
let wpos = lower_bound + Vec3::new(x, y, z);
|
||||
let block = vol.get(wpos).map(|b| *b).unwrap_or_else(|_| Cell::Empty);
|
||||
let block = vol.get(wpos).copied().unwrap_or(Cell::Empty);
|
||||
flat[i] = block;
|
||||
i += 1;
|
||||
}
|
||||
@ -395,7 +393,7 @@ where
|
||||
|vol: &mut V, pos: Vec3<i32>| vol.get(pos).map_or(true, |vox| !vox.is_filled());
|
||||
let should_draw = |vol: &mut V, pos: Vec3<i32>, delta: Vec3<i32>, uv| {
|
||||
should_draw_greedy(pos, delta, uv, |vox| {
|
||||
vol.get(vox).map(|vox| *vox).unwrap_or_else(|_| Cell::Empty)
|
||||
vol.get(vox).copied().unwrap_or(Cell::Empty)
|
||||
})
|
||||
};
|
||||
let create_opaque = |_atlas_pos, pos: Vec3<f32>, norm| ParticleVertex::new(pos, norm);
|
||||
|
@ -305,7 +305,7 @@ pub fn generate_mesh<'a>(
|
||||
let wpos = range.min + Vec3::new(x, y, z);
|
||||
let block = volume
|
||||
.get(wpos)
|
||||
.map(|b| *b)
|
||||
.copied()
|
||||
// TODO: Replace with None or some other more reasonable value,
|
||||
// since it's not clear this will work properly with liquid.
|
||||
.unwrap_or(AIR);
|
||||
|
@ -205,6 +205,7 @@ struct ArmorVoxSpec {
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[allow(dead_code)]
|
||||
enum ModularComponentSpec {
|
||||
/// item id, offset from origin to mount point
|
||||
Damage((String, [i32; 3])),
|
||||
|
@ -173,7 +173,9 @@ pub(super) fn select_interactable(
|
||||
// interactable. We are only returning the mineable air
|
||||
// elements (e.g. minerals). The mineable weakrock are used
|
||||
// in the terrain selected_pos, but is not an interactable.
|
||||
if let Some(mine_tool) = b.mine_tool() && b.is_air() {
|
||||
if let Some(mine_tool) = b.mine_tool()
|
||||
&& b.is_air()
|
||||
{
|
||||
Some(Interactable::Block(
|
||||
b,
|
||||
VolumePos::terrain(t.position_int()),
|
||||
|
@ -990,8 +990,15 @@ impl PlayState for SessionState {
|
||||
))
|
||||
});
|
||||
}
|
||||
if let Some(pet_entity) = close_pet && client.state().read_storage::<Is<Mount>>().get(pet_entity).is_none() {
|
||||
let is_staying = client.state()
|
||||
if let Some(pet_entity) = close_pet
|
||||
&& client
|
||||
.state()
|
||||
.read_storage::<Is<Mount>>()
|
||||
.get(pet_entity)
|
||||
.is_none()
|
||||
{
|
||||
let is_staying = client
|
||||
.state()
|
||||
.read_component_copied::<CharacterActivity>(pet_entity)
|
||||
.map_or(false, |activity| activity.is_pet_staying);
|
||||
client.set_pet_stay(pet_entity, !is_staying);
|
||||
|
@ -73,11 +73,10 @@ impl SingleplayerState {
|
||||
let mut settings = server::Settings::singleplayer(&server_data_dir);
|
||||
let editable_settings = server::EditableSettings::singleplayer(&server_data_dir);
|
||||
|
||||
let file_opts = if let Some(gen_opts) = &world.gen_opts && !world.is_generated {
|
||||
server::FileOpts::Save(
|
||||
world.map_path.clone(),
|
||||
gen_opts.clone(),
|
||||
)
|
||||
let file_opts = if let Some(gen_opts) = &world.gen_opts
|
||||
&& !world.is_generated
|
||||
{
|
||||
server::FileOpts::Save(world.map_path.clone(), gen_opts.clone())
|
||||
} else {
|
||||
if !world.is_generated && world.gen_opts.is_none() {
|
||||
world.copy_default_world();
|
||||
@ -114,6 +113,7 @@ impl SingleplayerState {
|
||||
|
||||
let builder = thread::Builder::new().name("singleplayer-server-thread".into());
|
||||
let runtime = Arc::clone(runtime);
|
||||
#[allow(clippy::blocks_in_conditions)]
|
||||
let thread = builder
|
||||
.spawn(move || {
|
||||
trace!("starting singleplayer server thread");
|
||||
|
@ -593,6 +593,7 @@ where
|
||||
fn style(&self) -> Self::Style {}
|
||||
|
||||
/// Update the state of the Slot.
|
||||
#[allow(clippy::useless_asref)] // false positive
|
||||
fn update(mut self, args: widget::UpdateArgs<Self>) -> Self::Event {
|
||||
let widget::UpdateArgs {
|
||||
id,
|
||||
|
@ -538,6 +538,7 @@ impl Window {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::get_first)]
|
||||
pub fn fetch_events(&mut self) -> Vec<Event> {
|
||||
span!(_guard, "fetch_events", "Window::fetch_events");
|
||||
// Refresh ui size (used when changing playstates)
|
||||
|
@ -660,7 +660,7 @@ impl<'a, NN: NearestNeighbor, const N: u32> VoxelImageEncoding for PaletteEncodi
|
||||
}
|
||||
}
|
||||
|
||||
fn histogram_to_dictionary(histogram: &HashMap<Vec<u8>, usize>, dictionary: &mut Vec<u8>) {
|
||||
fn histogram_to_dictionary(histogram: &HashMap<Vec<u8>, usize>, dictionary: &mut [u8]) {
|
||||
let mut tmp: Vec<(Vec<u8>, usize)> = histogram.iter().map(|(k, v)| (k.clone(), *v)).collect();
|
||||
tmp.sort_by_key(|(_, count)| *count);
|
||||
debug!("{:?}", tmp.last());
|
||||
|
@ -1,7 +1,7 @@
|
||||
#![allow(incomplete_features)]
|
||||
#![allow(
|
||||
clippy::option_map_unit_fn,
|
||||
clippy::blocks_in_if_conditions,
|
||||
clippy::blocks_in_conditions,
|
||||
clippy::identity_op,
|
||||
clippy::needless_pass_by_ref_mut //until we find a better way for specs
|
||||
)]
|
||||
|
@ -648,13 +648,16 @@ impl Floor {
|
||||
),
|
||||
RoomKind::Peaceful | RoomKind::LavaPlatforming => {},
|
||||
}
|
||||
} else if let Some(Tile::UpStair(_, _)) = is_boss_tile && tile_wcenter.xy() == wpos2d {
|
||||
} else if let Some(Tile::UpStair(_, _)) = is_boss_tile
|
||||
&& tile_wcenter.xy() == wpos2d
|
||||
{
|
||||
// Create one teleporter at the top of the "stairs" and one at the botton
|
||||
let bottom_pos = tile_wcenter.map(|v| v as f32) ;
|
||||
let bottom_pos = tile_wcenter.map(|v| v as f32);
|
||||
let top_pos =
|
||||
(tile_wcenter + Vec3::unit_z() * self.total_depth()).map(|v| v as f32);
|
||||
|
||||
// Move both a bit to the side to prevent teleportation loop, ideally we'd have the portals at another location
|
||||
// Move both a bit to the side to prevent teleportation loop, ideally we'd have
|
||||
// the portals at another location
|
||||
supplement.add_entity(EntityInfo::at(top_pos).into_special(
|
||||
SpecialEntity::Teleporter(PortalData {
|
||||
target: bottom_pos + Vec3::unit_x() * 5.,
|
||||
@ -1187,7 +1190,9 @@ impl Floor {
|
||||
|
||||
if let Some(room) = room.map(|i| self.rooms.get(*i)) {
|
||||
height = height.min(room.height);
|
||||
if let Tile::UpStair(_, kind) = tile && !self.final_level {
|
||||
if let Tile::UpStair(_, kind) = tile
|
||||
&& !self.final_level
|
||||
{
|
||||
// Construct the staircase that connects this tile to the matching DownStair
|
||||
// tile on the floor above (or to the surface if this is the top floor), and a
|
||||
// hollow bounding box to place air in
|
||||
@ -1203,10 +1208,13 @@ impl Floor {
|
||||
StairsKind::WallSpiral => Primitive::Aabb(aabb),
|
||||
});
|
||||
|
||||
painter.fill(painter.prim(match kind {
|
||||
StairsKind::WallSpiral => Primitive::Aabb(outer_aabb),
|
||||
StairsKind::Spiral => Primitive::Cylinder(outer_aabb),
|
||||
}), Fill::Block(stone_wall));
|
||||
painter.fill(
|
||||
painter.prim(match kind {
|
||||
StairsKind::WallSpiral => Primitive::Aabb(outer_aabb),
|
||||
StairsKind::Spiral => Primitive::Cylinder(outer_aabb),
|
||||
}),
|
||||
Fill::Block(stone_wall),
|
||||
);
|
||||
|
||||
let stair = painter.prim(Primitive::sampling(bb, match kind {
|
||||
StairsKind::Spiral => spiral_staircase(center, radius, 0.5, 9.0),
|
||||
|
@ -1499,7 +1499,9 @@ impl Structure for Tavern {
|
||||
},
|
||||
}
|
||||
}
|
||||
if let Some(door) = wall.door_bounds() && !matches!(kinds, (Some(RoomKind::Garden), Some(RoomKind::Garden))) {
|
||||
if let Some(door) = wall.door_bounds()
|
||||
&& !matches!(kinds, (Some(RoomKind::Garden), Some(RoomKind::Garden)))
|
||||
{
|
||||
let orth = wall.to_dir.orthogonal();
|
||||
painter
|
||||
.aabb(aabb(Aabb {
|
||||
|
Loading…
Reference in New Issue
Block a user