private static List <Character> GetInhabitants(int count, Culture culture) { var r = new List <Character>(); var familyName = string.Empty; //var dontShareSurname = true; var areMarried = Random.NextDouble() > 0.7; var firstPlan = string.Empty; count = 2; for (var i = 0; i < count; i++) { Character c; var plan = culture.Bodyplans.PickWeighted().Name; if (i > 0 && Random.NextDouble() > 0.7) { plan = firstPlan; } Realms world; switch (culture.ID) { case "human": world = Realms.Nox; break; case "seradevar": world = Realms.Seradevari; break; default: world = Realms.Nox; break; } var myGender = count == 1 ? Gender.RollDice : (i == 0 ? Gender.Male : Gender.Female); c = Character.Generate(plan, myGender, myGender, world); if (i == 0) { familyName = c.Name.Surname; firstPlan = plan; } if (i == 1) { /* Just for the record, because I've had the wildest time trying to figure this out years later: * 0 0,25 0,5 0,75 1 <- culture.Marriage * 0 friend spouse spouse spouse spouse * 0,25 friend friend spouse spouse spouse * 0,5 friend friend friend spouse spouse * 0,75 friend friend friend friend spouse * 1 friend friend friend friend friend * ^- Random.NextDouble() * So a culture with Marriage set to 0 would NEVER marry, and a culture with Marriage set to 1 * NEARLY ALWAYS marries. */ var shipType = Random.NextDouble() < culture.Marriage ? "spouse" : "friend"; //if we chose spouse, handle the wife taking the surname of the husband. var ship = new Token(c.ID); ship.AddToken(shipType); r[0].Path("ships").Tokens.Add(ship); ship = new Token(r[0].ID); ship.AddToken(shipType); c.Path("ships").Tokens.Add(ship); } r.Add(c); //Scheduler.AddSchedule("villager", c); } return(r); }
/// <summary> /// Creates a new Token with the same name, value, text, and (recursively) children as this one. /// </summary> /// <param name="deep">If true, children are also cloned. If false, they are passed as references to the originals.</param> /// <returns>Returns a copy of this Token.</returns> public Token Clone(bool deep = true) { var t = new Token(Name, Value, Text); foreach (var child in Tokens) { t.AddToken(deep ? child.Clone() : child); } return(t); }
/// <summary> /// Put something IN a container, or SELL it to a vendor. /// </summary> /// <param name="boardchar">The container/vendor</param> /// <param name="token">The item token</param> /// <param name="chosen">The item's definition</param> /// <returns>Returns a failure message or null.</returns> /// <remarks>Sets vendorCaughtYou when you're being criminal scum.</remarks> private static string TryStore(BoardChar boardchar, Token token, InventoryItem chosen) { var inv = boardchar.Character.GetToken("items"); var con = other; if (token.HasToken("cursed")) { //Reveal the cursed item as such if we didn't already know. if (!token.GetToken("cursed").HasToken("known")) { token.GetToken("cursed").AddToken("known"); } return("It's cursed! You can't unequip it."); //DO NOT TRANSLATE -- Curses will be replaced with better terms and variants such as "Slippery" or "Sticky". } if (token.HasToken("equipped")) { //You should probably switch over to the Inventory screen and take the thing off. return(i18n.GetString("inventory_youareusingthis")); } if (mode == ContainerMode.Vendor && token.HasToken("owner") && token.GetToken("owner").Text == vendorChar.Name.ToID()) { //We tried to sell the vendor's own crap back to them. vendorCaughtYou = true; //Handler can deal with this now. return(i18n.Format("inventory_vendorcaughtyou", vendorChar.Name.ToString()).Viewpoint(vendorChar)); } if (token.HasToken("torn")) { price = (float)Math.Ceiling(price * 0.25f); //this ain't worth shit, bruh. } if (mode == ContainerMode.Vendor && price != 0) { //Handle the transaction. var pMoney = boardchar.Character.GetToken("money"); var vMoney = vendorChar.GetToken("money"); if (vMoney.Value - price < 0) { return(i18n.Format("inventory_vendorcantaffordthis", vendorChar.Name.ToString())); } //TODO: add charisma and relationship bonuses -- I'll throw in another tenner cos you're awesome. //notice that the bonus is determined AFTER the budget check so a vendor won't bug out on that. pMoney.Value += price; vMoney.Value -= price; token.AddToken("for_sale"); } con.Tokens.Add(token); inv.Tokens.Remove(token); boardchar.ParentBoard.Redraw(); boardchar.ParentBoard.Draw(); boardchar.Character.CheckHasteSlow(); NoxicoGame.Sound.PlaySound("set://PutItem"); return(null); }
private static void ApplyBonusMaybe(Token possibleItem, InventoryItem knownItem) { if (knownItem.HasToken("unique")) { return; } if (Random.NextDouble() < 0.3) { return; } if (knownItem.HasToken("weapon")) { var bonus = Random.Next(1, 6); possibleItem.AddToken("bonus", bonus); } }
public bool Equip(Character character, Token item) { /* * if rings and character is quadruped, error out. * if required slots have covering slots * check for target slot's reachability. * if unreachable, try to temp-remove items in covering slots, recursively. * if still unreachable, error out. * if required slots are taken * try to unequip the items in those slots, recursively. * if required slots are still taken, error out; * else, mark the item as equipped. * replace each temp-removed item whose required slots are still free. */ var equip = this.GetToken("equipable"); var tempRemove = new Stack <Token>(); //var items = character.GetToken("items"); //TODO: make full quadrupeds equip weapons in their mouth instead of the hands they don't have. //This means they can carry only ONE weapon at a time, and maybe not be able to converse until unequipped. if ((equip.HasToken("hands") || equip.HasToken("ring")) && (character.HasToken("quadruped"))) { throw new ItemException(i18n.Format("cannot_equip_no_hands", this.ToString(item, true, false))); } if (equip.HasToken("hand")) { CheckHands(character, "hand"); } else if (equip.HasToken("ring")) { CheckHands(character, "ring"); } if (equip.HasToken("pants") || equip.HasToken("underpants") || equip.HasToken("shoes") || equip.HasToken("socks")) { CheckPants(character, equip); } if (character.HasToken("snaketail") && (equip.HasToken("pants") || equip.HasToken("underpants"))) { throw new ItemException(i18n.Format("cannot_equip_no_legs", this.ToString(item, true, false))); } //lol foreach (var nonLayeredSlot in new[] { "socks", "hat", "mask", "goggles", "neck" }) { if (equip.HasToken(nonLayeredSlot)) { var currentNonLayeredItem = character.GetEquippedItemBySlot(nonLayeredSlot); if (currentNonLayeredItem != null) { currentNonLayeredItem.Unequip(character); } } } foreach (var t in equip.Tokens) { if (t.Name == "underpants" && (!TempRemove(character, tempRemove, "pants") || !TempRemove(character, tempRemove, "underpants"))) { return(false); } else if (t.Name == "undershirt" && (!TempRemove(character, tempRemove, "shirt") || !TempRemove(character, tempRemove, "undershirt"))) { return(false); } else if (t.Name == "shirt" && (!TempRemove(character, tempRemove, "shirt") || !TempRemove(character, tempRemove, "jacket"))) { return(false); } else if (t.Name == "jacket" && (!TempRemove(character, tempRemove, "cloak") || !TempRemove(character, tempRemove, "jacket"))) { return(false); } else if (t.Name == "socks" && (!TempRemove(character, tempRemove, "shoes") || !TempRemove(character, tempRemove, "socks"))) { return(false); } } var succeed = true; if (!this.OnEquip.IsBlank()) { succeed = Convert.ToBoolean(RunScript(item, this.OnEquip, character, null, null)); } if (succeed) { item.AddToken("equipped"); } if (this.HasToken("timer") && !this.OnTimer.IsBlank() && !item.HasToken("timer")) { item.AddToken("timer").Value = (this.GetToken("timer").Value == 0) ? 60 : this.GetToken("timer").Value; item.GetToken("timer").Text = NoxicoGame.InGameTime.ToBinary().ToString(); } character.RecalculateStatBonuses(); character.CheckHasteSlow(); //Difficult bit: gotta re-equip tempremovals without removing the target item all over. THAT WOULD BE QUITE BAD. return(succeed); }
public static List <Token> GetRandomLoot(string target, string type, Dictionary <string, string> filters = null) { Func <string, List <string> > getPal = new Func <string, List <string> >(c => { var pal = new List <string>(); var cols = new List <string>(); for (var i = 0; i < 4; i++) { if (cols.Count == 0) { cols.AddRange(c.Split(',').Select(x => x.Trim()).ToList()); } var co = cols.PickOne(); cols.Remove(co); pal.Add(co); } return(pal); }); var colors = getPal("black,gray,white,red,blue,green,navy,maroon,pink,yellow"); var color = -1; Func <string, Token> parseOption = new Func <string, Token>(option => { if (option[0] == '@') { var possibilities = new List <Token>(); option = option.Substring(1); if (option[0] == '-') { //simple negatory token check var items = NoxicoGame.KnownItems.Where(i => (!i.HasToken(option))).ToList(); if (items.Count > 0) { possibilities.Add(new Token(items.PickOne().ID)); } } else if (option.Contains('-') || option.Contains('+')) { //complicated token check var fuckery = option.Replace("+", ",").Replace("-", ",-").Split(','); foreach (var knownItem in NoxicoGame.KnownItems.Where(i => !i.HasToken("unique"))) { var includeThis = false; foreach (var f*****g in fuckery) { if (f*****g[0] != '-' && knownItem.HasToken(f*****g)) { includeThis = true; } else if (knownItem.HasToken(f*****g.Substring(1))) { includeThis = false; break; } } if (includeThis) { var newPoss = new Token(knownItem.ID); if (knownItem.HasToken("colored")) { newPoss.AddToken("color", 0, colors[color == -1 ? Random.Next(colors.Count) : color]); } ApplyBonusMaybe(newPoss, knownItem); possibilities.Add(newPoss); } } } else { //simple token check var items = NoxicoGame.KnownItems.Where(i => i.HasToken(option) && !i.HasToken("unique")).ToList(); if (items.Count > 0) { var knownItem = items.PickOne(); var newPoss = new Token(knownItem.ID); if (knownItem.HasToken("colored")) { newPoss.AddToken("color", 0, colors[color == -1 ? Random.Next(colors.Count) : color]); } if (knownItem.ID == "book") { newPoss.AddToken("id", NoxicoGame.BookTitles.Keys.ToArray().PickOne()); } possibilities.Add(newPoss); } } if (possibilities.Count > 0) { return(possibilities.PickOne()); } } else { //direct item ID //ascertain existance first, and maybe add a color or BUC state. var item = NoxicoGame.KnownItems.FirstOrDefault(i => i.ID == option); if (item != null) { var newPoss = new Token(option); if (item.HasToken("colored")) { newPoss.AddToken("color", 0, colors[color == -1 ? Random.Next(colors.Count) : color]); } return(newPoss); } } return(null); }); var loot = new List <Token>(); var lootsets = GetLoots(target, type, filters); if (lootsets.Count == 0) { return(loot); } var lootset = lootsets.PickOne(); if (!lootset.HasToken("someof") && !lootset.HasToken("oneof") && !lootset.HasToken("oneofeach")) { return(loot); } foreach (var of in lootset.Tokens) { var options = new List <string>(); var min = 1; var max = 1; color = -1; if (of.Name == "colors") { colors = getPal(string.Join(",", of.Tokens.Select(x => x.Name).ToList())); continue; } else if (of.Name == "oneof") { options = of.Tokens.Select(x => x.Name).Where(x => x[0] != '$').ToList(); color = of.HasToken("$color") ? (int)of.GetToken("$color").Value - 1 : -1; } else if (of.Name == "someof") { options = of.Tokens.Select(x => x.Name).Where(x => x[0] != '$').ToList(); color = of.HasToken("$color") ? (int)of.GetToken("$color").Value - 1 : -1; if (of.Text != null && of.Text.Contains('-')) { var minmax = of.Text.Split('-'); min = int.Parse(minmax[0]); max = int.Parse(minmax[1]); } else { min = max = (int)of.Value; } } else if (of.Name == "oneofeach") { foreach (var item in of.Tokens) { if (item.Name == "$color") { color = (int)of.GetToken("$color").Value - 1; continue; } var thing = parseOption(item.Name); if (thing != null) { loot.Add(thing); } } continue; } else { continue; } var amount = Random.Next(min, max); while (amount > 0) { var option = options.PickOne(); var toAdd = parseOption(option); if (toAdd != null) { loot.Add(toAdd); } amount--; } } return(loot); }