mirror of
https://gitgud.io/AsmodeusRex/rjw-race-support.git
synced 2024-08-15 00:03:24 +00:00
11.1.0
This commit is contained in:
parent
23fd56b07e
commit
6475e46293
63 changed files with 10733 additions and 6833 deletions
8
generator/Cargo.toml
Normal file
8
generator/Cargo.toml
Normal file
|
@ -0,0 +1,8 @@
|
|||
[package]
|
||||
name = "generator"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
70
generator/src/main.rs
Normal file
70
generator/src/main.rs
Normal file
|
@ -0,0 +1,70 @@
|
|||
use std::fs::File;
|
||||
use std::io::{self, Write};
|
||||
|
||||
mod parts;
|
||||
mod racegroups;
|
||||
mod surgery;
|
||||
mod things;
|
||||
|
||||
use parts::*;
|
||||
use racegroups::*;
|
||||
use surgery::*;
|
||||
use things::*;
|
||||
|
||||
fn write(path: &'static str, data: &String) -> io::Result<()> {
|
||||
let mut f = File::create(format!("../Content/Base/Defs/{path}.xml"))?;
|
||||
let s = format!("<?xml version=\"1.0\" encoding=\"utf-8\"?>
|
||||
<!-- This is an automatically generated file. If you are the end user, this is safe to edit. If you are a contributor, please edit the source files instead. -->
|
||||
<Defs>{data}</Defs>");
|
||||
f.write_all(s.as_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let animal_parts = part_data_animals();
|
||||
let mut animal_hediffs = String::new();
|
||||
for part in &animal_parts {
|
||||
animal_hediffs.push_str(&(construct_hediff(part, false) + "\n"));
|
||||
}
|
||||
|
||||
let mut human_hediffs = String::new();
|
||||
let human_parts = part_data_humans();
|
||||
for part in &human_parts {
|
||||
human_hediffs.push_str(&(construct_hediff(part, true) + "\n"));
|
||||
}
|
||||
|
||||
let (breasts, breast_hediffs) = part_data_breasts();
|
||||
let (parts, part_hediffs) = part_data_other();
|
||||
|
||||
let mut raceparts = String::new();
|
||||
let mut thingdefs = String::new();
|
||||
let mut surgeries = String::new();
|
||||
for part in animal_parts.iter().chain(human_parts.iter()).chain(breasts.iter()).chain(parts.iter()) {
|
||||
raceparts.push_str(&(construct_racepart(part) + "\n"));
|
||||
thingdefs.push_str(&(construct_thingdef(part) + "\n"));
|
||||
let surg = enumerate_surgeries(&part);
|
||||
for surgery in surg {
|
||||
surgeries.push_str(&(construct_surgery(&surgery) + "\n"));
|
||||
}
|
||||
}
|
||||
|
||||
let mut human_races = String::new();
|
||||
for group in racegroup_data_humans() {
|
||||
human_races.push_str(&construct_racegroup(&group));
|
||||
}
|
||||
|
||||
let mut animal_races = String::new();
|
||||
for group in racegroup_data_animals() {
|
||||
animal_races.push_str(&construct_racegroup(&group));
|
||||
}
|
||||
|
||||
write("HediffDefs/Hediffs_Animals", &animal_hediffs).unwrap();
|
||||
write("HediffDefs/Hediffs_Humans", &human_hediffs).unwrap();
|
||||
write("HediffDefs/Hediffs_Breasts", &breast_hediffs).unwrap();
|
||||
write("HediffDefs/Hediffs_Misc", &part_hediffs).unwrap();
|
||||
write("RaceSupport/Custom_Parts", &raceparts).unwrap();
|
||||
write("ThingDefs/Items_BodyParts", &thingdefs).unwrap();
|
||||
write("RecipeDefs/Recipes_Surgery", &surgeries).unwrap();
|
||||
write("RaceSupport/Humanoids", &human_races).unwrap();
|
||||
write("RaceSupport/Animals", &animal_races).unwrap();
|
||||
}
|
593
generator/src/parts.rs
Normal file
593
generator/src/parts.rs
Normal file
|
@ -0,0 +1,593 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum PartType {
|
||||
Anus,
|
||||
Breasts,
|
||||
Penis,
|
||||
Vagina,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Part {
|
||||
pub part_type: PartType,
|
||||
pub name: String,
|
||||
pub label: String,
|
||||
pub label_noun: String,
|
||||
pub description: String,
|
||||
// Known props:
|
||||
// Penis:
|
||||
// Girthy/Thin
|
||||
// Long/Small
|
||||
// Artificial
|
||||
// Barbed
|
||||
// Flared
|
||||
// Glowing
|
||||
// Humanlike
|
||||
// Internal
|
||||
// Knotted
|
||||
// Multiple
|
||||
// Prehensile
|
||||
// Resizable
|
||||
// Ridged
|
||||
// Rigid
|
||||
// Sheathed
|
||||
// Solid
|
||||
// STDImmune
|
||||
// Tapered
|
||||
//
|
||||
// Hole:
|
||||
// Loose/Tight
|
||||
// Barbed
|
||||
// Deep
|
||||
// Glowing
|
||||
// Resizable
|
||||
// Ridged
|
||||
// STDImmune
|
||||
|
||||
pub props: Vec<&'static str>,
|
||||
}
|
||||
|
||||
impl Part {
|
||||
fn standard(pre: &'static str, ty: PartType, species: &'static str, desc: &'static str, props: Vec<&'static str>) -> Option<Self> {
|
||||
let mut name = species.to_owned() + match ty {
|
||||
PartType::Anus => "Anus",
|
||||
PartType::Breasts => return None,
|
||||
PartType::Penis => "Penis",
|
||||
PartType::Vagina => "Vagina",
|
||||
};
|
||||
if let Some(c) = name.get_mut(0..1) {
|
||||
c.make_ascii_uppercase();
|
||||
};
|
||||
|
||||
let label_type = match ty {
|
||||
PartType::Anus => "anus",
|
||||
PartType::Breasts => panic!(),
|
||||
PartType::Penis => "penis",
|
||||
PartType::Vagina => "vagina",
|
||||
};
|
||||
let label = format!("{species} {label_type}");
|
||||
let label_noun = format!("{pre} {species} {label_type}");
|
||||
Some(Self {
|
||||
part_type: ty,
|
||||
name: name,
|
||||
label: label,
|
||||
label_noun: label_noun,
|
||||
description: desc.to_string(),
|
||||
props: props
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn construct_racepart(part: &Part) -> String {
|
||||
String::from(RACEPART_STRING).replace("{name}", &part.name)
|
||||
}
|
||||
|
||||
pub fn construct_hediff(part: &Part, human: bool) -> String {
|
||||
let mut s = String::from(HEDIFF_STRING);
|
||||
let ty = match part.part_type {
|
||||
PartType::Anus => "Anus",
|
||||
PartType::Breasts => return "".to_string(),
|
||||
PartType::Penis => "Penis",
|
||||
PartType::Vagina => "Vagina",
|
||||
};
|
||||
let mut props = String::new();
|
||||
for prop in &part.props {
|
||||
props.push_str(&format!("\n\t\t\t\t\t<li>{prop}</li>"));
|
||||
}
|
||||
if human {
|
||||
props.push_str(&format!("\n\t\t\t\t\t<li>Humanlike</li>"));
|
||||
}
|
||||
let replace = HashMap::from([
|
||||
("{type}", ty),
|
||||
("{name}", &part.name),
|
||||
("{label}", &part.label),
|
||||
("{label_noun}", &part.label_noun),
|
||||
("{description}", &part.description),
|
||||
("{props}", &props),
|
||||
]);
|
||||
for r in replace {
|
||||
s = s.replace(r.0, r.1);
|
||||
}
|
||||
s
|
||||
}
|
||||
|
||||
const HEDIFF_STRING: &'static str = "
|
||||
<rjw.HediffDef_PartBase ParentName=\"NaturalPrivatePart{type}\">
|
||||
<defName>{name}</defName>
|
||||
<label>{label}</label>
|
||||
<labelNoun>{label_noun}</labelNoun>
|
||||
<description>{description}</description>
|
||||
<descriptionHyperlinks>
|
||||
<ThingDef>{name}</ThingDef>
|
||||
</descriptionHyperlinks>
|
||||
<spawnThingOnRemoved>{name}</spawnThingOnRemoved>
|
||||
<modExtensions>
|
||||
<li Class=\"rjw.PartProps\">
|
||||
<props>{props}
|
||||
</props>
|
||||
</li>
|
||||
</modExtensions>
|
||||
</rjw.HediffDef_PartBase>";
|
||||
|
||||
const HEDIFF_STRING_EXT: &'static str = "
|
||||
<rjw.HediffDef_PartBase ParentName=\"NaturalPrivatePart{type}\">
|
||||
<defName>{name}</defName>
|
||||
<label>{label}</label>
|
||||
<labelNoun>{label_noun}</labelNoun>
|
||||
<description>{description}</description>
|
||||
<descriptionHyperlinks>
|
||||
<ThingDef>{name}</ThingDef>
|
||||
</descriptionHyperlinks>
|
||||
<spawnThingOnRemoved>{name}</spawnThingOnRemoved>
|
||||
{fields}<modExtensions>
|
||||
<li Class=\"rjw.PartProps\">
|
||||
<props>{props}
|
||||
</props>
|
||||
</li>
|
||||
</modExtensions>
|
||||
</rjw.HediffDef_PartBase>\n";
|
||||
|
||||
const HEDIFF_STRING_BREASTS: &'static str = "
|
||||
<rjw.HediffDef_PartBase ParentName=\"{type}\">
|
||||
<defName>{name}</defName>
|
||||
<label>{label}</label>
|
||||
<labelNoun>{label_noun}</labelNoun>
|
||||
<description>{description}</description>
|
||||
<descriptionHyperlinks>
|
||||
<ThingDef>{name}</ThingDef>
|
||||
</descriptionHyperlinks>
|
||||
<spawnThingOnRemoved>{name}</spawnThingOnRemoved>
|
||||
{fields}<modExtensions>
|
||||
<li Class=\"rjw.PartProps\">
|
||||
<props>{props}
|
||||
</props>
|
||||
</li>
|
||||
</modExtensions>
|
||||
</rjw.HediffDef_PartBase>\n";
|
||||
|
||||
const RACEPART_STRING: &'static str = "
|
||||
<rjw.RacePartDef>
|
||||
<defName>{name}</defName>
|
||||
<hediffName>{name}</hediffName>
|
||||
</rjw.RacePartDef>";
|
||||
|
||||
pub fn part_data_animals() -> Vec<Part> {
|
||||
vec![
|
||||
// Mammals
|
||||
Part::standard("a", PartType::Penis, "bear",
|
||||
"A small penis supported by a bone.",
|
||||
vec!["Flared", "Small", "Rigid"]
|
||||
).unwrap(),
|
||||
Part::standard("a", PartType::Penis, "bovine",
|
||||
"A rather long but thin penis with large testicles.",
|
||||
vec!["Long", "Sheathed", "Thin"]
|
||||
).unwrap(),
|
||||
Part::standard("a", PartType::Vagina, "bovine",
|
||||
"A rather thin and deep vagina, likely belonging to a large mammal.",
|
||||
vec!["Tight", "Deep"]
|
||||
).unwrap(),
|
||||
Part::standard("a", PartType::Anus, "dog",
|
||||
"A canine anus.",
|
||||
vec![]
|
||||
).unwrap(),
|
||||
Part::standard("a", PartType::Penis, "dino",
|
||||
"A large tapered penis that is slightly flattened at the top. It looks similar to a large tongue.",
|
||||
vec!["Girthy", "Tapered", "Internal"]
|
||||
).unwrap(),
|
||||
Part::standard("an", PartType::Penis, "elephant",
|
||||
"A large and flexible prehensile penis.",
|
||||
vec!["Girthy", "Long", "Prehensile", "Sheathed"]
|
||||
).unwrap(),
|
||||
Part::standard("an", PartType::Vagina, "elephant",
|
||||
"The deep vagina of a female elephant.",
|
||||
vec!["Deep"]
|
||||
).unwrap(),
|
||||
Part::standard("an", PartType::Anus, "equine",
|
||||
"An anus shaped like a doughnut.",
|
||||
vec!["Loose"]
|
||||
).unwrap(),
|
||||
Part::standard("a", PartType::Anus, "feline",
|
||||
"A feline anus.",
|
||||
vec!["Tight"]
|
||||
).unwrap(),
|
||||
Part::standard("a", PartType::Penis, "monkey",
|
||||
"A very thin, but otherwise humanoid-looking penis.",
|
||||
vec!["Thin"]
|
||||
).unwrap(),
|
||||
Part::standard("a", PartType::Penis, "pig",
|
||||
"A corkscrew shaped penis.",
|
||||
vec!["Long", "Sheathed", "Thin"]
|
||||
).unwrap(),
|
||||
Part::standard("a", PartType::Vagina, "pig",
|
||||
"The foldy vagina of a female pig.",
|
||||
vec!["Tight"]
|
||||
).unwrap(),
|
||||
Part {
|
||||
part_type: PartType::Vagina,
|
||||
name: "MammalVagina".to_string(),
|
||||
label: "mammal vagina".to_string(),
|
||||
label_noun: "a mammalian vagina".to_string(),
|
||||
description: "A generic vagina that probably belongs to some mammal.".to_string(),
|
||||
props: vec![],
|
||||
},
|
||||
Part {
|
||||
part_type: PartType::Anus,
|
||||
name: "MammalAnus".to_string(),
|
||||
label: "mammal anus".to_string(),
|
||||
label_noun: "a mammalian anus".to_string(),
|
||||
description: "A generic mammalian animal's anus.".to_string(),
|
||||
props: vec![],
|
||||
},
|
||||
Part {
|
||||
part_type: PartType::Anus,
|
||||
name: "CervineAnus".to_string(),
|
||||
label: "cervine anus".to_string(),
|
||||
label_noun: "a deer anus".to_string(),
|
||||
description: "A deer's anus.".to_string(),
|
||||
props: vec![],
|
||||
},
|
||||
Part {
|
||||
part_type: PartType::Vagina,
|
||||
name: "HyenaVagina".to_string(),
|
||||
label: "hyena pseudo-penis".to_string(),
|
||||
label_noun: "a hyena pseudo-penis".to_string(),
|
||||
description: "The clitoris of the female spotted hyena is enlarged into a pseudo-penis, through which the female urinates and reproduces. It can even get erect!".to_string(),
|
||||
props: vec!["Barbed", "Deep"],
|
||||
},
|
||||
Part {
|
||||
part_type: PartType::Penis,
|
||||
name: "MarinePenis".to_string(),
|
||||
label: "marine penis".to_string(),
|
||||
label_noun: "a marine mammal penis".to_string(),
|
||||
description: "A girthy, retractable penis that tapers to a point; it likely belongs to a seal, walrus, or hippo.".to_string(),
|
||||
props: vec!["Girthy", "Internal", "Tapered"],
|
||||
},
|
||||
Part {
|
||||
part_type: PartType::Vagina,
|
||||
name: "MarineVagina".to_string(),
|
||||
label: "marine vagina".to_string(),
|
||||
label_noun: "a marine mammal vagina".to_string(),
|
||||
description: "A slippery vagina.".to_string(),
|
||||
props: vec!["Loose"],
|
||||
},
|
||||
// Non-Mammals
|
||||
Part::standard("a", PartType::Penis, "cactoid",
|
||||
"A rough plant-like penis, with thorns along the shaft.",
|
||||
vec!["Barbed", "Ridged"]
|
||||
).unwrap(),
|
||||
Part::standard("a", PartType::Vagina, "cactoid",
|
||||
"A rough plant-like vagina, with thorns lining the inner walls. The thorns grip male genitals during sex.",
|
||||
vec!["Barbed", "Ridged"]
|
||||
).unwrap(),
|
||||
Part::standard("a", PartType::Anus, "cactoid",
|
||||
"A rough plant-like anus. No thorns this time.",
|
||||
vec!["Barbed", "Ridged"]
|
||||
).unwrap(),
|
||||
Part::standard("a", PartType::Penis, "turtle",
|
||||
"A large penis with a huge flare at the tip.",
|
||||
vec!["Flared", "Girthy", "Internal", "Long"]
|
||||
).unwrap(),
|
||||
Part {
|
||||
part_type: PartType::Penis,
|
||||
name: "Aedeagus".to_string(),
|
||||
label: "aedeagus".to_string(),
|
||||
label_noun: "an aedeagus".to_string(),
|
||||
description: "The phallus of a male arthropod, for excreting a spermatophore to inseminate a female arthropod.".to_string(),
|
||||
props: vec!["Rigid"],
|
||||
},
|
||||
Part {
|
||||
part_type: PartType::Vagina,
|
||||
name: "OviporeVagina".to_string(),
|
||||
label: "ovipore".to_string(),
|
||||
label_noun: "an ovipore".to_string(),
|
||||
description: "A pore-like sexual organ of a female arthropod for receiving a spermatophore. Very loosely comparable to a vagina.".to_string(),
|
||||
props: vec!["Rigid"],
|
||||
},
|
||||
Part {
|
||||
part_type: PartType::Penis,
|
||||
name: "AntherPenis".to_string(),
|
||||
label: "anther".to_string(),
|
||||
label_noun: "a flower's anther".to_string(),
|
||||
description: "A flower's male reproductive organ. A long and thin filament, with a large pollen-producing head in the tip.".to_string(),
|
||||
props: vec!["Long", "Thin"],
|
||||
},
|
||||
Part {
|
||||
part_type: PartType::Vagina,
|
||||
name: "PistilVagina".to_string(),
|
||||
label: "pistil".to_string(),
|
||||
label_noun: "a flower's pistil".to_string(),
|
||||
description: "A flower's female reproductive organ. The sticky entrance is connected to the ovaries via a long tube-like structure.".to_string(),
|
||||
props: vec![],
|
||||
},
|
||||
Part {
|
||||
part_type: PartType::Penis,
|
||||
name: "TentaclePenis".to_string(),
|
||||
label: "tentacles".to_string(),
|
||||
label_noun: "reproductive tentacles".to_string(),
|
||||
description: "A mass of tentacle-like penises, capable of both restraining and pleasuring.".to_string(),
|
||||
props: vec!["Long", "Multiple", "Prehensile"],
|
||||
},
|
||||
Part {
|
||||
part_type: PartType::Penis,
|
||||
name: "VinePenis".to_string(),
|
||||
label: "vines".to_string(),
|
||||
label_noun: "a mass of vines".to_string(),
|
||||
description: "Genetically altered vines capable of reproduction.".to_string(),
|
||||
props: vec!["Long", "Multiple", "Prehensile", "Thin"],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
pub fn part_data_humans() -> Vec<Part> {
|
||||
vec![
|
||||
Part::standard("a", PartType::Penis, "necro",
|
||||
"A disgusting, rotting penis that somehow still works.",
|
||||
vec![]
|
||||
).unwrap(),
|
||||
Part::standard("a", PartType::Vagina, "necro",
|
||||
"A disgusting, rotting vagina. Its insides are as cold as a grave.",
|
||||
vec!["Loose"]
|
||||
).unwrap(),
|
||||
Part::standard("a", PartType::Anus, "necro",
|
||||
"A disgusting, rotting anus. Its insides are as cold as a grave.",
|
||||
vec!["Loose"]
|
||||
).unwrap(),
|
||||
Part::standard("an", PartType::Penis, "elf",
|
||||
"A thinner and longer humanlike penis. Is that glitter?",
|
||||
vec!["Long", "Thin"]
|
||||
).unwrap(),
|
||||
Part::standard("an", PartType::Vagina, "elf",
|
||||
"A tighter humanlike vagina. Tastes like oranges.",
|
||||
vec!["Tight"]
|
||||
).unwrap(),
|
||||
Part::standard("an", PartType::Anus, "elf",
|
||||
"A tighter humanlike anus. Smells of flowers.",
|
||||
vec!["Tight"]
|
||||
).unwrap(),
|
||||
Part::standard("a", PartType::Penis, "golem",
|
||||
"A rough and jagged stone-like penis.",
|
||||
vec!["Rigid", "Solid"]
|
||||
).unwrap(),
|
||||
Part::standard("an", PartType::Penis, "ghoul",
|
||||
"A humanlike penis that glows slightly. It's very hot to the touch.",
|
||||
vec!["Glowing"]
|
||||
).unwrap(),
|
||||
Part::standard("a", PartType::Vagina, "ghoul",
|
||||
"A humanlike vagina that glows slightly. It is uncomfortably hot inside.",
|
||||
vec!["Glowing"]
|
||||
).unwrap(),
|
||||
Part::standard("a", PartType::Anus, "ghoul",
|
||||
"An anus that glows slightly. It is uncomfortably hot inside.",
|
||||
vec!["Glowing"]
|
||||
).unwrap(),
|
||||
Part::standard("an", PartType::Penis, "orc",
|
||||
"A girthy penis with a preputial ring, but otherwise similar to a humanoid penis.",
|
||||
vec!["Girthy"]
|
||||
).unwrap(),
|
||||
Part::standard("an", PartType::Vagina, "orc",
|
||||
"A loose humanlike vagina with very large lips.",
|
||||
vec!["Loose"]
|
||||
).unwrap(),
|
||||
Part::standard("an", PartType::Anus, "orc",
|
||||
"An anus that looks like a mix between an humanlike anus and an equine anus.",
|
||||
vec!["Loose"]
|
||||
).unwrap(),
|
||||
Part {
|
||||
part_type: PartType::Penis,
|
||||
name: "TreePenis".to_string(),
|
||||
label: "bark penis".to_string(),
|
||||
label_noun: "a wooden penis".to_string(),
|
||||
description: "A naturally grown wooden penis. The testicles are completely covered in hard, wooden bark, while the texture along the shaft is softer, leaving the tip uncovered.".to_string(),
|
||||
props: vec!["Ridged", "Rigid"],
|
||||
},
|
||||
Part {
|
||||
part_type: PartType::Vagina,
|
||||
name: "TreeVagina".to_string(),
|
||||
label: "bark vagina".to_string(),
|
||||
label_noun: "a wooden vagina".to_string(),
|
||||
description: "A naturally grown wooden vagina. While the outside looks like bark, the inside is soft.".to_string(),
|
||||
props: vec!["Ridged", "Rigid"],
|
||||
},
|
||||
Part {
|
||||
part_type: PartType::Anus,
|
||||
name: "TreeAnus".to_string(),
|
||||
label: "bark anus".to_string(),
|
||||
label_noun: "a wooden anus".to_string(),
|
||||
description: "A naturally grown wooden anus. While the outside looks like bark, the inside is soft.".to_string(),
|
||||
props: vec!["Ridged", "Rigid"],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
pub fn part_data_breasts() -> (Vec<Part>, String) {
|
||||
let breasts = vec![
|
||||
(Part {
|
||||
part_type: PartType::Breasts,
|
||||
name: "MammalBreasts".to_string(),
|
||||
label: "mammal breasts".to_string(),
|
||||
label_noun: "a pair of mammalian breasts".to_string(),
|
||||
description: "A group of breasts/nipples that mammals use to suckle their young.".to_string(),
|
||||
props: vec![],
|
||||
}, "MammalBreastBase", None),
|
||||
(Part {
|
||||
part_type: PartType::Breasts,
|
||||
name: "CatBreasts".to_string(),
|
||||
label: "kitty titties".to_string(),
|
||||
label_noun: "the kitty's titties".to_string(),
|
||||
description: "It's the kitty's titties!".to_string(),
|
||||
props: vec![],
|
||||
}, "MammalBreastBase", None),
|
||||
(Part {
|
||||
part_type: PartType::Breasts,
|
||||
name: "GhostBreasts".to_string(),
|
||||
label: "immaterial breasts".to_string(),
|
||||
label_noun: "a pair of immaterial breasts".to_string(),
|
||||
description: "A translucent, almost intangible pair of breasts. Touching them sends chills down the spine.".to_string(),
|
||||
props: vec!["Humanlike"],
|
||||
}, "NaturalPrivatePartBreast", Some(
|
||||
"<FluidType>Ecto</FluidType>\n\t\t"
|
||||
)),
|
||||
(Part {
|
||||
part_type: PartType::Breasts,
|
||||
name: "CactoidBreasts".to_string(),
|
||||
label: "cactoid breasts".to_string(),
|
||||
label_noun: "a pair of cactoid breasts".to_string(),
|
||||
description: "A pair of rough plant-like breasts, with thorns all around them, and flower-like nipples.".to_string(),
|
||||
props: vec![],
|
||||
}, "NaturalPrivatePartBreast", None),
|
||||
(Part {
|
||||
part_type: PartType::Breasts,
|
||||
name: "GhoulBreasts".to_string(),
|
||||
label: "irradiated breasts".to_string(),
|
||||
label_noun: "a pair of irradiated breasts".to_string(),
|
||||
description: "A pair of humanlike breasts that glow slightly. They're very hot to the touch.".to_string(),
|
||||
props: vec!["Humanlike"],
|
||||
}, "NaturalPrivatePartBreast", None),
|
||||
(Part {
|
||||
part_type: PartType::Breasts,
|
||||
name: "NecroBreasts".to_string(),
|
||||
label: "decayed breasts".to_string(),
|
||||
label_noun: "A pair of decayed breasts".to_string(),
|
||||
description: "A disgusting, rotting pair of breasts.".to_string(),
|
||||
props: vec!["Humanlike"],
|
||||
}, "NaturalPrivatePartBreast", None),
|
||||
(Part {
|
||||
part_type: PartType::Breasts,
|
||||
name: "OrcBreasts".to_string(),
|
||||
label: "orc breasts".to_string(),
|
||||
label_noun: "a pair of orc breasts".to_string(),
|
||||
description: "A pair of humanlike breasts that sag greatly.".to_string(),
|
||||
props: vec!["Humanlike"],
|
||||
}, "NaturalPrivatePartBreast", None),
|
||||
(Part {
|
||||
part_type: PartType::Breasts,
|
||||
name: "ScaleBreasts".to_string(),
|
||||
label: "scaly breasts".to_string(),
|
||||
label_noun: "a pair of scaly breasts".to_string(),
|
||||
description: "A pair of scale-covered breasts, without nipples.".to_string(),
|
||||
props: vec!["Humanlike"],
|
||||
}, "NaturalPrivatePartBreast", None),
|
||||
(Part {
|
||||
part_type: PartType::Breasts,
|
||||
name: "TreeBreasts".to_string(),
|
||||
label: "bark breasts".to_string(),
|
||||
label_noun: "a pair of wooden breasts".to_string(),
|
||||
description: "A pair of naturally grown wooden breasts. Hard bark covers the entire outer portion, while leaving the nipples underneath exposed.".to_string(),
|
||||
props: vec!["Humanlike", "Ridged", "Rigid"],
|
||||
}, "NaturalPrivatePartBreast", None),
|
||||
];
|
||||
|
||||
let mut hediffs = String::new();
|
||||
for breast in &breasts {
|
||||
let mut s = String::from(HEDIFF_STRING_BREASTS);
|
||||
let mut props = String::new();
|
||||
for prop in &breast.0.props {
|
||||
props.push_str(&format!("\n\t\t\t\t\t<li>{prop}</li>"));
|
||||
}
|
||||
let fields = breast.2.unwrap_or("");
|
||||
let replace = HashMap::from([
|
||||
("{type}", breast.1),
|
||||
("{name}", &breast.0.name),
|
||||
("{label}", &breast.0.label),
|
||||
("{label_noun}", &breast.0.label_noun),
|
||||
("{description}", &breast.0.description),
|
||||
("{fields}", &fields),
|
||||
("{props}", &props),
|
||||
]);
|
||||
for r in replace {
|
||||
s = s.replace(r.0, r.1);
|
||||
}
|
||||
hediffs.push_str(&s);
|
||||
}
|
||||
(breasts.into_iter().map(|x| x.0).collect(), hediffs)
|
||||
}
|
||||
|
||||
pub fn part_data_other() -> (Vec<Part>, String) {
|
||||
let parts = vec![
|
||||
(Part {
|
||||
part_type: PartType::Penis,
|
||||
name: "GhostPenis".to_string(),
|
||||
label: "immaterial penis".to_string(),
|
||||
label_noun: "an immaterial penis".to_string(),
|
||||
description: "A translucent, almost intangible penis. Touching it sends chills down the spine.".to_string(),
|
||||
props: vec!["Humanlike"],
|
||||
}, "<FluidType>Ecto</FluidType>\n\t\t".to_string() ),
|
||||
(Part {
|
||||
part_type: PartType::Vagina,
|
||||
name: "GhostVagina".to_string(),
|
||||
label: "immaterial vagina".to_string(),
|
||||
label_noun: "an immaterial vagina".to_string(),
|
||||
description: "A translucent, almost intangible vagina. Penetrating it sends chills down the spine.".to_string(),
|
||||
props: vec!["Humanlike"],
|
||||
}, "<FluidType>Ecto</FluidType>\n\t\t".to_string() ),
|
||||
(Part {
|
||||
part_type: PartType::Anus,
|
||||
name: "GhostAnus".to_string(),
|
||||
label: "immaterial anus".to_string(),
|
||||
label_noun: "an immaterial anus".to_string(),
|
||||
description: "A translucent, almost intangible anus. Penetrating it sends chills down the spine.".to_string(),
|
||||
props: vec!["Humanlike"],
|
||||
}, "<FluidType>Ecto</FluidType>\n\t\t".to_string() ),
|
||||
(Part {
|
||||
part_type: PartType::Vagina,
|
||||
name: "DemonTentaclesF".to_string(),
|
||||
label: "demon tentacle".to_string(),
|
||||
label_noun: "a female demon tentacle".to_string(),
|
||||
description: "A long and flexible tentacle, capable of laying eggs.".to_string(),
|
||||
props: vec!["Long", "Prehensile"],
|
||||
}, "<produceEggs>true</produceEggs>
|
||||
<minEggTick>12000</minEggTick>
|
||||
<maxEggTick>60000</maxEggTick>
|
||||
<FluidType>GR_EldritchInsectJelly</FluidType>\n\t\t".to_string() ),
|
||||
];
|
||||
|
||||
let mut hediffs = String::new();
|
||||
for part in &parts {
|
||||
let mut s = String::from(HEDIFF_STRING_EXT);
|
||||
let ty = match part.0.part_type {
|
||||
PartType::Anus => "Anus",
|
||||
PartType::Breasts => panic!(),
|
||||
PartType::Penis => "Penis",
|
||||
PartType::Vagina => "Vagina",
|
||||
};
|
||||
let mut props = String::new();
|
||||
for prop in &part.0.props {
|
||||
props.push_str(&format!("\n\t\t\t\t\t<li>{prop}</li>"));
|
||||
}
|
||||
let replace = HashMap::from([
|
||||
("{type}", ty),
|
||||
("{name}", &part.0.name),
|
||||
("{label}", &part.0.label),
|
||||
("{label_noun}", &part.0.label_noun),
|
||||
("{description}", &part.0.description),
|
||||
("{fields}", &part.1),
|
||||
("{props}", &props),
|
||||
]);
|
||||
for r in replace {
|
||||
s = s.replace(r.0, r.1);
|
||||
}
|
||||
hediffs.push_str(&s);
|
||||
}
|
||||
(parts.into_iter().map(|x| x.0).collect(), hediffs)
|
||||
}
|
1377
generator/src/racegroups.rs
Normal file
1377
generator/src/racegroups.rs
Normal file
File diff suppressed because it is too large
Load diff
138
generator/src/surgery.rs
Normal file
138
generator/src/surgery.rs
Normal file
|
@ -0,0 +1,138 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use crate::parts::{Part, PartType};
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
struct Operation {
|
||||
surgery_type: &'static str,
|
||||
verbs: (&'static str, &'static str, &'static str),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Surgery {
|
||||
part: Part,
|
||||
operation: Operation,
|
||||
}
|
||||
|
||||
const SURGERY_STRING: &str = "
|
||||
<RecipeDef ParentName=\"{type}\">
|
||||
<defName>{type}{name}</defName>
|
||||
<label>{verb.0} {label}</label>
|
||||
<description>{verb.1} {label_noun}</description>
|
||||
<jobString>{verb.2} {label_noun}</jobString>
|
||||
<ingredients>
|
||||
<li>
|
||||
<filter>
|
||||
<categories>
|
||||
<li>Medicine</li>
|
||||
</categories>
|
||||
</filter>
|
||||
<count>1</count>
|
||||
</li>
|
||||
<li>
|
||||
<filter>
|
||||
<thingDefs>
|
||||
<li>{name}</li>
|
||||
</thingDefs>
|
||||
</filter>
|
||||
<count>1</count>
|
||||
</li>
|
||||
</ingredients>
|
||||
<fixedIngredientFilter>
|
||||
<categories>
|
||||
<li>Medicine</li>
|
||||
</categories>
|
||||
<thingDefs>
|
||||
<li>{name}</li>
|
||||
</thingDefs>
|
||||
</fixedIngredientFilter>
|
||||
<addsHediff>{name}</addsHediff>
|
||||
</RecipeDef>";
|
||||
|
||||
const BREAST_SURGERIES: [Option<Operation>;3] = [
|
||||
Some(Operation{
|
||||
surgery_type: "MultiBreast",
|
||||
verbs: ("add", "Adds", "Adding"),
|
||||
}),
|
||||
Some(Operation{
|
||||
surgery_type: "BreastSurgery",
|
||||
verbs: ("attach", "Attaches", "Attaching"),
|
||||
}),
|
||||
None
|
||||
];
|
||||
|
||||
const PENIS_SURGERIES: [Option<Operation>;3] = [
|
||||
Some(Operation{
|
||||
surgery_type: "FutaMakingF",
|
||||
verbs: ("add", "Adds", "Adding"),
|
||||
}),
|
||||
Some(Operation{
|
||||
surgery_type: "MultiPenis",
|
||||
verbs: ("add", "Adds", "Adding"),
|
||||
}),
|
||||
Some(Operation{
|
||||
surgery_type: "SexReassignmentP",
|
||||
verbs: ("attach", "Attaches", "Attaching"),
|
||||
})
|
||||
];
|
||||
|
||||
const VAGINA_SURGERIES: [Option<Operation>;3] = [
|
||||
Some(Operation{
|
||||
surgery_type: "FutaMakingM",
|
||||
verbs: ("add", "Adds", "Adding"),
|
||||
}),
|
||||
Some(Operation{
|
||||
surgery_type: "MultiVagina",
|
||||
verbs: ("add", "Adds", "Adding"),
|
||||
}),
|
||||
Some(Operation{
|
||||
surgery_type: "SexReassignmentV",
|
||||
verbs: ("attach", "Attaches", "Attaching"),
|
||||
})
|
||||
];
|
||||
|
||||
const ANUS_SURGERIES: [Option<Operation>;3] = [
|
||||
Some(Operation{
|
||||
surgery_type: "MultiAnus",
|
||||
verbs: ("add", "Adds", "Adding"),
|
||||
}),
|
||||
Some(Operation{
|
||||
surgery_type: "AnalSurgery",
|
||||
verbs: ("attach", "Attaches", "Attaching"),
|
||||
}),
|
||||
None
|
||||
];
|
||||
|
||||
pub fn enumerate_surgeries<'a>(part: &Part) -> Vec<Surgery> {
|
||||
// Every part should have 2-3 relevant surgeries
|
||||
let surgeries = match part.part_type {
|
||||
PartType::Anus => ANUS_SURGERIES,
|
||||
PartType::Breasts => BREAST_SURGERIES,
|
||||
PartType::Penis => PENIS_SURGERIES,
|
||||
PartType::Vagina => VAGINA_SURGERIES,
|
||||
};
|
||||
|
||||
surgeries.iter().filter(|x| x.is_some()).map(|operation|
|
||||
Surgery {
|
||||
part: part.clone(),
|
||||
operation: operation.unwrap()
|
||||
}
|
||||
).collect()
|
||||
}
|
||||
|
||||
pub fn construct_surgery(surgery: &Surgery) -> String {
|
||||
let mut s = String::from(SURGERY_STRING);
|
||||
let replace = HashMap::from([
|
||||
("{type}", surgery.operation.surgery_type),
|
||||
("{verb.0}", surgery.operation.verbs.0),
|
||||
("{verb.1}", surgery.operation.verbs.1),
|
||||
("{verb.2}", surgery.operation.verbs.2),
|
||||
("{name}", &surgery.part.name),
|
||||
("{label}", &surgery.part.label),
|
||||
("{label_noun}", &surgery.part.label_noun),
|
||||
]);
|
||||
for r in replace {
|
||||
s = s.replace(r.0, r.1);
|
||||
}
|
||||
s
|
||||
}
|
77
generator/src/things.rs
Normal file
77
generator/src/things.rs
Normal file
|
@ -0,0 +1,77 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use crate::parts::{Part, PartType};
|
||||
|
||||
const THINGDEF_STRING: &str = "
|
||||
<ThingDef ParentName=\"rjw_BodyPartNaturalBase{type}\">
|
||||
<defName>{name}</defName>
|
||||
<label>{label}</label>
|
||||
<description>{description}</description>
|
||||
<statBases>
|
||||
<MarketValue>{value}</MarketValue>
|
||||
<Mass>{mass}</Mass>
|
||||
</statBases>
|
||||
</ThingDef>";
|
||||
|
||||
|
||||
pub fn construct_thingdef(part: &Part) -> String {
|
||||
let mut s = String::from(THINGDEF_STRING);
|
||||
|
||||
let ty = match part.part_type {
|
||||
PartType::Anus => "Anus",
|
||||
PartType::Breasts => "Breast",
|
||||
PartType::Penis => "GenMale",
|
||||
PartType::Vagina => "GenFemale",
|
||||
};
|
||||
|
||||
let mass = match part.part_type {
|
||||
PartType::Anus => 0.12,
|
||||
PartType::Breasts => 0.5,
|
||||
PartType::Penis => 0.16,
|
||||
PartType::Vagina => 0.10,
|
||||
};
|
||||
|
||||
let mut mass_mult = 1.;
|
||||
|
||||
for prop in &part.props {
|
||||
match *prop {
|
||||
// positive
|
||||
"Long" => mass_mult += 0.5,
|
||||
"Girthy" => mass_mult += 0.5,
|
||||
"Deep" => mass_mult += 0.3,
|
||||
"Knotted" => mass_mult += 0.1,
|
||||
"Solid" => mass_mult += 1.,
|
||||
"Multiple" => mass_mult += 0.2,
|
||||
// negative
|
||||
"Thin" => mass_mult -= 0.3,
|
||||
"Small" => mass_mult -= 0.5,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
let m = format!("{:.3}", mass * mass_mult);
|
||||
|
||||
let val = match part.name.as_str() {
|
||||
// positive
|
||||
"DinoPenis" => "300",
|
||||
"DinoVagina" => "300",
|
||||
"TentaclePenis" => "350",
|
||||
// negative
|
||||
"OviporeVagina" => "50",
|
||||
"AedeagusPenis" => "50",
|
||||
_ => "250",
|
||||
};
|
||||
|
||||
let replace = HashMap::from([
|
||||
("{type}", ty),
|
||||
("{name}", &part.name),
|
||||
("{label}", &part.label),
|
||||
("{description}", &part.description),
|
||||
("{value}", val),
|
||||
("{mass}", &m),
|
||||
]);
|
||||
for r in replace {
|
||||
s = s.replace(r.0, r.1);
|
||||
}
|
||||
s
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue