Remove rtsim uids

This commit is contained in:
Joshua Barretto 2026-07-08 22:23:26 +01:00
parent ca7c6042da
commit 68f32276d9
11 changed files with 56 additions and 65 deletions

1
Cargo.lock generated
View file

@ -8955,6 +8955,7 @@ dependencies = [
"schnellru",
"serde",
"serde_json",
"slotmap",
"specs",
"strum",
"tokio",

View file

@ -209,6 +209,7 @@ serde_json = { version = "1.0.50" }
sha2 = "0.11"
signal-hook = "0.4.3"
slab = { version = "0.4.2" }
slotmap = { version = "1.0", features = ["serde"] }
specs = { version = "0.20", features = ["nightly"] }
strum = { version = "0.28", features = ["derive"] }
thread-priority = { version = "3.0.0" }

View file

@ -80,7 +80,7 @@ clap = { workspace = true, optional = true }
# Data structures
hashbrown = { workspace = true }
slab = { workspace = true }
slotmap = { version = "1.0", features = ["serde"] }
slotmap = { workspace = true }
indexmap = { version = "2.7.1", features = ["rayon"] }
# ECS

View file

@ -327,7 +327,7 @@ lazy_static! {
pub enum EntityTarget {
Player(String),
RtsimNpc(u64),
RtsimNpc(String),
Uid(crate::uid::Uid),
}
@ -338,9 +338,7 @@ impl FromStr for EntityTarget {
// NOTE: `@` is an invalid character in usernames, so we can use it here.
if let Some((spec, data)) = s.split_once('@') {
match spec {
"rtsim" => Ok(EntityTarget::RtsimNpc(u64::from_str(data).map_err(
|_| format!("Expected a valid number after 'rtsim@' but found {data}."),
)?)),
"rtsim" => Ok(EntityTarget::RtsimNpc(data.to_string())),
"uid" => {
let raw = u64::from_str(data).map_err(|_| {
format!("Expected a valid number after 'uid@' but found {data}.")

View file

@ -27,13 +27,12 @@ use std::{collections::VecDeque, sync::Arc};
use strum::{EnumIter, IntoEnumIterator};
use vek::*;
slotmap::new_key_type! { pub struct ActorId; }
slotmap::new_key_type! { pub struct SiteId; }
slotmap::new_key_type! { pub struct FactionId; }
slotmap::new_key_type! { pub struct ReportId; }
slotmap::new_key_type! {
pub struct ActorId;
pub struct SiteId;
pub struct FactionId;
pub struct ReportId;
}
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
pub struct QuestId(pub u64);

View file

@ -18,7 +18,7 @@ rmp-serde = "1.1.0"
anymap2 = "0.13"
tracing = { workspace = true }
atomic_refcell = { workspace = true }
slotmap = { version = "1.0.6", features = ["serde"] }
slotmap = { workspace = true }
rand = { workspace = true }
rand_chacha = { workspace = true }
fxhash = { workspace = true }

View file

@ -315,7 +315,6 @@ pub enum ActorKind {
pub struct Actor {
pub kind: ActorKind,
pub uid: u64,
// Persisted state
pub seed: u32,
/// Represents the location of the NPC.
@ -378,7 +377,6 @@ impl Clone for Actor {
last_present_at: c.last_present_at,
}),
},
uid: self.uid,
seed: self.seed,
wpos: self.wpos,
dir: self.dir,
@ -411,8 +409,6 @@ impl Actor {
inbox: Default::default(),
brain: None,
}),
// To be assigned later
uid: 0,
seed,
wpos,
dir: Vec2::unit_x(),
@ -455,8 +451,6 @@ impl Actor {
id,
last_present_at: None,
}),
// To be assigned later
uid: 0,
seed,
wpos,
dir: Vec2::unit_x(),
@ -780,7 +774,6 @@ pub struct MountData {
#[derive(Clone, Serialize, Deserialize)]
pub struct Actors {
pub uid_counter: u64,
pub actors: DenseSlotMap<ActorId, Actor>,
pub mounts: ActorLinks,
// TODO: This feels like it should be its own rtsim resource
@ -792,7 +785,6 @@ pub struct Actors {
impl Default for Actors {
fn default() -> Self {
Self {
uid_counter: 0,
actors: Default::default(),
mounts: Default::default(),
actor_grid: construct_actor_grid(),
@ -814,11 +806,7 @@ pub enum MountingError {
}
impl Actors {
pub fn create_actor(&mut self, mut actor: Actor) -> ActorId {
actor.uid = self.uid_counter;
self.uid_counter += 1;
self.actors.insert(actor)
}
pub fn create_actor(&mut self, actor: Actor) -> ActorId { self.actors.insert(actor) }
/// Queries nearby npcs, not garantueed to work if radius > 32.0
// TODO: Find a more efficient way to implement this, it's currently

View file

@ -13,7 +13,6 @@ use world::site::Site as WorldSite;
#[derive(Clone, Serialize, Deserialize)]
pub struct Site {
pub uid: u64,
pub seed: u32,
pub wpos: Vec2<i32>,
pub faction: Option<FactionId>,
@ -72,7 +71,6 @@ impl Site {
#[derive(Clone, Default, Serialize, Deserialize)]
pub struct Sites {
pub uid_counter: u64,
pub sites: DenseSlotMap<SiteId, Site>,
#[serde(skip_serializing, skip_deserializing)]
@ -80,12 +78,9 @@ pub struct Sites {
}
impl Sites {
pub fn create(&mut self, mut site: Site) -> SiteId {
pub fn create(&mut self, site: Site) -> SiteId {
let world_site = site.world_site;
site.uid = self.uid_counter;
self.uid_counter = self.uid_counter.wrapping_add(1);
let key = self.sites.insert(site);
if let Some(world_site) = world_site {
self.world_site_map.insert(world_site, key);

View file

@ -55,8 +55,6 @@ impl Site {
};
Self {
// This is assigned later
uid: 0,
seed: rng.random(),
wpos,
world_site: Some(world_site_id),

View file

@ -73,6 +73,7 @@ authc = { git = "https://gitlab.com/veloren/auth.git", rev = "ae0e16783a9f904195
enum-map = { workspace = true }
noise = { workspace = true }
censor = "0.3"
slotmap = { workspace = true }
rusqlite = { workspace = true }
refinery = { version = "0.9", features = ["rusqlite"] }

View file

@ -20,6 +20,7 @@ use crate::{
};
#[cfg(feature = "worldgen")]
use common::{cmd::SPOT_PARSER, spot::Spot};
use slotmap::Key as _;
use assets::{AssetExt, Ron};
use authc::Uuid;
@ -250,6 +251,17 @@ fn do_command(
handler(server, client, target, args, cmd)
}
fn key_matches(key: impl slotmap::Key, query: &str) -> bool {
let key = format!("{:?}", key.data());
if query.contains("v") {
key == query
} else if let Some((idx, _)) = key.split_once('v') {
idx == query
} else {
false
}
}
// Fallibly get position of entity with the given descriptor (used for error
// message).
fn position(server: &Server, entity: EcsEntity, descriptor: &str) -> CmdResult<comp::Pos> {
@ -1365,10 +1377,6 @@ fn resolve_site(
Option<common::store::Id<world::site::Plot>>,
)> {
if let Some(id) = key.strip_prefix("rtsim@") {
let id = id
.parse::<u64>()
.map_err(|_| Content::Plain(format!("Expected number after 'rtsim@', got {id}")))?;
let ws = server
.state
.ecs()
@ -1376,9 +1384,9 @@ fn resolve_site(
.state()
.data()
.sites
.values()
.find(|site| site.uid == id)
.map(|site| site.world_site)
.iter()
.find(|(site_id, _)| key_matches(*site_id, id))
.map(|(_, site)| site.world_site)
.ok_or(Content::Plain(format!(
"Could not find rtsim site with id {id}."
)))?;
@ -1922,8 +1930,8 @@ fn handle_rtsim_tp(
action: &ServerChatCommand,
) -> CmdResult<()> {
use crate::rtsim::RtSim;
let (npc_id, dismount_volume) = parse_cmd_args!(args, u64, bool);
let pos = if let Some(id) = npc_id {
let (id, dismount_volume) = parse_cmd_args!(args, String, bool);
let pos = if let Some(id) = id {
server
.state
.ecs()
@ -1931,8 +1939,9 @@ fn handle_rtsim_tp(
.state()
.data()
.actors
.values()
.find(|npc| npc.uid == id)
.iter()
.find(|(actor_id, _)| key_matches(*actor_id, &id))
.map(|(_, actor)| actor)
.ok_or_else(|| Content::Plain(format!("No NPC has the id {id}")))?
.wpos
} else {
@ -1958,7 +1967,7 @@ fn handle_rtsim_info(
) -> CmdResult<()> {
use crate::rtsim::RtSim;
let rtsim = server.state.ecs().read_resource::<RtSim>();
let id = parse_cmd_args!(args.clone(), u64)
let id = parse_cmd_args!(args.clone(), String)
.map(Ok)
.or_else(|| {
let entity = parse_cmd_args!(args, EntityTarget)?;
@ -1967,13 +1976,14 @@ fn handle_rtsim_info(
Err(e) => return Some(Err(e)),
};
let npc_id = *server
.state
.ecs()
.read_storage::<common::rtsim::ActorId>()
.get(entity)?;
Some(Ok(rtsim.state().data().actors.get(npc_id)?.uid))
Some(Ok(format!(
"{:?}",
server
.state
.ecs()
.read_storage::<common::rtsim::ActorId>()
.get(entity)?
)))
})
.transpose()?;
@ -1982,7 +1992,7 @@ fn handle_rtsim_info(
let (id, actor) = data
.actors
.iter()
.find(|(_, actor)| actor.uid == id)
.min_by_key(|(actor_id, _)| key_matches(*actor_id, &id))
.ok_or_else(|| Content::Plain(format!("No actor has the id {id}")))?;
let mut info = String::new();
@ -2005,7 +2015,7 @@ fn handle_rtsim_info(
data.actors
.mounts
.get_mount_link(id)
.map(|link| data.actors.get(link.mount).map_or(0, |mount| mount.uid))
.map(|link| format!("{:?}", link.mount.data()))
);
let _ = writeln!(&mut info, "-- Action State --");
if let Some(npc) = actor.npc()
@ -2050,8 +2060,8 @@ fn handle_rtsim_npc(
let data = rtsim.state().data();
let mut actors = data
.actors
.values()
.filter(|actor| {
.iter()
.filter(|(actor_id, actor)| {
let mut tags = vec![
actor
.profession()
@ -2064,7 +2074,7 @@ fn handle_rtsim_npc(
Role::Vehicle => "vehicle".to_string(),
},
format!("{:?}", actor.mode),
format!("{}", actor.uid),
format!("{:?}", actor_id.data()),
npc_names[&actor.body].keyword.clone(),
];
if let Some(species_meta) = npc_names.get_species_meta(&actor.body) {
@ -2082,18 +2092,18 @@ fn handle_rtsim_npc(
})
.collect::<Vec<_>>();
if let Ok(pos) = position(server, target, "target") {
actors.sort_by_key(|actor| (actor.wpos.distance_squared(pos.0) * 10.0) as u64);
actors.sort_by_key(|(_, actor)| (actor.wpos.distance_squared(pos.0) * 10.0) as u64);
}
let mut info = String::new();
let _ = writeln!(&mut info, "-- NPCs matching [{}] --", terms.join(", "));
for actor in actors.iter().take(count.unwrap_or(!0) as usize) {
for (actor_id, actor) in actors.iter().take(count.unwrap_or(!0) as usize) {
let _ = write!(
&mut info,
"{} ({}), ",
"{} ({:?}), ",
actor.get_name().as_deref().unwrap_or("<unknown>"),
actor.uid
actor_id.data(),
);
}
let _ = writeln!(&mut info);
@ -4901,15 +4911,15 @@ fn get_entity_target(entity_target: EntityTarget, server: &Server) -> CmdResult<
match entity_target {
EntityTarget::Player(alias) => Ok(find_alias(server.state.ecs(), &alias, true)?.0),
EntityTarget::RtsimNpc(id) => {
let (actor_id, _) = server
let actor_id = server
.state
.ecs()
.read_resource::<crate::rtsim::RtSim>()
.state()
.data()
.actors
.iter()
.find(|(_, npc)| npc.uid == id)
.keys()
.find(|actor_id| key_matches(*actor_id, &id))
.ok_or(Content::Plain(format!(
"Could not find rtsim npc with id {id}."
)))?;