mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Parallelised rtsim NPC AI
This commit is contained in:
parent
077da13a5f
commit
c4032ee024
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -6952,6 +6952,7 @@ dependencies = [
|
|||||||
"hashbrown 0.12.3",
|
"hashbrown 0.12.3",
|
||||||
"itertools",
|
"itertools",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
|
"rayon",
|
||||||
"rmp-serde",
|
"rmp-serde",
|
||||||
"ron 0.8.0",
|
"ron 0.8.0",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -19,3 +19,4 @@ slotmap = { version = "1.0.6", features = ["serde"] }
|
|||||||
rand = { version = "0.8", features = ["small_rng"] }
|
rand = { version = "0.8", features = ["small_rng"] }
|
||||||
fxhash = "0.2.1"
|
fxhash = "0.2.1"
|
||||||
itertools = "0.10.3"
|
itertools = "0.10.3"
|
||||||
|
rayon = "1.5"
|
||||||
|
@ -89,7 +89,7 @@ impl Data {
|
|||||||
.with_z(world.sim().get_alt_approx(wpos2d).unwrap_or(0.0))
|
.with_z(world.sim().get_alt_approx(wpos2d).unwrap_or(0.0))
|
||||||
};
|
};
|
||||||
if good_or_evil {
|
if good_or_evil {
|
||||||
for _ in 0..32 {
|
for _ in 0..250 {
|
||||||
this.npcs.create(
|
this.npcs.create(
|
||||||
Npc::new(rng.gen(), rand_wpos(&mut rng))
|
Npc::new(rng.gen(), rand_wpos(&mut rng))
|
||||||
.with_faction(site.faction)
|
.with_faction(site.faction)
|
||||||
@ -107,7 +107,7 @@ impl Data {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for _ in 0..5 {
|
for _ in 0..15 {
|
||||||
this.npcs.create(
|
this.npcs.create(
|
||||||
Npc::new(rng.gen(), rand_wpos(&mut rng))
|
Npc::new(rng.gen(), rand_wpos(&mut rng))
|
||||||
.with_faction(site.faction)
|
.with_faction(site.faction)
|
||||||
|
@ -21,6 +21,7 @@ use common::{
|
|||||||
use fxhash::FxHasher64;
|
use fxhash::FxHasher64;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
|
use rayon::iter::{IntoParallelRefMutIterator, ParallelIterator};
|
||||||
use std::{
|
use std::{
|
||||||
any::{Any, TypeId},
|
any::{Any, TypeId},
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
@ -230,84 +231,91 @@ const MAX_STEP: f32 = 32.0;
|
|||||||
impl Rule for NpcAi {
|
impl Rule for NpcAi {
|
||||||
fn start(rtstate: &mut RtState) -> Result<Self, RuleError> {
|
fn start(rtstate: &mut RtState) -> Result<Self, RuleError> {
|
||||||
rtstate.bind::<Self, OnTick>(|mut ctx| {
|
rtstate.bind::<Self, OnTick>(|mut ctx| {
|
||||||
let npc_ids = ctx.state.data().npcs.keys().collect::<Vec<_>>();
|
let mut npc_data = {
|
||||||
|
let mut data = ctx.state.data_mut();
|
||||||
for npc_id in npc_ids {
|
data.npcs
|
||||||
let mut brain = ctx.state.data_mut().npcs[npc_id]
|
.iter_mut()
|
||||||
.brain
|
.map(|(npc_id, npc)| {
|
||||||
.take()
|
let controller = Controller { goto: npc.goto };
|
||||||
.unwrap_or_else(|| Brain {
|
let brain = npc.brain.take().unwrap_or_else(|| Brain {
|
||||||
action: Box::new(think().repeat()),
|
action: Box::new(think().repeat()),
|
||||||
});
|
|
||||||
|
|
||||||
let controller = {
|
|
||||||
let data = &*ctx.state.data();
|
|
||||||
let npc = &data.npcs[npc_id];
|
|
||||||
|
|
||||||
let mut controller = Controller { goto: npc.goto };
|
|
||||||
|
|
||||||
brain.action.tick(&mut NpcCtx {
|
|
||||||
state: ctx.state,
|
|
||||||
world: ctx.world,
|
|
||||||
index: ctx.index,
|
|
||||||
time_of_day: ctx.event.time_of_day,
|
|
||||||
time: ctx.event.time,
|
|
||||||
npc,
|
|
||||||
npc_id,
|
|
||||||
controller: &mut controller,
|
|
||||||
});
|
|
||||||
|
|
||||||
/*
|
|
||||||
let action: ControlFlow<()> = try {
|
|
||||||
brain.tick(&mut NpcData {
|
|
||||||
ctx: &ctx,
|
|
||||||
npc,
|
|
||||||
npc_id,
|
|
||||||
controller: &mut controller,
|
|
||||||
});
|
});
|
||||||
/*
|
(npc_id, controller, brain)
|
||||||
// // Choose a random plaza in the npcs home site (which should be the
|
})
|
||||||
// // current here) to go to.
|
.collect::<Vec<_>>()
|
||||||
let task =
|
};
|
||||||
generate(move |(_, npc, ctx): &(NpcId, &Npc, &EventCtx<_, _>)| {
|
|
||||||
let data = ctx.state.data();
|
|
||||||
let site2 =
|
|
||||||
npc.home.and_then(|home| data.sites.get(home)).and_then(
|
|
||||||
|home| match &ctx.index.sites.get(home.world_site?).kind
|
|
||||||
{
|
|
||||||
SiteKind::Refactor(site2)
|
|
||||||
| SiteKind::CliffTown(site2)
|
|
||||||
| SiteKind::DesertCity(site2) => Some(site2),
|
|
||||||
_ => None,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
let wpos = site2
|
{
|
||||||
.and_then(|site2| {
|
let data = &*ctx.state.data();
|
||||||
let plaza = &site2.plots
|
|
||||||
[site2.plazas().choose(&mut thread_rng())?];
|
|
||||||
Some(site2.tile_center_wpos(plaza.root_tile()).as_())
|
|
||||||
})
|
|
||||||
.unwrap_or(npc.wpos.xy());
|
|
||||||
|
|
||||||
TravelTo {
|
npc_data
|
||||||
wpos,
|
.par_iter_mut()
|
||||||
use_paths: true,
|
.for_each(|(npc_id, controller, brain)| {
|
||||||
}
|
let npc = &data.npcs[*npc_id];
|
||||||
})
|
|
||||||
.repeat();
|
|
||||||
|
|
||||||
task_state.perform(task, &(npc_id, &*npc, &ctx), &mut controller)?;
|
brain.action.tick(&mut NpcCtx {
|
||||||
*/
|
state: ctx.state,
|
||||||
};
|
world: ctx.world,
|
||||||
*/
|
index: ctx.index,
|
||||||
|
time_of_day: ctx.event.time_of_day,
|
||||||
controller
|
time: ctx.event.time,
|
||||||
};
|
npc,
|
||||||
|
npc_id: *npc_id,
|
||||||
ctx.state.data_mut().npcs[npc_id].goto = controller.goto;
|
controller,
|
||||||
ctx.state.data_mut().npcs[npc_id].brain = Some(brain);
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut data = ctx.state.data_mut();
|
||||||
|
for (npc_id, controller, brain) in npc_data {
|
||||||
|
data.npcs[npc_id].goto = controller.goto;
|
||||||
|
data.npcs[npc_id].brain = Some(brain);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
let action: ControlFlow<()> = try {
|
||||||
|
brain.tick(&mut NpcData {
|
||||||
|
ctx: &ctx,
|
||||||
|
npc,
|
||||||
|
npc_id,
|
||||||
|
controller: &mut controller,
|
||||||
|
});
|
||||||
|
/*
|
||||||
|
// // Choose a random plaza in the npcs home site (which should be the
|
||||||
|
// // current here) to go to.
|
||||||
|
let task =
|
||||||
|
generate(move |(_, npc, ctx): &(NpcId, &Npc, &EventCtx<_, _>)| {
|
||||||
|
let data = ctx.state.data();
|
||||||
|
let site2 =
|
||||||
|
npc.home.and_then(|home| data.sites.get(home)).and_then(
|
||||||
|
|home| match &ctx.index.sites.get(home.world_site?).kind
|
||||||
|
{
|
||||||
|
SiteKind::Refactor(site2)
|
||||||
|
| SiteKind::CliffTown(site2)
|
||||||
|
| SiteKind::DesertCity(site2) => Some(site2),
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
let wpos = site2
|
||||||
|
.and_then(|site2| {
|
||||||
|
let plaza = &site2.plots
|
||||||
|
[site2.plazas().choose(&mut thread_rng())?];
|
||||||
|
Some(site2.tile_center_wpos(plaza.root_tile()).as_())
|
||||||
|
})
|
||||||
|
.unwrap_or(npc.wpos.xy());
|
||||||
|
|
||||||
|
TravelTo {
|
||||||
|
wpos,
|
||||||
|
use_paths: true,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.repeat();
|
||||||
|
|
||||||
|
task_state.perform(task, &(npc_id, &*npc, &ctx), &mut controller)?;
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
*/
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(Self)
|
Ok(Self)
|
||||||
|
Loading…
Reference in New Issue
Block a user