Beispiel #1
0
        // It appears that in c# you can only write a copy constructor like this.
        public AObject(AObject prototype)
        {
            if (prototype == null)
            {
                throw new ArgumentNullException(nameof(prototype));
            }
            Name             = prototype.Name;
            Alias            = prototype.Alias;
            IsTakable        = prototype.IsTakable;
            Information      = prototype.Information;
            Description      = prototype.Description;
            LightDescription = prototype.LightDescription;
            SubObjects       = prototype.SubObjects;
            Parent           = prototype.Parent;

            IsOpenable  = prototype.IsOpenable;
            OpenState   = prototype.OpenState;
            IsSwitch    = prototype.IsSwitch;
            SwitchState = prototype.SwitchState;
            IsClothing  = prototype.IsClothing;

            //OnPuttingOn = obj.OnPuttingOn;
            OnExaminaion    = prototype.OnExaminaion;
            OnOpening       = prototype.OnOpening;
            OnClosing       = prototype.OnClosing;
            OnTurningOn     = prototype.OnTurningOn;
            OnTurningOff    = prototype.OnTurningOff;
            OnBeingSmelled  = prototype.OnBeingSmelled;
            OnBeingTouched  = prototype.OnBeingTouched;
            OnBeingListened = prototype.OnBeingListened;
        }
Beispiel #2
0
        // DOUBLE OBJECT VERBS

        private void PutIn(string a, string b)
        {
            AObject oa = FindSensoryObject(a);
            AObject ob = FindSensoryObject(b);

            if (oa == null || ob == null)
            {
                return;
            }
            if (!ob.IsContainer)
            {
                Print("你没法把东西放到那里面。\n\n");
                return;
            }
            if (oa == ob)
            {
                Print("把一样东西放进自身的想法听上去很荒谬;仿佛在向自己炫耀学识一般,你思考:利用一些拓扑学的把戏,这种行为在四维空间中也许很容易做到……或者,你可以把它弄成一个克莱因瓶……算了。\n\n");
                return;
            }
            // if the object is untakable, it'll pass here but complain when you take it
            if (ob.Capacity - ob.SubObjectsSize < oa.Size)
            {
                Print($"看上去装不下:{(ob.Capacity < oa.Size ? $"对于{ob.Name}来说,{oa.Name}实在太大了。" : $"{ob.Name}里面已经装了太多东西。")}\n\n");
                return;
            }
Beispiel #3
0
 private static void SetupArea(ref Area a, string name, string desc,
                               AObject[] usable, AObject[] notClear, Dictionary <Direction, Area> godir,
                               string ldesc = "", AObject defDoor = null)
 {
     a.Name = name;
     if (string.IsNullOrEmpty(ldesc))
     {
         a.OverrideDescription = (s, v) => desc;
     }
     else
     {
         a.OverrideDescription = (s, v) => v.IsLight() ? ldesc : desc;
     }
     a.AreaTo.Clear();
     foreach (var p in godir)
     {
         a.AreaTo.Add(p.Key, p.Value);
     }
     a.DefaultDoor  = defDoor;
     a.FilterObject = (x) =>
     {
         if (notClear.Contains(x))
         {
             return(ObjectVisibility.Unclear);
         }
         if (usable.Contains(x))
         {
             return(ObjectVisibility.Visible);
         }
         return(ObjectVisibility.NotVisible);
     };
 }
Beispiel #4
0
 private void TurnOffThing(AObject obj)
 {
     if (!obj.IsSwitch)
     {
         Print("这不是一个能够开关的东西。\n\n");
         return;
     }
     if (!obj.SwitchState)
     {
         Print("它已经是关着的了。\n\n");
     }
     else
     {
         HandleResult res = CRoom.BeforeTurningOff(CRoom, Variables, obj);
         if (res == HandleResult.Continue)
         {
             res = obj.OnTurningOff(obj, Variables);
             if (res == HandleResult.Continue)
             {
                 obj.SwitchState = false;
                 Print("你关闭了它。\n\n");
             }
         }
         CRoom.PostTurningOff(CRoom, Variables, obj);
     }
 }
Beispiel #5
0
        private bool Enter(AObject obj)
        {
            if (!obj.IsEnterable)
            {
                Print("你没法进入那里。\n\n");
                return(false);
            }
            if (obj.IsOpenable && !obj.OpenState)
            {
                // In case the player automatically attempts to open it but failed
                Print("你进不去,门还没有打开。\n\n");
                return(false);
            }
            HandleResult res = obj.OnEntering(obj, Variables);

            if (res == HandleResult.Continue)
            {
                Print($"你走进{obj.Name}。\n\n");

                if (CRoom.IsPlayerLit)
                {
                    // bring player's torch into the next room
                    CRoom.IsPlayerLit      = false;
                    obj.RoomTo.IsPlayerLit = true;
                }

                Variables.currentRoom = obj.RoomTo;
                if (CRoom.IsWarm)
                {
                    Variables.temperature = 0;
                }
                DescribeRoom();
            }
            return(true);
        }
Beispiel #6
0
 private static void BuildObjList(AObject o)
 {
     Objects.Add(o);
     foreach (AObject oo in o.SubObjects)
     {
         BuildObjList(oo);
     }
 }
Beispiel #7
0
        static void BuildDormsHallway()
        {
            DormsHallway.Name = "寝室楼二楼走廊";
            DormsHallway.Alias.Clear();
            DormsHallway.Alias.AddRange(new[] { "走廊", "门廊" });

            DormsHallway.Description =
                "“安全出口”的标志在这里发出荧荧的绿光。走廊延伸到远处,两边尽头都是墙壁。北侧有上下楼梯,南侧相应位置是储藏室。此外就是寝室了。从9#到13#是你们班的,而其中12#就是你所在的那间。";
            DormsHallway.LightDescription =
                "在手电筒开辟出的坚硬光柱之外,幽暗的墙壁和瓷砖里映出一点点绿色光芒。走廊延伸到远处,两边尽头都是墙壁。北侧有上下楼梯,南侧相应位置是储藏室。此外就是寝室了。从9#到13#是你们班的,而其中12#就是你所在的那间。";

            AObject Sign = new AObject(
                "标志", new[] { "安全出口", "绿光", "标牌" },
                desc: "很远就能看得清楚,主要是因为它一如往常,没什么特别:“安全出口”,一个指向楼梯的发光箭头,还有一个逃跑人形的发光标识。",
                // You may see that the escaping humanoid symbol disappears in the dark. This is only an ominous easter egg, for clarification.
                ldesc: "绿光就是从这个标志上发出来。你现在用手电筒指向它,它的光就收敛起来了。标志上有“安全出口”几个字加上一个指向楼梯的箭头。");

            DormsHallway.Objects.Clear();
            DormsHallway.Objects.Add(Sign);

            DormsHallway.Objects.Add(new AObject("墙壁",
                                                 new[] { "墙壁", "墙", "地面", "地板", "地", "楼梯", "门" }));

            // Now we build all the 20 doors
            for (int i = 1; i <= 20; i++)
            {
                if (i == 12)
                {
                    AObject d12 = AObject.SimpleDoor(Dormitory12,
                                                     "12#寝室的门", new[] { "12#寝室门", "12#门", "门" },
                                                     "去" + i + "#寝室的门。",
                                                     flopside: () => Dormitory12.FindObjectInternal("去走廊的门"));
                    DormsHallway.Objects.Add(d12);
                }
                else
                {
                    AObject d = AObject.SimpleDoor(null, i + "#寝室的门",
                                                   new[] { i + "#寝室门", i + "#门", i + "#寝室", i + "#", "门" },

                                                   "去" + i + "#寝室的门。", locked: true);
                    d.OnOpening = (self, v) =>
                    {
                        if (!v.foundDoorsLocked)
                        {
                            Print("你拧了拧门把手。根本转不动,就像整个是一块实心金属一样;这些寝室肯定是因为某些原因被锁住了。\n\n");
                            v.foundDoorsLocked = true;
                            return(HandleResult.Refused);
                        }
                        return(HandleResult.Continue);
                    };
                    DormsHallway.Objects.Add(d);
                }
            }

            DormsHallway.RoomTo.Clear();
            DormsHallway.RoomTo.Add(Direction.Down, LobbyNo8);
        }
Beispiel #8
0
 private void FindSubObjectIn(AObject obj, string name, List <AObject> matches)
 {
     if (obj.IsOpenable && !obj.OpenState)
     {
         return;
     }
     foreach (var subObj in obj.SubObjects)
     {
         if (subObj.Name == name || subObj.Alias.Contains(name))
         {
             matches.Add(subObj);
         }
         FindSubObjectIn(subObj, name, matches);
     }
 }
Beispiel #9
0
        private void OpenThing(AObject obj)
        {
            if (!obj.IsOpenable)
            {
                Print("这不是一个能够开关的东西。\n\n");
                return;
            }
            if (obj.OpenState)
            {
                Print("它已经是开着的了。\n\n");
                return;
            }

            HandleResult res = CRoom.BeforeOpening(CRoom, Variables, obj);

            if (res == HandleResult.Continue)
            {
                if (obj.IsLocked)
                {
                    Print("它紧紧锁着。\n\n");
                    return;
                }
                res = obj.OnOpening(obj, Variables);
                if (res == HandleResult.Continue)
                {
                    obj.OpenState = true;
                    AObject flop = obj.LinkedSide();
                    if (flop != null)
                    {
                        flop.OpenState = obj.OpenState;
                    }
                    Print("你打开了它。\n\n");
                }
                else if (res == HandleResult.Refused)
                {
                    return;
                }
            }
            else if (res == HandleResult.Refused)
            {
                return;
            }
            CRoom.PostOpening(CRoom, Variables, obj);
        }
Beispiel #10
0
        private AObject FindSensoryObject(string p)
        {
            AObject iobj = Variables.InventoryGet(p);

            if (iobj == null)
            {
                iobj = CRoom.FindObject(p, Variables);
            }
            if (iobj == null)
            {
                Print($"我不知道{p}是什么,请尝试不同的表达方法。\n\n");
                return(null);
            }
            if (!iobj.IsReachable)
            {
                Print($"你够不到{iobj.Name}。真是可惜。\n\n");
                return(null);
            }
            return(iobj);
        }
Beispiel #11
0
        private void CloseThing(AObject obj)
        {
            if (!obj.IsOpenable)
            {
                Print("这不是一个能够开关的东西。\n\n");
                return;
            }
            if (!obj.OpenState)
            {
                Print("它已经是关着的了。\n\n");
                return;
            }

            HandleResult res = CRoom.BeforeClosing(CRoom, Variables, obj);

            if (res == HandleResult.Continue)
            {
                res = obj.OnClosing(obj, Variables);
                if (res == HandleResult.Continue)
                {
                    obj.OpenState = false;
                    AObject flop = obj.LinkedSide();
                    if (flop != null)
                    {
                        flop.OpenState = obj.OpenState;
                    }
                    Print("你关上了它。\n\n");
                }
                else if (res == HandleResult.Refused)
                {
                    return;
                }
            }
            else if (res == HandleResult.Refused)
            {
                return;
            }
            CRoom.PostClosing(CRoom, Variables, obj);
        }
Beispiel #12
0
        private void DescribeObject(AObject what)
        {
            HandleResult res = CRoom.BeforeExaminaion(CRoom, Variables, what);

            if (res == HandleResult.Continue)
            {
                res = what.OnExaminaion(what, Variables);
                if (res == HandleResult.Continue)
                {
                    if (what.IsNondescript)
                    {
                        Print(AObject.DefaultDescription + "\n\n");
                    }
                    else if (CRoom.IsLit || CRoom.IsPlayerLit)
                    {
                        Print(what.LightDescription(what, Variables) + "\n\n");
                    }
                    else
                    {
                        Print(what.Description(what, Variables) + "\n\n");
                    }
                }
            }

            res = CRoom.PostExamination(CRoom, Variables, what);

            // go on to provide information for all subobjects
            var shortInfoObjs = what.SubObjects
                                .Where(x => x.ShortInfo != null &&
                                       (CArea == null || CArea.FilterObject(x) == ObjectVisibility.Visible))
                                .Select(x => x.FullShortInfo(x, Variables));

            if (shortInfoObjs.Any())
            {
                Print($"这里放着{string.Join("、", shortInfoObjs)}。\n\n");
            }
        }
Beispiel #13
0
        static void BuildDormitory12()
        {
            Dormitory12.Name = "你的寝室";
            Dormitory12.Alias.Clear();
            Dormitory12.Alias.AddRange(new[] { "寝室", "12#寝室", "12#" });

            Dormitory12.LightDescription =
                "这是你熟悉的寝室,闭上眼都能想象出它的样子。你能看见衣柜,桌子,床铺(四张:你睡在靠窗的下铺)以及通向走廊和洗手间过道的两扇门。";
            Dormitory12.Description =
                "你只能在黑暗中看见大概的轮廓:衣柜,桌子,床铺(四张:你睡在靠窗的下铺),以及通向走廊和洗手间过道的两扇门。\n\n现在仅有的照明是从窗帘后透出的一点微光。";
            Dormitory12.IsLit = false;

            // FIXME: do better than this
            AObject Clothes = new AObject(
                "衣服", new[] { "衣物", "服装" },
                desc:   "杂乱堆着的衣服;在顶上有几件外套和外裤。",
                ldesc:  "杂乱堆着的衣服;在顶上有几件外套和外裤。",
                info:   "打开的衣柜里能看见你杂乱堆放着的衣服。");

            AObject Closet = new AObject(
                "衣柜", new[] { "柜子", "橱柜", "柜门" },
                desc:   "普通的寝室衣柜,没有上锁。")
            {
                IsOpenable = true,
                OnOpening  = (self, v) =>
                {
                    self.OpenState = true;
                    v.currentRoom.Objects.Add(Clothes);
                    Print("你打开衣柜,里面杂乱地堆放着你的衣服。\n\n");
                    return(HandleResult.FullManaged);
                },
                OnClosing = (self, v) =>
                {
                    v.currentRoom.Objects.Remove(Clothes);
                    return(HandleResult.Continue);
                }
            };

            AObject Bottle = new AObject(
                "水杯", new[] { "水瓶", "杯子", "瓶子", "保温杯" },
                desc:   "它的金属表面握起来凉凉的。",
                ldesc:  "它银色的金属表面光滑发亮。",
                sinfo:  "一个水杯")
            {
                IsTakable = true, Size = 2f
            };

            AObject Flashlight = new AObject(
                "手电筒", new[] { "手电", "电筒" },
                desc:   "简单的手电筒,然而设计得十分周到,在黑暗中还会发出一小圈荧光。",
                ldesc:  "一个闪亮的银色金属手电筒。这花了你不少钱,但是挺漂亮,照明范围也大。",
                sinfo:  "一个小手电筒")
            {
                IsTakable   = true, IsSwitch = true, Size = 0.5f,
                OnTurningOn = (self, v) =>
                {
                    if (!v.inventory.Contains(self))
                    {
                        Print("你先得拿到它。\n\n");
                        return(HandleResult.Refused);
                    }
                    else if (!v.flashlightOK)
                    {
                        v.flashlightOK = true; self.SwitchState = true;
                        Print("咔哒。没有反应。难道是接触不良?\n\n");
                    }
                    else
                    {
                        self.SwitchState          = true;
                        v.currentRoom.IsPlayerLit = true;
                        if (!v.firstLight)
                        {
                            Print("咔哒。这次灯亮了,猛烈的白光使你一时间难以睁眼。不过令你欣慰的是你竟然没有惊动别人。一切看起来都在原位。\n\n");
                        }
                        else
                        {
                            Print("咔哒。灯亮了。\n\n");
                        }
                        v.firstLight = true;
                    }
                    return(HandleResult.FullManaged);
                },
                OnTurningOff = (self, v) =>
                {
                    if (!v.inventory.Contains(self))
                    {
                        Print("你先得拿到它。\n\n");
                        return(HandleResult.Refused);
                    }
                    else
                    {
                        self.SwitchState = false;
                        if (v.flashlightOK)
                        {
                            v.currentRoom.IsPlayerLit = false;
                        }
                        Print("咔哒。\n\n");
                        return(HandleResult.FullManaged);
                    }
                }
            };

            AObject ACControl = new AObject(
                "空调遥控器", new[] { "遥控器" },
                desc:   "一团方块形状的空调遥控器,按键在黑暗中微弱地发光。",
                ldesc:  "方块形状的白色空调遥控器,侧面带着红色条纹。",
                sinfo:  "一个空调遥控器")
            {
                IsTakable = true, Size = 0.3f
            };

            AObject Desk = new AObject(
                "桌子", new[] { "课桌", "桌椅" },
                desc:   "看上去漆黑一片,但是你知道自己的位置上有盏台灯,上面的格子里堆放着杂物。",
                ldesc:  "普通的桌子,从寝室一边的衣柜延伸到洗手间过道的门边。上面的格子里堆放着杂物。")
            {
                IsContainer = true, Capacity = 100
            };

            Desk.SubObjects.AddRange(new[] { Bottle, Flashlight, ACControl });

            AObject Lamp = new AObject(
                "台灯", new[] { "灯" },
                desc:   "虽然看不清楚,但是你至少知道开关在哪里。",
                ldesc:  "廉价的白色塑料台灯。如果能开,应该会挺亮的。")
            {
                IsSwitch    = true,
                OnTurningOn = (self, v) =>
                {
                    if (!v.foundLampUnlit)
                    {
                        Print("咔哒。没有反应。你突然明白过来,这个时候寝室里没有电源。于是你又把它关了。\n\n");
                        v.foundLampUnlit = true;
                    }
                    else
                    {
                        Print("咔哒。没有反应。\n\n");
                    }
                    return(HandleResult.Refused);
                },
                OnTaking = (self, v) =>
                {
                    Print("那东西的电线一直连到桌下,很不方便移动。\n\n");
                    return(HandleResult.Refused);
                }
            };

            AObject Beds = new AObject(
                "床铺", new[] { "床", "床位", "被子" },
                desc:   "看上去只是漆黑一片。",
                ldesc:  "床铺里面全都空无一人,被子随意铺开,就好像睡觉的人凭空消失了一样。床架、栏杆都非常完整,没有其他的痕迹。")
            {
                IsContainer  = true, Capacity = 300,
                OnExaminaion = (self, v) =>
                {
                    if (!v.foundNobody && (v.currentRoom.IsPlayerLit || v.currentRoom.IsLit))
                    {
                        string x = v.currentRoom.IsPlayerLit ? "手电筒的光束" : "视线";
                        Print(
                            "也许只是想确认一下,你打算看一眼床铺。当" + x + "聚焦在同学的床上时,有什么东西吓得你倒退了一步。最开始你不敢相信这是真的,但是无论怎么眨眼你看到的都是同一幅景象。\n\n");
                        v.foundNobody = true;
                    }
                    return(HandleResult.Continue);
                }
            };

            AObject AirConditioner = new AObject(
                "空调", new string[0],
                desc:   "空调制热模式低沉的呼吸声中,两个绿点随着在黑暗的高处闪光。",                 // can change
                ldesc:  "普通而标准的寝室空调,发出制热模式低沉的呼吸声。两个绿点微弱地在面板上亮着。")
            {
                IsSwitch    = true, SwitchState = true,
                IsReachable = false,
                OnTurningOn = (self, v) =>
                {
                    if (!v.inventory.Contains(ACControl))
                    {
                        Print("你没有拿遥控器。\n\n");
                        return(HandleResult.Refused);
                    }
                    self.Description = (_s, _v) =>
                                       "空调制热模式低沉的呼吸声中,两个绿点随着在黑暗的高处闪光。";
                    self.LightDescription = (_s, _v) =>
                                            "普通而标准的寝室空调,发出制热模式低沉的呼吸声。两个绿点微弱地在面板上亮着。";
                    Print("滴。导流板转动的僵硬声音。\n\n");
                    self.SwitchState = true;
                    return(HandleResult.FullManaged);
                },
                OnTurningOff = (self, v) =>
                {
                    if (!v.inventory.Contains(ACControl))
                    {
                        Print("你没有拿遥控器。\n\n");
                        return(HandleResult.Refused);
                    }
                    self.Description = (_s, _v) =>
                                       "看上去只是漆黑一片。";
                    self.LightDescription = (_s, _v) =>
                                            "普通而标准的寝室空调,毫无活力。";
                    Print("滴。导流板转动的僵硬声音。\n\n");
                    self.SwitchState = false;
                    return(HandleResult.FullManaged);
                }
            };

            AObject Window = new AObject(
                "窗户", new[] { "窗", "玻璃", "窗外", "天空", "外面" },
                desc:   "窗户被窗帘遮挡着,透出微弱的一点光。",
                ldesc:  "窗帘没有拉开,你看不见外面的样子。");

            AObject Darkness = new AObject(
                "黑暗", new[] { "窗外", "外面" },
                desc:   "在黑暗中看着黑暗是一种怪异的体验。事实上它并不全是黑暗:它其实在发光,室内窗帘后的微光便是它发出的。看着它使你感到头晕。",
                ldesc:  "不像是雾,手电筒照不穿它。你只能形容它为“黑暗”:事实上它在发光,室内窗帘后的微光便是它发出的。但你看着它的时候你完全确定它就是一片黑暗,深不可测,使你头晕。");

            AObject Curtain = new AObject(
                "窗帘", new[] { "帘子" },
                desc:   "从窗帘后面什么地方透出微弱的一点光来。",
                ldesc:  "浅黄的窗帘在灯光下显得苍白,遮蔽了窗外的一点点亮光。")                 // WILL CHANGE
            {
                IsOpenable = true, OpenState = false,
                OnOpening  = (self, v) =>
                {
                    self.OpenState        = true;
                    self.Description      = (_s, _v) => "窗帘被你拉开缩在一边,外面是一片黑暗。";
                    self.LightDescription = self.Description;
                    v.currentRoom.Objects.Remove(Window);
                    v.currentRoom.Objects.Add(Darkness);

                    if (!v.foundDarkness1)
                    {
                        Print(
                            "你拉开了窗帘。令你惊奇的是,后面根本就没有什么路灯在发光。事实上后面什么也没有:只是一片黑暗。\n\n");
                        v.foundDarkness1 = true;
                    }
                    else
                    {
                        Print(
                            "你拉开窗帘。窗帘外是一片黑暗。\n\n");
                    }
                    return(HandleResult.FullManaged);
                },
                OnClosing = (self, v) =>
                {
                    self.OpenState        = false;
                    self.Description      = (_s, _v) => "从窗帘后面什么地方透出微弱的一点光来。";
                    self.LightDescription = (_s, _v) => "浅黄的窗帘在灯光下显得苍白,遮蔽了窗外的一点点亮光。";
                    v.currentRoom.Objects.Remove(Darkness);
                    v.currentRoom.Objects.Add(Window);

                    Print("你拉上窗帘。\n\n");
                    return(HandleResult.FullManaged);
                }
            };

            Flashlight.Parent = Desk;
            Bottle.Parent     = Desk;
            ACControl.Parent  = Desk;

            AObject RestroomDoor = AObject.SimpleDoor(
                Restroom, "去洗手间过道的门",
                new[] { "厕所门", "洗手间门", "厕所", "洗手间", "门" },
                desc:   "通往洗手间过道的门。",
                flopside: () => Restroom.FindObjectInternal("去寝室的门"));

            AObject HallwayDoor = AObject.SimpleDoor(
                DormsHallway, "去走廊的门",
                new[] { "走廊门", "走廊", "门" },
                desc:   "通往寝室楼走廊的门。",
                flopside: () => DormsHallway.FindObjectInternal("12#寝室的门"));

            Dormitory12.Objects.Clear();
            Dormitory12.Objects.AddRange(new[] {
                Closet, Desk, Lamp, Beds, Window, Curtain, AirConditioner, RestroomDoor, HallwayDoor
            });
            Dormitory12.DefaultDoor = HallwayDoor;

            Dormitory12.Objects.Add(new AObject("椅子", new[]
                                                { "物品", "杂物", "枕头", "床单", "被子", "天花板", "东西", "床架", "栏杆",
                                                  "墙壁", "墙", "地面", "地板", "地" }));

            Area BedArea = new Area("床上")
            {
                OverrideDescription = (self, v) =>
                                      "躺在床上时,所有你能清楚看见的东西就是头顶的金属床板和一点栏杆。",
                FilterObject = (x) => ObjectVisibility.NotVisible
            };

            Dormitory12.Areas.Clear();
            Dormitory12.Areas.Add(BedArea);
            Dormitory12.CurrentArea = BedArea;

            Dormitory12.BeforeCommand = (self, v, p) =>
            {
                if (p == "起床" || p == "起来")
                {
                    if (self.CurrentArea == BedArea)
                    {
                        Print("你推开被子,试图让外部的空气刺激自己,但并没有什么用。最后你还是挣扎着坐了起来,摸索着穿上最近的一双拖鞋。在这个时候起来能干什么呢?还是走一圈再继续睡觉吧。\n\n");
                        self.CurrentArea = null;
                    }
                    else
                    {
                        Print("你并不在床上。\n\n");
                    }
                    self.PostCommand(self, v, p);
                    return(HandleResult.FullManaged);
                }
                else if (p == "睡" || p == "睡觉")
                {
                    Print($"{(self.CurrentArea == BedArea ? "" : "又一次走到床边躺下来之后,")}你被一种疲倦轻易地抓住了。你很快发现这很难逃脱——确切地说,你也不想要逃脱。闭上眼睛:这是多么美妙的动作,多么美好的感受啊!的确,你困了。你好像看见彩色的形状和线条在旋转,然后就睡着了。你没有再做梦。\n\n");
                    v.dreamStop  = true;
                    v.stopReason = "sleep";
                    self.PostCommand(self, v, p);
                    return(HandleResult.FullManaged);
                }
                else
                {
                    return(HandleResult.Continue);
                }
            };

            int acCounter = -1;

            Dormitory12.PostCommand = (self, v, p) =>
            {
                acCounter++;
                if (!AirConditioner.SwitchState)
                {
                    return(HandleResult.Continue);
                }
                switch (acCounter % 5)
                {
                case 0: Print(
                        "空调发出低沉的呼吸声,吐出温热的空气。\n\n"); break;

                case 1: Print(
                        "空调继续呼吸,声音变得更加急促。\n\n"); break;

                case 2: Print(
                        "空调平稳地呼吸。\n\n"); break;

                case 3: Print(
                        "空调仿佛打了个嗝,传来导流板转动的僵硬声音。咯吱。\n\n"); break;

                case 4: Print(
                        "空调的热气晃动着吹来。\n\n"); break;
                }
                return(HandleResult.Continue);
            };
        }
Beispiel #14
0
 public void ReplaceObjectInternal(string s, AObject newObj)
 => Objects[Objects.FindIndex((x) => x.Name == s)] = newObj;
Beispiel #15
0
        static void BuildBuilding1()
        {
            // first floor
            {
                Building1F1.Name = "行政楼[1#]一楼";
                Building1F1.Alias.Clear();
                Building1F1.IsLit = false;

                Area NLobby = new Area();
                Area SLobby = new Area();
                //Area Library = new Area();
                //Area Study = new Area();
                Building1F1.Areas.Clear();
                Building1F1.Areas.AddRange(new[]
                                           { NLobby, SLobby, /*Library, Study, CStairs*/ });
                Building1F1.Objects.Clear();

                AObject doorNLobby = AObject.SimpleDoor(
                    dest:           Campus,
                    name:           "北侧大门",
                    alias:          new[] { "外面", "大门", "门" },
                    desc:           "一扇开阔的玻璃门外,教学楼间的广场被暗紫色的天空微弱地照亮。",
                    flopside:       () => Campus.FindObjectInternal("行政楼的正门"));
                doorNLobby.OnEntering = (s, v) =>
                {
                    Campus.ChangeArea("教学楼间的小广场");
                    return(HandleResult.Continue);
                };
                Building1F1.Objects.Add(doorNLobby);
                SetupArea(ref NLobby, "大厅北侧",
                          desc: "你站在一个空旷、昏暗的大厅中,北侧开阔的玻璃门外教学楼间的广场被暗紫色的天空微弱地照亮。两边通往大厅南侧的过道之间,是往上延伸的宽敞大理石楼梯。",
                          ldesc: "空旷的大厅,在手电筒的光束下甚至显得更加空旷,你站在中间。北侧开阔的玻璃门外教学楼间的广场被暗紫色的天空微弱地照亮。两边通往大厅南侧的过道之间,是往上延伸的宽敞大理石台阶。",
                          usable: new[] { doorNLobby },
                          notClear: new AObject[0],
                          godir: new Dictionary <Direction, Area>
                {
                    { Direction.S, SLobby }
                },
                          defDoor: doorNLobby);
                NLobby.RoomTo.Add(Direction.Up, Building1F2);
                NLobby.OnGoDirection = (self, v, d) =>
                {
                    Building1F2.ChangeArea("中央楼梯");
                    return(HandleResult.Continue);
                };

                AObject doorSLobby = AObject.SimpleDoor(
                    dest:           Campus,
                    name:           "南侧大门",
                    alias:          new[] { "外面", "大门", "门" },
                    desc:           "一扇开阔的玻璃门外,道路后面是寝室楼和树木的阴暗影子。",
                    flopside:       () => Campus.FindObjectInternal("行政楼的南门"));
                doorSLobby.OnEntering = (s, v) =>
                {
                    Campus.ChangeArea("道路");
                    return(HandleResult.Continue);
                };
                Building1F1.Objects.Add(doorSLobby);
                SetupArea(ref SLobby, "大厅南侧",
                          desc: "你站在一个昏暗的大厅中,南侧开阔的玻璃门外,道路后面是寝室楼和树木的阴暗影子。两边通往大厅北侧的过道之间是一面有浮雕的墙。",
                          ldesc: "大厅在手电筒的光束下显得既狭小又空旷;你站在中间。南侧开阔的玻璃门外,道路后面是寝室楼和树木的阴暗影子。两边通往大厅北侧的过道之间是一面有浮雕的墙。",
                          usable: new[] { doorSLobby },
                          notClear: new AObject[0],
                          godir: new Dictionary <Direction, Area>
                {
                    { Direction.N, NLobby }
                },
                          defDoor: doorSLobby);
            }

            // second floor
            {
                Building1F2.Name = "行政楼[1#]二楼";
                Building1F2.Alias.Clear();
                Building1F2.IsLit = false;

                Area CStairs = new Area();
                //Area SLobby = new Area();

                Building1F2.Areas.Clear();
                Building1F2.Areas.AddRange(new[]
                                           { CStairs });
                Building1F2.Objects.Clear();

                SetupArea(ref CStairs, "中央楼梯",
                          desc: "你站在宽阔的大理石楼梯平台上;楼梯向上通往三楼,向下通往一楼。向南北方向绕过楼梯,是两边的过道;东西两面(西边是一块自习区域,东边堆着些活动用品)的空间被各层过道包围着向上通达楼顶。",
                          usable: new AObject[] { },
                          notClear: new AObject[0],
                          godir: new Dictionary <Direction, Area>
                {
                });
                CStairs.RoomTo.Add(Direction.Down, Building1F1);
                CStairs.RoomTo.Add(Direction.Up, Building1F3);
                CStairs.OnGoDirection = (self, v, d) =>
                {
                    Building1F1.ChangeArea("大厅北侧");
                    Building1F3.ChangeArea("中央楼梯");
                    return(HandleResult.Continue);
                };
            }

            // third floor
            {
                Building1F3.Name = "行政楼[1#]三楼";
                Building1F3.Alias.Clear();
                Building1F3.IsLit = false;

                Area CStairs = new Area();
                Building1F3.Areas.Clear();
                Building1F3.Areas.AddRange(new[]
                                           { CStairs });
                Building1F3.Objects.Clear();

                SetupArea(ref CStairs, "中央楼梯",
                          desc: "你站在宽阔的大理石楼梯平台上;楼梯向上通往四楼,向下通往二楼。向南北方向绕过楼梯,是两边的过道。",
                          usable: new AObject[] { },
                          notClear: new AObject[0],
                          godir: new Dictionary <Direction, Area>
                {
                });
                CStairs.RoomTo.Add(Direction.Down, Building1F2);
                CStairs.RoomTo.Add(Direction.Up, Building1F4);
                CStairs.OnGoDirection = (self, v, d) =>
                {
                    Building1F2.ChangeArea("中央楼梯");
                    Building1F4.ChangeArea("中央楼梯");
                    return(HandleResult.Continue);
                };
            }

            // fourth floor
            {
                Building1F4.Name = "行政楼[1#]四楼";
                Building1F4.Alias.Clear();
                Building1F4.IsLit = false;

                Area CStairs = new Area();
                Building1F4.Areas.Clear();
                Building1F4.Areas.AddRange(new[]
                                           { CStairs });
                Building1F4.Objects.Clear();

                SetupArea(ref CStairs, "中央楼梯",
                          desc: "你站在宽阔的大理石楼梯平台上;楼梯向上通往五楼,向下通往三楼。向南北方向绕过楼梯,是两边的过道。",
                          usable: new AObject[] { },
                          notClear: new AObject[0],
                          godir: new Dictionary <Direction, Area>
                {
                });
                CStairs.RoomTo.Add(Direction.Down, Building1F3);
                CStairs.RoomTo.Add(Direction.Up, Building1F5);
                CStairs.OnGoDirection = (self, v, d) =>
                {
                    Building1F3.ChangeArea("中央楼梯");
                    Building1F5.ChangeArea("中央楼梯");
                    return(HandleResult.Continue);
                };
            }

            // fifth floor
            {
                Building1F5.Name = "行政楼[1#]五楼";
                Building1F5.Alias.Clear();
                Building1F5.IsLit = false;

                Area CStairs = new Area();
                Building1F5.Areas.Clear();
                Building1F5.Areas.AddRange(new[]
                                           { CStairs });
                Building1F5.Objects.Clear();

                SetupArea(ref CStairs, "中央楼梯",
                          desc: "你站在宽阔的大理石楼梯平台上;楼梯向下通往四楼。向南北方向绕过楼梯,是两边的过道。",
                          usable: new AObject[] { },
                          notClear: new AObject[0],
                          godir: new Dictionary <Direction, Area>
                {
                });
                CStairs.RoomTo.Add(Direction.Down, Building1F4);
                CStairs.OnGoDirection = (self, v, d) =>
                {
                    Building1F4.ChangeArea("中央楼梯");
                    return(HandleResult.Continue);
                };
            }

            // sixth floor: to be added (only approachable from the side stairs)
        }
Beispiel #16
0
        static void BuildRestroom()
        {
            Restroom.Name = "洗手间和过道";
            Restroom.Alias.Clear();
            Restroom.Alias.AddRange(new[] { "洗手间", "过道" });

            Restroom.LightDescription =
                "手电筒在镜子里映出一片光芒,几乎掩盖了你的模样。下面的黑色台面上有两个洗手池。镜子的墙后有两个蹲厕和一个淋浴间,没有门,所以夜里上厕所会很方便。在洗手池对面,你能透过移门看见阳台一角。";
            Restroom.Description =
                "你的形象模模糊糊地映在黑暗的镜子里。洗手池和墙的后面是蹲厕和淋浴间。那里没有门,夜里可以方便地过去:就像现在。洗手池对面有一个移门,通往阳台。";
            Restroom.IsLit = false;

            AObject Mirror = new AObject(
                "镜子", new[] { "镜面", "镜" },
                desc:           "黑暗的镜子里面模模糊糊的映出你的样子和移门后的阳台,但是看不清楚。",
                ldesc:          "手电筒在镜子里映出一片光芒,几乎掩盖了你的模样,看不清什么东西。");

            AObject Sink = new AObject(
                "洗手池", new[] { "洗手台", "台面", "池", "池子" },
                desc:           "黑色台面上两个白色洗手池,看起来就像两只空洞的眼睛。",
                ldesc:          "黑色台面上的两个洗手池,在晚上使你想到白色的大眼睛,特别是在手电筒的光照下。");

            AObject WaterTap = new AObject(
                "水龙头", new[] { "龙头" },
                desc:           "两个金属水龙头。",
                ldesc:          "两个闪亮的金属水龙头。")
            {
                IsSwitch = true, SwitchState = false
            };
            // it doesn't emit water for now, but in later stages of development I think I'll add support for it when I implement the chemistry module.

            AObject Toilet = new AObject(
                "蹲厕", new[] { "厕所", "便池" },
                desc:           "你现在并不想上厕所,也不想无缘无故地走进去看。又不是什么好玩的东西。",
                ldesc:          "你现在并不想上厕所,也不想无缘无故地走进去看。又不是什么好玩的东西。");

            AObject Bathroom = new AObject(
                "淋浴间", new[] { "浴室", "洗澡间" },
                desc:           "半夜里你不想踩进那又暗又滑的地方,更不可能洗澡。",
                ldesc:          "半夜里你不想踩进那湿湿滑滑的地方,更不可能洗澡。");

            AObject DormDoor = AObject.SimpleDoor(
                Dormitory12, "去寝室的门", new[] { "寝室门", "寝室", "门" },
                desc:           "通往寝室的门。",
                flopside:       () => Dormitory12.FindObjectInternal("去洗手间过道的门"));

            AObject BalconyDoor = AObject.SimpleDoor(
                Balcony, "去阳台的移门", new[] { "阳台门", "阳台", "移门", "门" },
                desc:           "通往阳台的移门。",
                flopside:       () => Balcony.FindObjectInternal("去洗手间过道的门"));

            Restroom.Objects.Clear();
            Restroom.Objects.AddRange(new AObject[]
                                      { Mirror, Sink, WaterTap, Toilet, Bathroom, DormDoor, BalconyDoor });

            Restroom.Objects.Add(new AObject("墙壁", new string[]
                                             { "墙壁", "墙", "地面", "地板", "地", "天花板" }));

            Restroom.PostCommand = (self, v, p) =>
            {
                if (self.FindObjectInternal("水龙头").SwitchState)
                {
                    Print("你身边传来水龙头的哗哗声。\n\n");
                }
                return(HandleResult.Continue);
            };
        }
Beispiel #17
0
        static void BuildCampus()
        {
            Campus.Name = "学校";
            Campus.Alias.Clear();
            Campus.IsLit  = true;
            Campus.IsWarm = false;

            // No global descriptors. they are placed in the areas
            Campus.GetDescription = (self, v) => "Should not see this\n\n";

            // Buildings

            AObject Building1 = new AObject(
                "1#楼", new[] { "行政楼", "1#", "大楼", "楼房" },
                desc:           "1#楼:高大、方形的学校行政楼。六层楼里是大大小小的办公室、校长室(你见过,那里有两层房间,永远不知道其中在发生什么)、机房、电子阅览室、图书馆、“谈国家大事的地方”。东西很多。两边的二、三层都有天桥,通向初中和高中楼。");

            AObject Building2 = new AObject(
                "2#楼", new string[] {
                "高中楼", "高中教学楼", "教学楼", "2#", "大楼", "楼房"
            },
                desc:           "2#楼:高中教学楼。与初中教学楼分布在行政楼前广场的两边,互相各成背对着的C字形。你没怎么去过,除了到那里一楼教室上美术课的时候。");

            AObject ReportHall = new AObject(
                "报告厅", new string[] {
                "大厅", "楼房"
            },
                desc:           "报告厅与高中教学楼[2#]相连,是凸出于教学楼东南侧的一个宽扁的方块。里面的座椅只够一个年级坐下:更大规模的活动通常在体育馆[6#]或者行政楼[1#]六楼举行。");

            AObject Building3 = new AObject(
                "3#楼", new string[] {
                "初中楼", "初中教学楼", "教学楼", "3#", "大楼", "楼房"
            },
                desc:           "3#楼:初中教学楼,你白天的寄居之地。与初中教学楼分布在行政楼前广场的两边,互相各成背对着的C字形。");

            AObject Building4 = new AObject(
                "4#楼", new string[] {
                "外事公寓楼", "外事公寓", "外事楼", "4#", "大楼", "楼房"
            },
                desc:           "4#楼:外事公寓楼。");

            AObject Building5 = new AObject(
                "5#楼", new[] { "5#", "大楼", "楼房" },
                desc:           "5#楼:没什么用的一幢楼。游戏里永远锁着。放在这里只是出于方便。");

            AObject Building6 = new AObject(
                "6#楼", new[] { "体育馆", "6#", "大楼", "楼房" },
                desc:           "6#楼:体育馆,高高的两层楼相当于其他地方的四层,夏天在这里爬上爬下的确令人泄气。不过它众多楼梯中也隐藏着各种各样的房间。");

            AObject Building7 = new AObject(
                "7#楼", new[] { "食堂", "餐厅", "7#", "大楼", "楼房" },
                desc:           "7#楼:食堂。半夜里世界上最没用的地方;二楼和三楼几盏应急灯微弱的红光从大窗户里透出来,此外一片黑暗。一楼附带超市,但此刻同样没用:你进不去。");

            AObject Building8 = new AObject(
                "8#楼", new[] { "初中男生寝室楼", "初中寝室楼", "男生寝室楼", "寝室楼", "8#", "大楼", "楼房" },
                desc:           "8#楼:你最熟悉的寝室楼。灯全部关了,外墙上失去了生活的气息,但那些交替凹凸排列着的窗户和阳台还是令你感到规整而舒适。");

            AObject Building9 = new AObject(
                "9#楼", new[] { "高中男生寝室楼", "高中寝室楼",
                               "男生寝室楼", "寝室楼", "9#", "大楼", "楼房" },
                desc:           "");

            AObject Building10 = new AObject(
                "10#楼", new[] { "高中女生寝室楼", "高中寝室楼",
                                "女生寝室楼", "寝室楼", "10#", "大楼", "楼房" },
                desc:           "");

            AObject Building11 = new AObject(
                "11#楼", new[] { "初中女生寝室楼", "初中寝室楼",
                                "女生寝室楼", "寝室楼", "11#", "大楼", "楼房" },
                desc:           "");

            AObject Playground = new AObject(
                "操场", new[] { "足球场" },
                desc:           "");

            AObject Garage = new AObject(
                "车库", new string[0],
                desc:           "");

            AObject BasketballCourt = new AObject(
                "篮球场", new[] { "球场" },
                desc:           "");

            // other items

            AObject GymPond = new AObject(
                "体育馆边的池塘", new[] { "池塘", "水池", "水" },
                desc:           "池塘在体育馆东门外延伸成L形。略微浑浊的水面被风吹成网状褶皱,建筑的阴影在其中破碎。几只模糊的鱼在水中移动。");
            AObject SquarePond = new AObject(
                "教学楼边的池塘", new[] { "池塘", "水池", "水" },
                desc:           "教学楼边的长方形池塘里,略微浑浊的水面被风吹成网状褶皱,天空的颜色在其中破碎。几只模糊的鱼在水中移动。");
            AObject Fish = new AObject(
                "鱼", new string[0],
                desc:           "几只鱼模糊地在水中移动。在不明朗的光线中你分辨出它们的样子:红色,黑色,白色,它们的胡须,它们大而呆滞的眼睛。");

            Fish.OnBeingSmelled = GymPond.OnBeingSmelled = (s, v) =>
            {
                Interactive.Print("闻起来像水。\n\n");
                return(HandleResult.FullManaged);
            };
            Fish.OnTaking = Fish.OnBeingTouched = (s, v) =>
            {
                if (v.triedGetFish)
                {
                    Interactive.Print("你已经徒劳地试过捉鱼了,并且不想再试一遍。\n\n");
                    return(HandleResult.Refused);
                }
                Interactive.Print("你走到池塘边,蹲下来把手伸进意外冰冷的水里。你的双手有些麻木,而鱼的反应速度比你更快;事实上,你烦躁地发觉自己完全无法从视觉上预测它们在水里的位置。");
                if (Utility.Chance(0.6))
                {
                    Interactive.Print("毫无希望地,你缩回手站起来。\n\n");
                    v.triedGetFish = true;
                }
                else
                {
                    Interactive.Print("你把手伸得更远,试着跟上几条向远处游走的鱼,然后你突然失去了平衡。在你能够做出反应之前,你已经随着一声巨响被彻骨寒冷的水包围着渗入。你挣扎着想浮起来(你记得池塘看上去很浅),但水看上去充满了整个世界。你无法呼吸……你的视野在暗下来。\n\n");
                    v.triedGetFish = true;
                    v.dreamStop    = true;
                    v.stopReason   = "water";
                }
                return(HandleResult.FullManaged);
            };
            SquarePond.SubObjects.Add(Fish);
            GymPond.SubObjects.Add(Fish);

            AObject Flower = new AObject(
                "花坛", new[] { "花" },
                desc:           "如迷宫般围绕台阶的花坛有你的一半高;从其中升起的花枝在雾中看起来非常微小,像显微镜下花瓣的纤毛。当然,运动是假象。");

            Campus.Objects.Clear();
            Campus.Objects.AddRange(new AObject[]
            {
                Building1, Building2, Building3, Building4, Building5, Building6, Building7, Building8, Building9, Building10, Building11, Playground, Garage, BasketballCourt,
                GymPond, SquarePond, Flower
            });

            // A = between; Hi = high; Lo = low; Fr = front of; Bk = back of;
            // NESW = n, e, s, w of; t = and; Tri = trivium; Sq = square; Rd = road;

            Area A7t8       = new Area();
            Area HiSq       = new Area();
            Area FrHiSq     = new Area();
            Area BkHiSq     = new Area();
            Area S1Rd       = new Area();
            Area TriWS1Rd   = new Area();
            Area A1t5       = new Area();
            Area A1t4       = new Area();
            Area A3t5       = new Area();
            Area LoSq       = new Area();
            Area A2t4       = new Area();
            Area FrRepHl    = new Area();
            Area A7t4       = new Area();
            Area Fr7        = new Area();
            Area TriEGate   = new Area();
            Area EA7t8      = new Area();
            Area ERepHl     = new Area();
            Area EGym       = new Area();
            Area FrGym      = new Area();
            Area EPlg       = new Area();
            Area A5tPlg     = new Area();
            Area NA5tPlg    = new Area();
            Area TriWGate   = new Area();
            Area RdWGate    = new Area();
            Area TriFrWGate = new Area();
            Area W6         = new Area();
            Area BkGym      = new Area();
            Area SE6Brg     = new Area();

            Campus.Areas.Clear();
            Campus.Areas.AddRange(new Area[] {
                A7t8, HiSq, FrHiSq, BkHiSq, S1Rd, TriWS1Rd, A1t5, A1t4, A3t5, LoSq, A2t4, FrRepHl, A7t4, Fr7, TriEGate, EA7t8, ERepHl, EGym, FrGym, EPlg, A5tPlg, NA5tPlg, TriWGate, RdWGate, TriFrWGate, W6, BkGym, SE6Brg, DarknessArea
            });

            AObject doorA7t8 = AObject.SimpleDoor(
                dest:           LobbyNo8,
                name:           "去8#寝室楼大厅的门",
                alias:          new[] { "里面", "室内", "大门", "门", "门内", "寝室楼", "大厅" },
                desc:           "通向室内的门。寝室楼大厅的灯光在里面苍白地亮着。",
                open:           true,
                flopside:       () => LobbyNo8.FindObjectInternal("外面"));

            Campus.Objects.Add(doorA7t8);
            SetupArea(ref A7t8, "食堂和寝室楼之间",
                      desc: "你站在食堂[7#]与你的寝室楼[8#]之间的空地上。东侧的远处围栏前停着几辆车。西侧通往一个小广场,几棵灰暗的大树后面显示出体育馆高大的影子。",
                      usable: new[] { Building7, Building8, doorA7t8 },
                      notClear: new[] { Building6 },
                      godir: new Dictionary <Direction, Area>
            {
                { Direction.W, HiSq },
                { Direction.E, EA7t8 }
            });

            SetupArea(ref HiSq, "寝室楼前的小广场",
                      desc: "你站在小广场的树下,浓荫掩蔽了光线,南边周围是一大片花坛。这里还属于“高地”,所以去北侧的行政楼[1#]就要走下台阶。西侧就是体育馆[6#],入口前有一个小池塘;在东边你能望见食堂[7#]和8#寝室楼。女生寝室楼[10#, 11#]在南边,还要上一段台阶才能走到。",
                      usable: new[] { Building6, Building8, Flower },
                      notClear: new[] { Building1, Building7, GymPond },
                      godir: new Dictionary <Direction, Area>
            {
                { Direction.E, A7t8 },
                { Direction.W, EGym },
                { Direction.N, FrHiSq },
                { Direction.S, BkHiSq }
            });

            SetupArea(ref BkHiSq, "台阶",
                      desc: "你站在花坛之间的台阶上,被雾中漂浮的不明确微细枝条所包围。北边立着小广场中间巨大的树。花坛的小路之外,四幢寝室楼在南面和东面形成半包围的结构。",
                      usable: new[] { Building1, Building7, Flower },
                      notClear: new[] { Building6, Building8, Building10, GymPond },
                      godir: new Dictionary <Direction, Area>
            {
                { Direction.N, HiSq }
            });

            SetupArea(ref FrHiSq, "台阶",
                      desc: "你站在连接学校南北两部分的台阶上,向北面对行政楼[1#],向南面对小广场。广场中央那棵巨大的树在这里看上去像一枚在雾霭中漂浮的榛子。",
                      usable: new[] { Building1, Building7 },
                      notClear: new[] { Building6 },
                      godir: new Dictionary <Direction, Area>
            {
                { Direction.S, HiSq },
                { Direction.N, S1Rd }
            });

            AObject doorS1Rd = AObject.SimpleDoor(
                dest:           Building1F1,
                name:           "行政楼的南门",
                alias:          new[] { "里面", "室内", "大门", "门", "门内", "行政楼" },
                desc:           "通向行政楼室内的门。",
                open:           false,
                flopside:       () => Building1F1.FindObjectInternal("南侧大门"));

            doorS1Rd.OnEntering = (s, v) =>
            {
                Building1F1.ChangeArea("大厅南侧");
                return(HandleResult.Continue);
            };
            Campus.Objects.Add(doorS1Rd);
            SetupArea(ref S1Rd, "道路",
                      desc: "你站在一条东西走向的大路上。这条路很长;顺着西边望去能看见操场,东边的另一头能看见食堂[7#]。北边侧对着行政楼[1#]入口,南边有台阶通向高地,那里有寝室和体育馆。你也可以向东北拐到行政楼[1#]和外事公寓[4#]之间。在你的头顶上方,树荫遮住了一半天空,紫红色的微光从树叶缝隙里漏下来。西端体育馆那边的墙上爬着稀疏的藤蔓。",
                      usable: new[] { Building1, Building7, doorS1Rd },
                      notClear: new[] { Building6 },
                      godir: new Dictionary <Direction, Area>
            {
                { Direction.S, FrHiSq },
                { Direction.W, TriWS1Rd },
                { Direction.E, Fr7 },
                { Direction.NE, A1t4 }
            });

            SetupArea(ref TriWS1Rd, "三岔路口",
                      desc: "你站在一条东西走向的大路上,西边延伸直到操场,东边的另一头延伸直到食堂[7#]。这个路口的北侧在行政楼[1#]和国际部[5#]之间分出一条过道。",
                      usable: new[] { Building1, Building5 },
                      notClear: new[] { Building6 },
                      godir: new Dictionary <Direction, Area>
            {
                { Direction.E, S1Rd },
                { Direction.W, EPlg },
                { Direction.N, A1t5 }
            });

            AObject doorA1t5_1 = AObject.SimpleDoor(
                dest:           null,
                name:           "行政楼西面的小门",
                alias:          new[] { "里面", "室内", "大门", "门", "门内", "行政楼" },
                desc:           "行政楼侧面通往楼梯间的门。",
                open:           false,
                locked: true);
            AObject doorA1t5_2 = AObject.SimpleDoor(
                dest:           null,
                name:           "国际部东门",
                alias:          new[] { "里面", "室内", "大门", "门", "门内", "国际部" },
                desc:           "通往国际部室内的大门。",
                open:           false,
                locked: true);

            Campus.Objects.Add(doorA1t5_1);
            Campus.Objects.Add(doorA1t5_2);
            SetupArea(ref A1t5, "行政楼侧面",
                      desc: "你站在行政楼[1#]和国际部[5#]之间的道路上。北边是初中教学楼[3#]下的空地,南边通向一条东西走向的大路。5#楼的大门在你西侧;东边有一个1#楼的侧门。",
                      usable: new[] { Building1, Building5, doorA1t5_1, doorA1t5_2 },
                      notClear: new[] { Building3 },
                      godir: new Dictionary <Direction, Area>
            {
                { Direction.S, TriWS1Rd },
                { Direction.N, A3t5 }
            });

            AObject doorA1t4_1 = AObject.SimpleDoor(
                dest:           null,
                name:           "行政楼东面的小门",
                alias:          new[] { "里面", "室内", "大门", "门", "门内", "行政楼" },
                desc:           "行政楼侧面通往楼梯间的门。",
                open:           false,
                locked: true);
            AObject doorA1t4_2 = AObject.SimpleDoor(
                dest:           null,
                name:           "外事公寓西门",
                alias:          new[] { "里面", "室内", "大门", "门", "门内", "外事公寓", "公寓" },
                desc:           "通往外事公寓室内的大门。",
                open:           false,
                locked: true);

            Campus.Objects.Add(doorA1t4_1);
            Campus.Objects.Add(doorA1t4_2);
            SetupArea(ref A1t4, "行政楼侧面",
                      desc: "你站在行政楼[1#]和外事公寓[4#]之间的道路上。北边是高中教学楼[2#]和报告厅附近的空地,西南通向一条东西走向的大路,东南通向食堂一带。4#楼的大门在你东侧;西边有一个1#楼的侧门。",
                      usable: new[] { Building1, Building4, doorA1t4_1, doorA1t4_2 },
                      notClear: new[] { Building2 },
                      godir: new Dictionary <Direction, Area>
            {
                { Direction.SW, S1Rd },
                { Direction.SE, Fr7 },
                { Direction.N, A2t4 }
            });

            AObject doorA3t5 = AObject.SimpleDoor(
                dest:           null,
                name:           "初中教学楼边门",
                alias:          new[] { "里面", "室内", "大门", "门", "门内", "初中教学楼", "教学楼" },
                desc:           "边门经过一段走廊通向高中教学楼。",
                open:           false,
                locked: true);

            Campus.Objects.Add(doorA3t5);
            SetupArea(ref A3t5, "教学楼侧面",
                      desc: "你站在初中教学楼[3#]和国际部[5#]之间宽阔的道路上;这里更像一块供人来往活动的空地。西边通向一条操场边南北走向的大路。在东边,教学楼三、四楼的天桥从你的上方经过进入行政楼[1#];你可以向东从天桥下走向教学楼间的广场。南边有一条路通往行政楼[1#]和国际部[5#]之间。",
                      usable: new[] { Building3, Building5, doorA3t5 },
                      notClear: new[] { Building1 },
                      godir: new Dictionary <Direction, Area>
            {
                { Direction.S, A1t5 },
                { Direction.E, LoSq }
            });

            AObject doorLoSq_1 = AObject.SimpleDoor(
                dest:           null,
                name:           "初中教学楼正门",
                alias:          new[] { "里面", "室内", "大门", "门", "门内", "初中教学楼", "教学楼" },
                desc:           "楼边池塘上一座小桥后面,初中教学楼的正门。",
                open:           false,
                locked: true);
            AObject doorLoSq_2 = AObject.SimpleDoor(
                dest:           null,
                name:           "高中教学楼正门",
                alias:          new[] { "里面", "室内", "大门", "门", "门内", "高中教学楼", "教学楼" },
                desc:           "楼边池塘上一座小桥后面,高中教学楼的正门。",
                open:           false,
                locked: true);
            AObject doorLoSq_3 = AObject.SimpleDoor(
                dest:           Building1F1,
                name:           "行政楼的正门",
                alias:          new[] { "里面", "室内", "大门", "门", "门内", "行政楼" },
                desc:           "通向行政楼室内的门。",
                open:           false,
                flopside:       () => Building1F1.FindObjectInternal("北侧大门"));

            doorLoSq_3.OnEntering = (s, v) =>
            {
                Building1F1.ChangeArea("大厅北侧");
                return(HandleResult.Continue);
            };
            Campus.Objects.Add(doorLoSq_1);
            Campus.Objects.Add(doorLoSq_2);
            Campus.Objects.Add(doorLoSq_3);
            SetupArea(ref LoSq, "教学楼间的小广场",
                      desc: "你在教学楼间平坦的广场上,无树的夜晚天空广阔地显现在你的头顶,投下奇异的光照。旗杆是这里唯一高的事物;你注意到上面没有旗帜。行政楼的正门在广场的南面;向西、向东分别可以从三、四楼的天桥下走向初中、高中教学楼的侧门;当然,广场前部侧面的教学楼正门也可进入。",
                      usable: new[] { Building1, Building2, Building3, doorLoSq_1, doorLoSq_2,
                                      doorLoSq_3, SquarePond },
                      notClear: new AObject[0],
                      godir: new Dictionary <Direction, Area>
            {
                { Direction.W, A3t5 },
                { Direction.E, A2t4 }
            });

            AObject doorA2t4 = AObject.SimpleDoor(
                dest:           null,
                name:           "高中教学楼边门",
                alias:          new[] { "里面", "室内", "大门", "门", "门内", "高中教学楼", "教学楼" },
                desc:           "边门经过一段走廊通向高中教学楼。",
                open:           false,
                locked: true);

            Campus.Objects.Add(doorA2t4);
            SetupArea(ref A2t4, "教学楼侧面",
                      desc: "你站在高中教学楼[2#]和外事公寓[4#]之间宽阔的道路上;这里更像一块供人来往活动的空地。东侧不远处你能看见高中楼一楼附带的报告厅及其入口的方块形状(入口在外面);再往东就到了围墙附近。在西边,教学楼三、四楼的天桥从你的上方经过进入行政楼[1#];你可以向西从天桥下走向教学楼间的广场。南边有一条路通往行政楼[1#]和外事公寓[4#]之间。",
                      usable: new[] { Building2, Building5, ReportHall, doorA2t4 },
                      notClear: new[] { Building1 },
                      godir: new Dictionary <Direction, Area>
            {
                { Direction.S, A1t4 },
                { Direction.E, FrRepHl },
                { Direction.W, LoSq }
            });

            AObject doorFrRepHl = AObject.SimpleDoor(
                dest:           null,
                name:           "报告厅大门",
                alias:          new[] { "里面", "室内", "大门", "门", "门内", "报告厅", "大厅" },
                desc:           "报告厅的大门大多数时候都是锁着的;透过玻璃你只能隐约可见几排昏暗的座椅。",
                open:           false,
                locked: true);

            Campus.Objects.Add(doorFrRepHl);
            SetupArea(ref FrRepHl, "报告厅入口",
                      desc: "你站在高中楼一楼报告厅的入口附近,高中教学楼[2#]外的空地中。外事公寓[4#]在你的南边显现出侧面;东边通往围墙边的道路。你也可以向西朝教学楼入口那边行走。",
                      usable: new[] { Building2, Building5, ReportHall, doorFrRepHl },
                      notClear: new[] { Building4 },
                      godir: new Dictionary <Direction, Area>
            {
                { Direction.W, A2t4 },
                { Direction.E, ERepHl }
            });

            AObject doorFr7 = AObject.SimpleDoor(
                dest:           null,
                name:           "食堂大门",
                alias:          new[] { "里面", "室内", "大门", "门", "门内", "食堂" },
                desc:           "一段台阶后面的食堂正门,透过玻璃只能看见比天色更为黑暗的一团方块。",
                open:           false,
                locked: true);

            Campus.Objects.Add(doorFr7);
            SetupArea(ref Fr7, "食堂前的大路",
                      desc: "你站在一条东西走向的大路上。你的南边是食堂[7#]的台阶和大门,在夜里看上去是比天色更为黑暗的一团方块;北边,外事公寓[4#]以其侧面阻挡了你的视线。西边,道路直通向操场方向;你也可以向东到达一个三岔路口,或者向西北拐到4#楼的另一面。",
                      usable: new[] { Building4, Building7, doorFr7 },
                      notClear: new[] { Building1 },
                      godir: new Dictionary <Direction, Area>
            {
                { Direction.W, S1Rd },
                { Direction.E, TriEGate },
                { Direction.NW, A1t4 }
            });

            SetupArea(ref TriEGate, "东门边的三岔路口",
                      desc: "你站在一条东西走向的大路的尽头,东边本应是学校的侧门,但此刻——虽然有路灯和天空的亮光照耀——那里只是一片令人不寒而栗的黑暗。南北两面各有围墙边的道路环绕学校;你也可以从西面走到食堂[7#]和外事公寓[4#]之间。",
                      usable: new[] { Building7 },
                      notClear: new[] { Building4 },
                      godir: new Dictionary <Direction, Area>
            {
                { Direction.W, Fr7 },
                { Direction.E, DarknessArea },
                { Direction.N, ERepHl },
                { Direction.S, EA7t8 }
            });

            SetupArea(ref EA7t8, "围墙边的道路",
                      desc: "你站在一条南北走向的道路上,东边紧靠学校的围墙。西边,食堂[7#]和8#寝室楼之间有大路直通向寝室楼前的小广场。围墙外只有一片超现实、不透明的黑暗。",
                      usable: new AObject[0],
                      notClear: new[] { Building7, Building8 },
                      godir: new Dictionary <Direction, Area>
            {
                { Direction.N, TriEGate },
                { Direction.W, A7t8 }
            });

            SetupArea(ref ERepHl, "围墙边的道路",
                      desc: "你站在一条南北走向的道路上,东边紧靠学校的围墙。西边,高中教学楼[2#]报告厅和食堂之间分岔出一块空地直通向行政楼[1#]一带。东边的围墙外只有一片超现实、不透明的黑暗。",
                      usable: new AObject[0],
                      notClear: new[] { Building4, ReportHall, Building2 },
                      godir: new Dictionary <Direction, Area>
            {
                { Direction.S, TriEGate },
                { Direction.W, FrRepHl }
            });
            // TODO: a few cars

            AObject doorEGym = AObject.SimpleDoor(
                dest:           null,
                name:           "体育馆的侧门",
                alias:          new[] { "里面", "室内", "大门", "门", "门内", "体育馆" },
                desc:           "体育馆的侧门,透过玻璃能看见苍白昏暗的楼梯间。",
                open:           false,
                locked: true);

            Campus.Objects.Add(doorEGym);
            SetupArea(ref EGym, "体育馆边",
                      desc: "你站在体育馆边上。小广场在你东侧,西边则是体育馆[6#]的侧门;门前有一个长方形池塘。你也可以往西北绕过侧门来到正门前的平地上,或是向南绕过花坛边缘,那边远处是一排寝室楼。",
                      usable: new[] { Building6, GymPond, doorEGym },
                      notClear: new[] { Building7, Building8, Building9, Building10, Flower },
                      godir: new Dictionary <Direction, Area>
            {
                { Direction.E, HiSq },
                { Direction.NW, FrGym },
                { Direction.S, SE6Brg }
            });

            AObject doorFrGym = AObject.SimpleDoor(
                dest:           null,
                name:           "体育馆的大门",
                alias:          new[] { "里面", "室内", "大门", "门", "门内", "体育馆" },
                desc:           "一段台阶后是体育馆的大门;里面的宽阔空间没有开灯,透过玻璃看不清楚。",
                open:           false,
                locked: true);

            Campus.Objects.Add(doorFrGym);
            SetupArea(ref FrGym, "体育馆前的平台",
                      desc: "你站在体育馆[6#]前的平台上。这是石板铺成的一大块平地,北边的栏杆之外,你能看见行政楼[1#]和5#楼,它们处于低地,那边无法直接走上来。平地的西边有台阶下去通向大路,路的另一边就是操场和篮球场。你也可以向东南走到体育馆[6#]东边的侧门处,小广场附近。",
                      usable: new[] { Building6, doorFrGym },
                      notClear: new[] { Building1, Building5 },
                      godir: new Dictionary <Direction, Area>
            {
                { Direction.SE, EGym },
                { Direction.W, TriWGate }
            });

            SetupArea(ref EPlg, "操场入口边",
                      desc: "你站在一条南北走向的大路上,另一边的道路直通向食堂[7#],南边大路直通向篮球场。环绕操场的围栏在西边入口处打开。",
                      usable: new[] { Playground, Building5 },
                      notClear: new[] { BasketballCourt, Building6 },
                      godir: new Dictionary <Direction, Area>
            {
                { Direction.E, TriWS1Rd },
                { Direction.N, A5tPlg },
                { Direction.S, TriWGate }
            });
            EPlg.RoomTo.Add(Direction.W, GameMap.Playground);
            EPlg.OnGoDirection = (s, v, d) =>
            {
                GameMap.Playground.ChangeArea("入口处的空地");
                return(HandleResult.Continue);
            };

            AObject doorA5tPlg = AObject.SimpleDoor(
                dest:           null,
                name:           "国际部的西门",
                alias:          new[] { "里面", "室内", "大门", "门", "门内", "国际部" },
                desc:           "通往国际部室内的门。",
                open:           false,
                locked: true);

            Campus.Objects.Add(doorA5tPlg);
            SetupArea(ref A5tPlg, "操场边的道路",
                      desc: "你站在一条南北走向的道路上,西边围栏之外就是操场,东边面对国际部[5#]大楼的后门。",
                      usable: new[] { Playground, Building5, doorA5tPlg },
                      notClear: new AObject[0],
                      godir: new Dictionary <Direction, Area>
            {
                { Direction.S, EPlg },
                { Direction.N, NA5tPlg }
            });

            SetupArea(ref NA5tPlg, "操场边的道路",
                      desc: "你站在一条南北走向的道路上,西边围栏之外就是操场,东边在初中教学楼[3#]和国际部[5#]之间分岔出一条大路。",
                      usable: new[] { Playground, Building5 },
                      notClear: new AObject[0],
                      godir: new Dictionary <Direction, Area>
            {
                { Direction.S, A5tPlg },
                { Direction.E, A3t5 }
            });

            SetupArea(ref TriWGate, "岔路口",
                      desc: "你站在一条南北走向的大路上,西边在足球场和篮球场之间分出另一条路通向学校西门,东边有一条坡道通往体育馆前的空地。",
                      usable: new[] { Building6, Playground, BasketballCourt },
                      notClear: new AObject[0],
                      godir: new Dictionary <Direction, Area>
            {
                { Direction.E, FrGym },
                { Direction.W, RdWGate },
                { Direction.N, EPlg },
                { Direction.S, W6 }
            });

            SetupArea(ref RdWGate, "通向学校西门的道路",
                      desc: "你站在足球场和篮球场之间的路上,西边通往你通常在那里搭校车回家的西门,但此刻——虽然有路灯和天空的亮光照耀——那里只是一片令人不寒而栗的黑暗。你也可以从东面退回学校。",
                      usable: new AObject[0],
                      notClear: new[] { Playground, BasketballCourt },
                      godir: new Dictionary <Direction, Area>
            {
                { Direction.W, TriFrWGate },
                { Direction.E, TriWGate }
            });
            RdWGate.RoomTo.Add(Direction.N, GameMap.Playground);
            RdWGate.OnGoDirection = (s, v, d) =>
            {
                GameMap.Playground.ChangeArea("观众席末端平台");
                return(HandleResult.Continue);
            };

            SetupArea(ref TriFrWGate, "西门前的三岔路口",
                      desc: "你站在足球场和篮球场之间道路上的尽头,西边(那里原本是学校西门)紧邻着一片令人不寒而栗的黑暗。道路向东面延伸退回学校,另有一条小路在北面分岔到操场后面。",
                      usable: new AObject[0],
                      notClear: new[] { Playground, BasketballCourt },
                      godir: new Dictionary <Direction, Area>
            {
                { Direction.W, DarknessArea },
                { Direction.E, RdWGate }
            });

            AObject doorW6 = AObject.SimpleDoor(
                dest:           null,
                name:           "体育馆侧面楼梯",
                alias:          new[] { "入口", "东", "楼梯", "体育馆" },
                desc:           "体育馆侧面延伸到路边的楼梯,向上通往体育馆二楼。",
                open:           false,                 // TODO: should be true
                locked: true);

            doorW6.Information = (s, v) => "";
            doorW6.IsOpenable  = false;
            Campus.Objects.Add(doorW6);
            SetupArea(ref W6, "篮球场边的道路",
                      desc: "你站在一条南北走向的道路上,西边围栏之外就是室外篮球场,东边面对体育馆[6#]侧面延伸到路边的楼梯。楼梯向上通往体育馆二楼;一楼没有侧门,只有几扇带防护栏的窗户。你也可以向东南拐到体育馆后面。",
                      usable: new[] { BasketballCourt, Building6, doorW6 },
                      notClear: new[] { Playground },
                      godir: new Dictionary <Direction, Area>
            {
                { Direction.N, TriWGate },
                { Direction.SE, BkGym }
            });

            AObject doorBkGym = AObject.SimpleDoor(
                dest:           null,
                name:           "体育馆的后门",
                alias:          new[] { "里面", "室内", "大门", "门", "门内", "体育馆" },
                desc:           "体育馆的后门,透过玻璃能看见苍白昏暗的楼梯间。",
                open:           false,
                locked: true);

            Campus.Objects.Add(doorBkGym);
            SetupArea(ref BkGym, "体育馆后的空地",
                      desc: "你站在体育馆[6#]南边;这是种有树木的一块平地,东边是一座向北通向体育馆侧面池塘上的木板桥的入口,西北通向篮球场边的道路。你也可以向南,横穿过花坛走向空地靠近初中女生寝室楼[11#]附近的一边。",
                      usable: new[] { Building6, Flower, Building11, GymPond, doorBkGym },
                      notClear: new[] { BasketballCourt, Building10 },
                      godir: new Dictionary <Direction, Area>
            {
                { Direction.NW, W6 },
                { Direction.E, SE6Brg }
            });

            SetupArea(ref SE6Brg, "木板桥上",
                      desc: "你站在一座体育馆边池塘的木板桥上,北边通往体育馆侧面附近的地面,南边通向初中女生寝室楼[11#]附近。你也可以往西去向体育馆南边的空地。",
                      usable: new[] { Building6, Flower, GymPond, Building11 },
                      notClear: new[] { Building9, Building10 },
                      godir: new Dictionary <Direction, Area>
            {
                { Direction.N, EGym },
                { Direction.W, BkGym }
            });
        }