Give every NPC a race and class, resolved at spawn time
NPCs can now optionally specify race and class in their TOML. When omitted, race is randomly selected from non-hidden races and class is determined by the race's default_class or picked randomly from compatible non-hidden classes. Race/class are re-rolled on each respawn for NPCs without fixed values, so killing the barkeep may bring back a different race next time. New hidden content (excluded from character creation): - Beast race: for animals (rats, etc.) with feral stats and no equipment slots - Peasant class: weak default for humanoid NPCs - Creature class: default for beasts/animals Existing races gain default_class fields (humanoids → peasant, beast → creature, dragon → random compatible). Look and examine commands now display NPC race and class. Made-with: Cursor
This commit is contained in:
@@ -29,7 +29,8 @@ impl ChargenState {
|
||||
"\r\n{}\r\n\r\n",
|
||||
ansi::bold("=== Choose Your Race ===")
|
||||
));
|
||||
for (i, race) in world.races.iter().enumerate() {
|
||||
let visible_races: Vec<_> = world.races.iter().filter(|r| !r.hidden).collect();
|
||||
for (i, race) in visible_races.iter().enumerate() {
|
||||
let mods = format_stat_mods(&race.stats);
|
||||
out.push_str(&format!(
|
||||
" {}{}.{} {} {}\r\n {}\r\n",
|
||||
@@ -82,7 +83,8 @@ impl ChargenState {
|
||||
"\r\n{}\r\n\r\n",
|
||||
ansi::bold("=== Choose Your Class ===")
|
||||
));
|
||||
for (i, class) in world.classes.iter().enumerate() {
|
||||
let visible_classes: Vec<_> = world.classes.iter().filter(|c| !c.hidden).collect();
|
||||
for (i, class) in visible_classes.iter().enumerate() {
|
||||
let guild_info = class.guild.as_ref()
|
||||
.and_then(|gid| world.guilds.get(gid))
|
||||
.map(|g| format!(" → joins {}", ansi::color(ansi::YELLOW, &g.name)))
|
||||
@@ -126,7 +128,7 @@ impl ChargenState {
|
||||
ChargenStep::AwaitingRace => {
|
||||
let race = find_by_input(
|
||||
input,
|
||||
&world.races.iter().map(|r| (r.id.clone(), r.name.clone())).collect::<Vec<_>>(),
|
||||
&world.races.iter().filter(|r| !r.hidden).map(|r| (r.id.clone(), r.name.clone())).collect::<Vec<_>>(),
|
||||
);
|
||||
match race {
|
||||
Some((id, name)) => {
|
||||
@@ -149,6 +151,7 @@ impl ChargenState {
|
||||
&world
|
||||
.classes
|
||||
.iter()
|
||||
.filter(|c| !c.hidden)
|
||||
.map(|c| (c.id.clone(), c.name.clone()))
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user