Flexible race system with slot-based equipment and dragon race
- Expand race TOML schema: 7 stats, body shape (size/weight/custom slots), natural armor and attacks with damage types, resistances, traits/disadvantages, regen multipliers, vision types, XP rate, guild compatibility - Replace equipped_weapon/equipped_armor with slot-based HashMap<String, Object> - Each race defines available equipment slots; default humanoid slots as fallback - Combat uses natural weapons/armor from race when no gear equipped - DB migration from old weapon/armor columns to equipped_json - Add Dragon race: huge body, custom slots (forelegs/wings/tail), fire breath, natural armor 8, fire immune, slow XP rate for balance - Update all existing races with expanded fields (traits, resistances, vision, regen) - Objects gain optional slot field; kind=weapon/armor still works as fallback - Update chargen to display race traits, size, natural attacks, vision - Update stats display to show equipment and natural bonuses separately - Update TESTING.md and AGENTS.md with race/slot system documentation Made-with: Cursor
This commit is contained in:
@@ -44,6 +44,31 @@ impl ChargenState {
|
||||
},
|
||||
ansi::color(ansi::DIM, &race.description),
|
||||
));
|
||||
let mut extras = Vec::new();
|
||||
if race.size != "medium" {
|
||||
extras.push(format!("Size: {}", race.size));
|
||||
}
|
||||
if !race.traits.is_empty() {
|
||||
extras.push(format!("Traits: {}", race.traits.join(", ")));
|
||||
}
|
||||
if race.natural_armor > 0 {
|
||||
extras.push(format!("Natural armor: {}", race.natural_armor));
|
||||
}
|
||||
if !race.natural_attacks.is_empty() {
|
||||
let atks: Vec<String> = race.natural_attacks.iter()
|
||||
.map(|a| format!("{} ({}dmg {})", a.name, a.damage, a.damage_type))
|
||||
.collect();
|
||||
extras.push(format!("Natural attacks: {}", atks.join(", ")));
|
||||
}
|
||||
if !race.vision.is_empty() {
|
||||
extras.push(format!("Vision: {}", race.vision.join(", ")));
|
||||
}
|
||||
if !extras.is_empty() {
|
||||
out.push_str(&format!(
|
||||
" {}\r\n",
|
||||
ansi::color(ansi::DIM, &extras.join(" | "))
|
||||
));
|
||||
}
|
||||
}
|
||||
out.push_str(&format!(
|
||||
"\r\n{}",
|
||||
@@ -179,6 +204,8 @@ fn format_stat_mods(stats: &crate::world::StatModifiers) -> String {
|
||||
("CON", stats.constitution),
|
||||
("INT", stats.intelligence),
|
||||
("WIS", stats.wisdom),
|
||||
("PER", stats.perception),
|
||||
("CHA", stats.charisma),
|
||||
];
|
||||
for (label, val) in fields {
|
||||
if val != 0 {
|
||||
|
||||
Reference in New Issue
Block a user