mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Fix travellers stuck in town
There was an off by one error in the code that negates the progress along paths that are reversed.
This commit is contained in:
parent
126b7efa92
commit
5cbdf1850c
@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Auto camera setting, making the game easier to play with one hand
|
- Auto camera setting, making the game easier to play with one hand
|
||||||
- Topographic map option
|
- Topographic map option
|
||||||
- Search bars for social and crafting window
|
- Search bars for social and crafting window
|
||||||
|
- RTsim travellers now follow paths between towns
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ use common::{
|
|||||||
};
|
};
|
||||||
use rand_distr::{Distribution, Normal};
|
use rand_distr::{Distribution, Normal};
|
||||||
use std::f32::consts::PI;
|
use std::f32::consts::PI;
|
||||||
|
use tracing::warn;
|
||||||
use world::{
|
use world::{
|
||||||
civ::{Site, Track},
|
civ::{Site, Track},
|
||||||
util::RandomPerm,
|
util::RandomPerm,
|
||||||
@ -142,17 +143,21 @@ impl Entity {
|
|||||||
.civs()
|
.civs()
|
||||||
.sites
|
.sites
|
||||||
.iter()
|
.iter()
|
||||||
|
.filter(|s| s.1.is_settlement() || s.1.is_castle())
|
||||||
.min_by_key(|(_, site)| {
|
.min_by_key(|(_, site)| {
|
||||||
let wpos = site.center * TerrainChunk::RECT_SIZE.map(|e| e as i32);
|
let wpos = site.center * TerrainChunk::RECT_SIZE.map(|e| e as i32);
|
||||||
wpos.map(|e| e as f32).distance(self.pos.xy()) as u32
|
wpos.map(|e| e as f32).distance(self.pos.xy()) as u32
|
||||||
})
|
})
|
||||||
.map(|(id, _)| id)
|
.map(|(id, _)| id)
|
||||||
{
|
{
|
||||||
|
// The path choosing code works best when Humanoids can assume they are
|
||||||
|
// in a town that has at least one path. If the Human isn't in a town
|
||||||
|
// with at least one path, we need to get them to a town that does.
|
||||||
let nearest_site = &world.civs().sites[nearest_site_id];
|
let nearest_site = &world.civs().sites[nearest_site_id];
|
||||||
let site_wpos =
|
let site_wpos =
|
||||||
nearest_site.center * TerrainChunk::RECT_SIZE.map(|e| e as i32);
|
nearest_site.center * TerrainChunk::RECT_SIZE.map(|e| e as i32);
|
||||||
let dist = site_wpos.map(|e| e as f32).distance(self.pos.xy()) as u32;
|
let dist = site_wpos.map(|e| e as f32).distance(self.pos.xy()) as u32;
|
||||||
if dist < 32 {
|
if dist < 64 {
|
||||||
Travel::InSite {
|
Travel::InSite {
|
||||||
site_id: nearest_site_id,
|
site_id: nearest_site_id,
|
||||||
}
|
}
|
||||||
@ -165,6 +170,7 @@ impl Entity {
|
|||||||
// Somehow no nearest site could be found
|
// Somehow no nearest site could be found
|
||||||
// Logically this should never happen, but if it does the rtsim entity
|
// Logically this should never happen, but if it does the rtsim entity
|
||||||
// will just sit tight
|
// will just sit tight
|
||||||
|
warn!("Nearest site could not be found");
|
||||||
Travel::Lost
|
Travel::Lost
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -240,16 +246,6 @@ impl Entity {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
Travel::InSite { site_id } => {
|
Travel::InSite { site_id } => {
|
||||||
let site = &world.civs().sites[site_id];
|
|
||||||
let site_name = site
|
|
||||||
.site_tmp
|
|
||||||
.map_or("".to_string(), |id| index.sites[id].name().to_string());
|
|
||||||
let last_name = self
|
|
||||||
.brain
|
|
||||||
.last_visited
|
|
||||||
.and_then(|last| site.site_tmp.map(|id| index.sites[id].name().to_string()))
|
|
||||||
.or_else(|| Some("None".to_string()));
|
|
||||||
println!("In: {:?}, prev: {:?}", site_name, last_name);
|
|
||||||
if !self.get_body().is_humanoid() {
|
if !self.get_body().is_humanoid() {
|
||||||
// Non humanoids don't care if they start at a site
|
// Non humanoids don't care if they start at a site
|
||||||
Travel::Lost
|
Travel::Lost
|
||||||
@ -280,8 +276,10 @@ impl Entity {
|
|||||||
reversed: false,
|
reversed: false,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// This should never trigger, since neighbors returns a list of sites for
|
||||||
|
// which a track exists going from the current town.
|
||||||
|
warn!("Could not get track after selecting from neighbor list");
|
||||||
self.brain.last_visited = Some(site_id);
|
self.brain.last_visited = Some(site_id);
|
||||||
// This should never trigger
|
|
||||||
Travel::Direct { target_id }
|
Travel::Direct { target_id }
|
||||||
}
|
}
|
||||||
} else if let Some(target_id) = world
|
} else if let Some(target_id) = world
|
||||||
@ -297,10 +295,13 @@ impl Entity {
|
|||||||
})
|
})
|
||||||
.map(|(id, _)| id)
|
.map(|(id, _)| id)
|
||||||
{
|
{
|
||||||
|
// This code should only trigger when no paths out of the current town exist.
|
||||||
|
// The traveller will attempt to directly travel to another town
|
||||||
self.brain.last_visited = Some(site_id);
|
self.brain.last_visited = Some(site_id);
|
||||||
// Directly travel if no paths exist
|
|
||||||
Travel::Direct { target_id }
|
Travel::Direct { target_id }
|
||||||
} else {
|
} else {
|
||||||
|
// No paths we're picked, so stay in town. This will cause direct travel on the
|
||||||
|
// next tick.
|
||||||
self.brain.last_visited = Some(site_id);
|
self.brain.last_visited = Some(site_id);
|
||||||
Travel::InSite { site_id }
|
Travel::InSite { site_id }
|
||||||
}
|
}
|
||||||
@ -353,7 +354,7 @@ impl Entity {
|
|||||||
|
|
||||||
if let Some(wpos) = &path.get(progress) {
|
if let Some(wpos) = &path.get(progress) {
|
||||||
let dist = wpos.map(|e| e as f32).distance(self.pos.xy()) as u32;
|
let dist = wpos.map(|e| e as f32).distance(self.pos.xy()) as u32;
|
||||||
if dist < 64 {
|
if dist < 16 {
|
||||||
if progress + 1 < path.len() {
|
if progress + 1 < path.len() {
|
||||||
Travel::CustomPath {
|
Travel::CustomPath {
|
||||||
target_id,
|
target_id,
|
||||||
@ -407,7 +408,7 @@ impl Entity {
|
|||||||
.site_tmp
|
.site_tmp
|
||||||
.map_or("".to_string(), |id| index.sites[id].name().to_string());
|
.map_or("".to_string(), |id| index.sites[id].name().to_string());
|
||||||
let nth = if reversed {
|
let nth = if reversed {
|
||||||
track.path().len() - progress
|
track.path().len() - progress - 1
|
||||||
} else {
|
} else {
|
||||||
progress
|
progress
|
||||||
};
|
};
|
||||||
@ -422,8 +423,8 @@ impl Entity {
|
|||||||
let dist = wpos.map(|e| e as f32).distance(self.pos.xy()) as u32;
|
let dist = wpos.map(|e| e as f32).distance(self.pos.xy()) as u32;
|
||||||
|
|
||||||
match dist {
|
match dist {
|
||||||
d if d < 32 => {
|
d if d < 16 => {
|
||||||
if progress + 1 > track.path().len() {
|
if progress + 1 >= track.path().len() {
|
||||||
Travel::Direct { target_id }
|
Travel::Direct { target_id }
|
||||||
} else {
|
} else {
|
||||||
Travel::Path {
|
Travel::Path {
|
||||||
@ -477,6 +478,11 @@ impl Entity {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// This code should never trigger. If we've gone outside the bounds of the
|
||||||
|
// tracks vec then a logic bug has occured. I actually had
|
||||||
|
// an off by one error that caused this to trigger and
|
||||||
|
// resulted in travellers getting stuck in towns.
|
||||||
|
warn!("Progress out of bounds while following track");
|
||||||
Travel::Lost
|
Travel::Lost
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -489,7 +495,7 @@ impl Entity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
enum Travel {
|
enum Travel {
|
||||||
Lost,
|
Lost,
|
||||||
InSite {
|
InSite {
|
||||||
|
Loading…
Reference in New Issue
Block a user