mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Fix rtsim NPC respawning
This commit is contained in:
parent
08afe26112
commit
bc4d1a71f6
@ -100,6 +100,8 @@ pub struct Npc {
|
||||
pub faction: Option<FactionId>,
|
||||
pub riding: Option<Riding>,
|
||||
|
||||
pub is_dead: bool,
|
||||
|
||||
/// The [`Report`]s that the NPC is aware of.
|
||||
pub known_reports: HashSet<ReportId>,
|
||||
|
||||
@ -139,6 +141,7 @@ impl Clone for Npc {
|
||||
home: self.home,
|
||||
faction: self.faction,
|
||||
riding: self.riding.clone(),
|
||||
is_dead: self.is_dead,
|
||||
known_reports: self.known_reports.clone(),
|
||||
body: self.body,
|
||||
personality: self.personality,
|
||||
@ -169,6 +172,7 @@ impl Npc {
|
||||
home: None,
|
||||
faction: None,
|
||||
riding: None,
|
||||
is_dead: false,
|
||||
known_reports: Default::default(),
|
||||
chunk_pos: None,
|
||||
current_site: None,
|
||||
|
@ -22,12 +22,27 @@ impl Rule for CleanUp {
|
||||
|
||||
// TODO: Use `.into_par_iter()` for these by implementing rayon traits in upstream slotmap.
|
||||
|
||||
// Decay NPC sentiments
|
||||
data.npcs
|
||||
.iter_mut()
|
||||
// Only cleanup NPCs every few ticks
|
||||
.filter(|(_, npc)| (npc.seed as u64 + ctx.event.tick) % NPC_SENTIMENT_TICK_SKIP == 0)
|
||||
.for_each(|(_, npc)| npc.sentiments.decay(&mut rng, ctx.event.dt * NPC_SENTIMENT_TICK_SKIP as f32));
|
||||
|
||||
// Remove dead NPCs
|
||||
// TODO: Don't do this every tick, find a sensible way to gradually remove dead NPCs after they've been
|
||||
// forgotten
|
||||
data.npcs
|
||||
.retain(|npc_id, npc| if npc.is_dead {
|
||||
// Remove NPC from home population
|
||||
if let Some(home) = npc.home.and_then(|home| data.sites.get_mut(home)) {
|
||||
home.population.remove(&npc_id);
|
||||
}
|
||||
false
|
||||
} else {
|
||||
true
|
||||
});
|
||||
|
||||
// Clean up entities
|
||||
data.npcs
|
||||
.iter_mut()
|
||||
|
@ -215,6 +215,8 @@ impl Rule for NpcAi {
|
||||
let mut data = ctx.state.data_mut();
|
||||
data.npcs
|
||||
.iter_mut()
|
||||
// Don't run AI for dead NPCs
|
||||
.filter(|(_, npc)| !npc.is_dead)
|
||||
// Don't run AI for simulated NPCs every tick
|
||||
.filter(|(_, npc)| matches!(npc.mode, SimulationMode::Loaded) || (npc.seed as u64 + ctx.event.tick) % SIMULATED_TICK_SKIP == 0)
|
||||
.map(|(npc_id, npc)| {
|
||||
|
@ -61,7 +61,10 @@ fn on_death(ctx: EventCtx<SimulateNpcs, OnDeath>) {
|
||||
Some(*id) != npc.home
|
||||
&& site.faction == npc.faction
|
||||
&& site.world_site.map_or(false, |s| {
|
||||
matches!(ctx.index.sites.get(s).kind, SiteKind::Refactor(_))
|
||||
matches!(ctx.index.sites.get(s).kind, SiteKind::Refactor(_)
|
||||
| SiteKind::CliffTown(_)
|
||||
| SiteKind::SavannahPit(_)
|
||||
| SiteKind::DesertCity(_))
|
||||
})
|
||||
})
|
||||
.min_by_key(|(_, site)| site.population.len())
|
||||
@ -142,6 +145,8 @@ fn on_death(ctx: EventCtx<SimulateNpcs, OnDeath>) {
|
||||
home.population.insert(npc_id);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
error!("Trying to respawn non-existent NPC");
|
||||
}
|
||||
}
|
||||
|
||||
@ -151,7 +156,7 @@ fn on_tick(ctx: EventCtx<SimulateNpcs, OnTick>) {
|
||||
.npcs
|
||||
.npcs
|
||||
.values_mut()
|
||||
.filter(|npc| matches!(npc.mode, SimulationMode::Simulated))
|
||||
.filter(|npc| matches!(npc.mode, SimulationMode::Simulated) && !npc.is_dead)
|
||||
{
|
||||
// Simulate NPC movement when riding
|
||||
if let Some(riding) = &npc.riding {
|
||||
|
@ -34,19 +34,10 @@ fn on_death(ctx: EventCtx<SyncNpcs, OnDeath>) {
|
||||
let data = &mut *ctx.state.data_mut();
|
||||
|
||||
if let Actor::Npc(npc_id) = ctx.event.actor {
|
||||
// Remove NPC from home population
|
||||
if let Some(home) = data
|
||||
.npcs
|
||||
.get(npc_id)
|
||||
.and_then(|npc| npc.home)
|
||||
.and_then(|home| data.sites.get_mut(home))
|
||||
{
|
||||
home.population.remove(&npc_id);
|
||||
if let Some(npc) = data.npcs.get_mut(npc_id) {
|
||||
// Mark the NPC as dead, allowing us to clear them up later
|
||||
npc.is_dead = true;
|
||||
}
|
||||
|
||||
// TODO: Maybe death should be a marker flag instead of outright deleting the
|
||||
// NPC so that we can still query details about them?
|
||||
data.npcs.remove(npc_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user