Пример #1
0
        public static IReadOnlyList <IVerb <Entity> > GenerateVerbs()
        {
            List <IVerb <Entity> > output = new List <IVerb <Entity> >()
            {
                ZeroTarget(a => new QuitGameCommand(), "quit"),
                ZeroTarget(a => new DropAllAction(a), "drop all", "put down all", "discard all"),
                ZeroTarget(a => new TakeAllAction(a), "take all", "get all", "pick up all"),
                ZeroTarget(a => new InventoryAction(a), "inventory", "i", "items"),
                ZeroTarget(a => new LookAction(a), "look", "examine", "x"),
                ZeroTarget(a => new WaitAction(a), "wait"),
                ZeroTarget(a => new CampAction(a), "camp", "make camp"),
                ZeroTarget(a => new RelaxAction(a, new Random().NextDouble()), "relax", "rest"),
                OneTargetWithTool((actor, target, weapon) => new HitAction(actor, target, weapon), "hit", "strike", "attack"),
                OneTarget((a, t) => new DropAction(a, t), "drop", "put down", "discard"),
                OneTarget((a, t) => new TakeAction(a, t), "take", "get", "pick up"),
                OneTarget((a, t) => new ConsumeAction(a, t), "consume"),
                OneTarget((a, t) => new ConsumeAction(a, t, ConsumeMode.Eat), "eat"),
                OneTarget((a, t) => new ConsumeAction(a, t, ConsumeMode.Drink), "drink"),
                OneTarget((a, t) => new HitAction(a, t), "hit", "strike", "attack"),
            };

            foreach (Direction d in DirectionExtensions.EnumerateDirections())
            {
                string name   = d.Name();
                string letter = name[0].ToString();

                var moveVerb = ZeroTarget(a => new DirectionMoveAction(a, d), name, letter, "go " + name, "go " + letter);
                output.Add(moveVerb);
            }


            return(output);
        }
        public static OutputEntry GetDescription(Entity scene, Entity viewer)
        {
            Entity you = viewer;

            InteractiveSpan resolver(object symbol)
            {
                if (symbol is Entity entity)
                {
                    if (entity.Id.Equals(viewer.Id))
                    {
                        return(new InteractiveSpan("you"));
                    }
                    return(entity.GenerateMenu(viewer));
                }
                else
                {
                    throw new Exception($"Unexpected entry {symbol}");
                }
            }

            OutputTemplate sceneDescription = new();
            Senses?        senses           = viewer.Get <Senses>();

            if (senses is null)
            {
                sceneDescription.AddFormat($"{you} cannot perceive anything.");
                return(sceneDescription.Render(resolver));
            }

            if (scene.Has(out SceneDescription? desc))
            {
                sceneDescription.AddLines(desc.Lines);
            }
            else if (scene.Has(out Name? sceneName))
            {
                sceneDescription.AddFormat($"{you} are inside {scene}.");
            }
            else
            {
                sceneDescription.AddFormat($"{you} are inside an unnamed object.");
            }

            bool displayedItem = false;

            foreach (Entity item in scene.GetMembers <Location>())
            {
                if (!displayedItem)
                {
                    sceneDescription.AddLine("Nearby objects:");
                }
                if (item.Has <Visibility>())
                {
                    sceneDescription.AddFormat($"- {item}");
                    displayedItem = true;
                }
            }
            if (!displayedItem)
            {
                sceneDescription.AddLine("There are no items here");
            }

            if (scene.Has <RoomExits>(out var roomExits))
            {
                bool printedHeader = false;
                foreach (Direction direction in DirectionExtensions.EnumerateDirections())
                {
                    if (roomExits.GetFacing(direction).HasValue)
                    {
                        if (!printedHeader)
                        {
                            sceneDescription.AddLine("Exits:");
                            printedHeader = true;
                        }
                        sceneDescription.AddLine($"- Exit facing {direction.Name()}");
                    }
                }
            }

            return(sceneDescription.Render(resolver));
        }