public static void other_rando(KPaths paths) { // NameGen if (Properties.Settings.Default.RandomizeNameGen) { List <string> male_names = Properties.Settings.Default.FirstnamesM.Cast <string>().Select(x => x.Trim()).Where(x => x.Length > 2).ToList(); LTR ltr_male_names = new LTR(male_names); List <string> female_names = Properties.Settings.Default.FirstnamesF.Cast <string>().Select(x => x.Trim()).Where(x => x.Length > 2).ToList(); LTR ltr_female_names = new LTR(female_names); List <string> last_names = Properties.Settings.Default.Lastnames.Cast <string>().Select(x => x.Trim()).Where(x => x.Length > 2).ToList(); LTR ltr_last_names = new LTR(last_names); if (male_names.Any()) { ltr_male_names.WriteToFile(paths.Override + "humanm.ltr"); } if (female_names.Any()) { ltr_female_names.WriteToFile(paths.Override + "humanf.ltr"); } if (last_names.Any()) { ltr_last_names.WriteToFile(paths.Override + "humanl.ltr"); } } // Polymorph // Random NPC Pazaak Decks if (Properties.Settings.Default.RandomizePazaakDecks) { string ops = "+-*"; BIF b = new BIF(paths.data + "\\2da.bif"); KEY k = new KEY(paths.chitin_backup); b.AttachKey(k, "data\\2da.bif"); var resource = b.VariableResourceTable.Where(x => x.ResRef == PAZAAKDECKS_RESREF).FirstOrDefault(); if (resource == null) { throw new ArgumentOutOfRangeException($"The ResRef \"{PAZAAKDECKS_RESREF}\" could not be found."); } TwoDA t = new TwoDA(resource.EntryData, PAZAAKDECKS_RESREF); foreach (string c in t.Columns) { if (c == DECKNAME_COLUMN) { continue; } // [+-*][1-6] // "" + ops[Randomize.Rng.Next(0, 3)] + Convert.ToString(Randomize.Rng.Next(1, 7)); t.Data[c][0] = $"{ops[Randomize.Rng.Next(0, 3)]}{Convert.ToString(Randomize.Rng.Next(1, 7))}"; t.Data[c][1] = $"{ops[Randomize.Rng.Next(0, 3)]}{Convert.ToString(Randomize.Rng.Next(1, 7))}"; t.Data[c][2] = $"{ops[Randomize.Rng.Next(0, 3)]}{Convert.ToString(Randomize.Rng.Next(1, 7))}"; t.Data[c][3] = $"{ops[Randomize.Rng.Next(0, 3)]}{Convert.ToString(Randomize.Rng.Next(1, 7))}"; } t.WriteToDirectory(paths.Override); } }
public static void other_rando(KPaths paths) { // NameGen if (Properties.Settings.Default.RandomizeNameGen) { List <string> male_names = Properties.Settings.Default.FirstnamesM.Cast <string>().Select(x => x.Trim()).Where(x => x.Length > 2).ToList(); LTR ltr_male_names = new LTR(male_names); List <string> female_names = Properties.Settings.Default.FirstnamesF.Cast <string>().Select(x => x.Trim()).Where(x => x.Length > 2).ToList(); LTR ltr_female_names = new LTR(female_names); List <string> last_names = Properties.Settings.Default.Lastnames.Cast <string>().Select(x => x.Trim()).Where(x => x.Length > 2).ToList(); LTR ltr_last_names = new LTR(last_names); if (male_names.Any()) { NameGenLookup.Add(NAME_GEN_MALE, male_names); ltr_male_names.WriteToFile(paths.Override + "humanm.ltr"); } if (female_names.Any()) { NameGenLookup.Add(NAME_GEN_FEMALE, female_names); ltr_female_names.WriteToFile(paths.Override + "humanf.ltr"); } if (last_names.Any()) { NameGenLookup.Add(NAME_GEN_LAST, last_names); ltr_last_names.WriteToFile(paths.Override + "humanl.ltr"); } } // Polymorph if (Properties.Settings.Default.PolymorphMode) { BIF b = new BIF(paths.data + "templates.bif"); KEY k = new KEY(paths.chitin); b.AttachKey(k, "data\\templates.bif"); foreach (var res in b.VariableResourceTable.Where(x => x.ResourceType == ResourceType.UTI)) { GFF g = new GFF(res.EntryData); int item_basetype = (g.Top_Level.Fields.Where(x => x.Label == "BaseItem").FirstOrDefault() as GFF.INT).Value; //ignore items that can't be equipped in the chest slot if ((item_basetype < 35 || item_basetype > 43) && (item_basetype < 66 || item_basetype > 68) && item_basetype != 85 && item_basetype != 89) { continue; } ushort rando_appearance = 0; while (Globals.BROKEN_CHARS.Contains((int)rando_appearance) || Globals.LARGE_CHARS.Contains((int)rando_appearance)) { rando_appearance = (ushort)Randomize.Rng.Next(508); } //STRUCT that gives an item the "disguise" property GFF.STRUCT disguise_prop = new GFF.STRUCT("", 0, new List <GFF.FIELD>() { new GFF.BYTE("ChanceAppear", 100), new GFF.BYTE("CostTable", 0), new GFF.WORD("CostValue", 0), new GFF.BYTE("Param1", 255), new GFF.BYTE("Param1Value", 0), new GFF.WORD("PropertyName", 59), //Disguise property new GFF.WORD("Subtype", rando_appearance), //The random appearance value (same values used in model rando) } ); //Adds the disguise property to the UTI's property list (g.Top_Level.Fields.Where(x => x.Label == "PropertiesList").FirstOrDefault() as GFF.LIST).Structs.Add(disguise_prop); PolymorphLookupTable.Add(res.ResRef, rando_appearance); g.WriteToFile(paths.Override + res.ResRef + ".uti"); } } // Random NPC Pazaak Decks if (Properties.Settings.Default.RandomizePazaakDecks) { string ops = "+-*"; BIF b = new BIF(paths.data + "2da.bif"); KEY k = new KEY(paths.chitin_backup); b.AttachKey(k, "data\\2da.bif"); var resource = b.VariableResourceTable.Where(x => x.ResRef == PAZAAKDECKS_RESREF).FirstOrDefault(); if (resource == null) { throw new ArgumentOutOfRangeException($"The ResRef \"{PAZAAKDECKS_RESREF}\" could not be found."); } TwoDA t = new TwoDA(resource.EntryData, PAZAAKDECKS_RESREF); foreach (string c in t.Columns) { if (c == DECKNAME_COLUMN) { NpcPazaakLookupTable.Add(c, new List <Tuple <string, string> >() { new Tuple <string, string>(t.Data[c][0], t.Data[c][0]), new Tuple <string, string>(t.Data[c][1], t.Data[c][1]), new Tuple <string, string>(t.Data[c][2], t.Data[c][2]), new Tuple <string, string>(t.Data[c][3], t.Data[c][3]), }); continue; } NpcPazaakLookupTable.Add(c, new List <Tuple <string, string> >()); // [+-*][1-6] // "" + ops[Randomize.Rng.Next(0, 3)] + Convert.ToString(Randomize.Rng.Next(1, 7)); var card0 = $"{ops[Randomize.Rng.Next(0, 3)]}{Convert.ToString(Randomize.Rng.Next(1, 7))}"; var card1 = $"{ops[Randomize.Rng.Next(0, 3)]}{Convert.ToString(Randomize.Rng.Next(1, 7))}"; var card2 = $"{ops[Randomize.Rng.Next(0, 3)]}{Convert.ToString(Randomize.Rng.Next(1, 7))}"; var card3 = $"{ops[Randomize.Rng.Next(0, 3)]}{Convert.ToString(Randomize.Rng.Next(1, 7))}"; NpcPazaakLookupTable[c].Add(new Tuple <string, string>(t.Data[c][0], card0)); NpcPazaakLookupTable[c].Add(new Tuple <string, string>(t.Data[c][1], card1)); NpcPazaakLookupTable[c].Add(new Tuple <string, string>(t.Data[c][2], card2)); NpcPazaakLookupTable[c].Add(new Tuple <string, string>(t.Data[c][3], card3)); t.Data[c][0] = card0; t.Data[c][1] = card1; t.Data[c][2] = card2; t.Data[c][3] = card3; } t.WriteToDirectory(paths.Override); } // Party Rando if (Properties.Settings.Default.RandomizePartyMembers) { BIF b = new BIF(paths.data + "templates.bif"); KEY k = new KEY(paths.chitin_backup); b.AttachKey(k, "data\\templates.bif"); foreach (var ID in Party_IDs) { // Find a creature that isn't this party member var charsList = b.VariableResourceTable.Where(x => x.ResourceType == ResourceType.UTC).ToList(); var character = charsList.First(x => x.ResRef == ID.Item2); BIF.VariableResourceEntry resource; GFF g; do { int randoIndex = Randomize.Rng.Next(charsList.Count); resource = charsList[randoIndex]; if (resource.ResRef != character.ResRef && !InvalidPartyMembers.Contains(resource.ResRef)) { // Potentially valid party member. Check against broken and large characters. g = new GFF(resource.EntryData); var appearance = g.Top_Level.Fields.First(x => x.Label == ModelRando.LBL_APPEARANCE_TYPE) as GFF.WORD; if (!Globals.BROKEN_CHARS.Contains(appearance.Value) && !Globals.LARGE_CHARS.Contains(appearance.Value)) { break; // Character is valid. } } // Character is invalid, broken, or large. Skip it. Console.WriteLine($"Skipped invalid party member ({resource.ResRef}) when randomizing {ID.Item2}."); }while (true); PartyLookupTable.Add(ID.Item3, resource.ResRef); GFF gOld = new GFF(character.EntryData); ushort portraitId = (gOld.Top_Level.Fields.Where(x => x.Label == "PortraitId").FirstOrDefault() as GFF.WORD)?.Value ?? 0; // Turns creature file into a playable companion replacing the current party member. (g.Top_Level.Fields.Where(x => x.Label == "Conversation").FirstOrDefault() as GFF.ResRef).Reference = ID.Item1; (g.Top_Level.Fields.Where(x => x.Label == "Tag").FirstOrDefault() as GFF.CExoString).CEString = ID.Item3; (g.Top_Level.Fields.Where(x => x.Label == "TemplateResRef").FirstOrDefault() as GFF.ResRef).Reference = ID.Item2; (g.Top_Level.Fields.Where(x => x.Label == "NoPermDeath").FirstOrDefault() as GFF.BYTE).Value = 1; (g.Top_Level.Fields.Where(x => x.Label == "FactionID").FirstOrDefault() as GFF.WORD).Value = 2; // Give new companion the old companion's portrait. if (g.Top_Level.Fields.Where(x => x.Label == "PortraitId").FirstOrDefault() is GFF.WORD field) { field.Value = portraitId; } // Henchmen script suite. (g.Top_Level.Fields.Where(x => x.Label == "ScriptHeartbeat").FirstOrDefault() as GFF.ResRef).Reference = "k_hen_heartbt01"; (g.Top_Level.Fields.Where(x => x.Label == "ScriptOnNotice").FirstOrDefault() as GFF.ResRef).Reference = "k_hen_percept01"; (g.Top_Level.Fields.Where(x => x.Label == "ScriptSpellAt").FirstOrDefault() as GFF.ResRef).Reference = ""; (g.Top_Level.Fields.Where(x => x.Label == "ScriptAttacked").FirstOrDefault() as GFF.ResRef).Reference = "k_hen_attacked01"; (g.Top_Level.Fields.Where(x => x.Label == "ScriptDamaged").FirstOrDefault() as GFF.ResRef).Reference = "k_hen_damage01"; (g.Top_Level.Fields.Where(x => x.Label == "ScriptDisturbed").FirstOrDefault() as GFF.ResRef).Reference = ""; (g.Top_Level.Fields.Where(x => x.Label == "ScriptEndRound").FirstOrDefault() as GFF.ResRef).Reference = "k_hen_combend01"; (g.Top_Level.Fields.Where(x => x.Label == "ScriptEndDialogu").FirstOrDefault() as GFF.ResRef).Reference = ""; (g.Top_Level.Fields.Where(x => x.Label == "ScriptDialogue").FirstOrDefault() as GFF.ResRef).Reference = "k_hen_dialogue01"; (g.Top_Level.Fields.Where(x => x.Label == "ScriptSpawn").FirstOrDefault() as GFF.ResRef).Reference = "k_hen_spawn01"; (g.Top_Level.Fields.Where(x => x.Label == "ScriptRested").FirstOrDefault() as GFF.ResRef).Reference = ""; (g.Top_Level.Fields.Where(x => x.Label == "ScriptDeath").FirstOrDefault() as GFF.ResRef).Reference = ""; (g.Top_Level.Fields.Where(x => x.Label == "ScriptOnBlocked").FirstOrDefault() as GFF.ResRef).Reference = "k_hen_blocked01"; (g.Top_Level.Fields.Where(x => x.Label == "ScriptUserDefine").FirstOrDefault() as GFF.ResRef).Reference = ""; // Add a Dummy Feat to prevent the feats menu from crashing. (g.Top_Level.Fields.Where(x => x.Label == "FeatList").FirstOrDefault() as GFF.LIST).Structs.Add(new GFF.STRUCT("", 1, new List <GFF.FIELD>() { new GFF.WORD("Feat", 27) })); // If they are a Jedi class, add a Power to prevent powers menu from crashing. var charClassList = g.Top_Level.Fields.First(x => x.Label == "ClassList") as GFF.LIST; foreach (var classStruct in charClassList.Structs) { var charClassValue = (classStruct.Fields.First(x => x.Label == "Class") as GFF.INT).Value; if (charClassValue == 3 || // Jedi Guardian charClassValue == 4 || // Jedi Consular charClassValue == 5) // Jedi Sentinel { // Build a power to add to the list. GFF.STRUCT affectMind = new GFF.STRUCT("", 3, new List <GFF.FIELD>() { new GFF.WORD("Spell", 6), new GFF.BYTE("SpellMetaMagic", 0), new GFF.BYTE("SpellFlags", 1), }); if (!(classStruct.Fields.FirstOrDefault(x => x.Label == "KnownList0") is GFF.LIST knownList)) { // KnownList0 doesn't exist. Create it and add Affect Mind. classStruct.Fields.Add(new GFF.LIST("KnownList0", new List <GFF.STRUCT>() { affectMind })); } else if (knownList.Structs.Count == 0) { // KnownList0 exists but is empty. Add affect Mind. knownList.Structs.Add(affectMind); } break; } } g.WriteToFile(paths.Override + ID.Item2 + ".utc"); } }