예제 #1
0
        /// <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);
        }
예제 #2
0
 public bool HasRelation(Character with)
 {
     return(this.Path("ships/" + with.ID) != null);
 }
예제 #3
0
        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();
            }
        }
예제 #4
0
 public static void Engage(Character top, Character bottom)
 {
     Engage(top, bottom, "(start)");
 }