/// <summary> /// Returns a list of possible Recipes that a given character is able to craft. /// </summary> /// <param name="carrier">Probably the player character.</param> /// <returns>A list of possible recipes. Keep it, and invoke Apply on the player's choice.</returns> public static List <Recipe> GetPossibilities(Character carrier) { Carrier = carrier; ItemsToWorkWith = Carrier.GetToken("items"); var results = new List <Recipe>(); var tml = Mix.GetTokenTree("crafting.tml"); foreach (var recipe in tml) { var considered = new List <Token>(); var resultName = "?"; if (recipe.HasToken("produce")) { resultName = recipe.GetToken("produce").Text; } var resultingSourceItem = default(InventoryItem); var steps = recipe.Tokens; var stepRefs = new Token[steps.Count()]; var i = 0; var newRecipe = new Recipe(); foreach (var step in steps) { if (step.Name == "consume" || step.Name == "require") { var amount = 1; if (step.HasToken("amount")) { amount = (int)step.GetToken("amount").Value; } var numFound = 0; if (step.Text == "<anything>") { foreach (var carriedItem in ItemsToWorkWith.Tokens) { var knownItem = NoxicoGame.KnownItems.Find(ki => ki.ID == carriedItem.Name); if (knownItem == null) { Program.WriteLine("Crafting: don't know what a {0} is.", carriedItem.Name); continue; } var withs = step.GetAll("with"); var withouts = step.GetAll("withouts"); var okay = 0; foreach (var with in withs) { if (knownItem.HasToken(with.Text)) { okay++; } } foreach (var without in withouts) { if (knownItem.HasToken(without.Text)) { okay = 0; } } if (okay < withs.Count()) { continue; } if (carriedItem.HasToken("charge")) { numFound += (int)carriedItem.GetToken("charge").Value; } else { numFound++; } stepRefs[i] = carriedItem; if (i == 0) { resultingSourceItem = knownItem; } } } else if (step.Text == "book") { //TODO: see if a book with the given ID is marked as read. } else { foreach (var carriedItem in ItemsToWorkWith.Tokens.Where(t => t.Name == step.Text)) { var knownItem = NoxicoGame.KnownItems.Find(ki => ki.ID == carriedItem.Name); if (knownItem == null) { Program.WriteLine("Crafting: don't know what a {0} is.", carriedItem.Name); continue; } if (carriedItem.HasToken("charge")) { numFound += (int)carriedItem.GetToken("charge").Value; } else { numFound++; } stepRefs[i] = carriedItem; if (i == 0) { resultingSourceItem = knownItem; } } } if (numFound < amount) { Program.WriteLine("Crafting: not enough {0} to craft {1}.", step.Text, resultName); break; } if (step.Name == "consume") { newRecipe.Actions.Add(new CraftConsumeItemAction() { Target = stepRefs[i] }); } } else if (step.Name == "produce") { var itemMade = new Token(step.Text); itemMade.Tokens.AddRange(step.Tokens); newRecipe.Actions.Add(new CraftProduceItemAction() { Target = itemMade }); var resultingKnownItem = NoxicoGame.KnownItems.Find(ki => ki.ID == itemMade.Name); newRecipe.Display = i18n.Format("craft_produce_x_from_y", resultingKnownItem.ToString(itemMade), resultingSourceItem.ToString(stepRefs[0])); } else if (step.Name == "train") { newRecipe.Actions.Add(new CraftTrainAction() { Trainee = carrier, Target = step }); } } if (newRecipe.Display.IsBlank()) { continue; } if (results.Exists(x => x.Display == newRecipe.Display)) { continue; } results.Add(newRecipe); } //Find dyes foreach (var maybeDye in ItemsToWorkWith.Tokens) { var knownItem = NoxicoGame.KnownItems.Find(ki => ki.ID == maybeDye.Name); if (knownItem == null) { Program.WriteLine("Crafting: don't know what a {0} is.", maybeDye.Name); continue; } if (knownItem.HasToken("dye")) { var dyeItem = maybeDye; var color = dyeItem.GetToken("color").Text; foreach (var carriedItem in ItemsToWorkWith.Tokens) { knownItem = NoxicoGame.KnownItems.Find(ki => ki.ID == carriedItem.Name); if (knownItem == null) { Program.WriteLine("Crafting: don't know what a {0} is.", carriedItem.Name); continue; } if (knownItem.HasToken("colored") && !knownItem.HasToken("dye")) { var newRecipe = new Recipe(); newRecipe.Display = i18n.Format("craft_dye_x_y", knownItem.ToString(carriedItem), color); if (!carriedItem.HasToken("color")) { newRecipe.Actions.Add(new CraftAddTokenAction() { Target = carriedItem, Add = new Token("color", 0, color) }); } else if (carriedItem.GetToken("color").Text == color) { continue; } else { newRecipe.Actions.Add(new CraftChangeTokenAction() { Target = carriedItem.GetToken("color"), NewText = color, NewValue = 0 }); } results.Add(newRecipe); } } } } return(results); }
public bool HasRelation(Character with) { return(this.Path("ships/" + with.ID) != null); }
public static void Engage(Character top, Character bottom, string name = "(start)") { if (sceneList == null) { sceneList = Mix.GetTokenTree("dialogue.tml", true); } SceneSystem.top = top; SceneSystem.bottom = bottom; SceneSystem.actors = new[] { top, bottom }; var dreaming = top.HasToken("dream"); if (name.Contains('\xE064')) { name = name.Remove(name.LastIndexOf('\xE064')); } var openings = sceneList.Where(x => x.Name == "scene" && x.GetToken("name").Text == name).ToList(); if (openings.Count == 0) { MessageBox.Notice(string.Format("Could not find a proper opening for scene name \"{0}\". Aborting.", name), true, "Uh-oh."); return; } var firstScene = openings.FirstOrDefault(i => SexManager.LimitsOkay(actors, i)); var scenes = new List <Token>() { firstScene }; if (firstScene.HasToken("random")) { var randomKey = firstScene.GetToken("random").Text; foreach (var s in openings.Where(i => i != firstScene && i.HasToken("random") && i.GetToken("random").Text == randomKey && SexManager.LimitsOkay(actors, i))) { scenes.Add(s); } } var scene = scenes.PickOne(); var message = i18n.Viewpoint(ExtractParagraphsAndScripts(scene), SceneSystem.top, SceneSystem.bottom); var actions = ExtractActions(scene); if (actions.Count == 1) { var target = actions.First().Key; actions.Clear(); actions.Add(target, "==>"); } if (bottom == NoxicoGame.Me.Player.Character && !letBottomChoose) { if (actions.Count == 0) { MessageBox.Notice(message, true, bottom.Name.ToString(true)); } else { var randomAction = actions.Keys.ToArray().PickOne(); actions.Clear(); actions.Add(randomAction, "==>"); MessageBox.List(message, actions, () => { Engage(SceneSystem.top, SceneSystem.bottom, (string)MessageBox.Answer); }, false, true, bottom.GetKnownName(true, true)); } } else { letBottomChoose = false; if (actions.Count == 0) { MessageBox.Notice(message, !dreaming, bottom.GetKnownName(true, true)); } else { MessageBox.List(message, actions, () => { Engage(SceneSystem.top, SceneSystem.bottom, (string)MessageBox.Answer); }, false, !dreaming, bottom.GetKnownName(true, true)); } } if (dreaming) { new UIPNGBackground(Mix.GetBitmap("dream.png")).Draw(); } else { NoxicoGame.Me.CurrentBoard.Redraw(); NoxicoGame.Me.CurrentBoard.Draw(); } }
public static void Engage(Character top, Character bottom) { Engage(top, bottom, "(start)"); }