Esempio n. 1
0
        public void TestOneWayExitBehavior()
        {
            // Put the exit in room A only, and register an exit command to travel one way.
            roomA.Add(exit);
            exitBehavior.AddDestination("east", roomB.Id);

            // Ensure the exit is rigged up to the correct location now, but does not work the other way around.
            Assert.AreSame(exitBehavior.GetDestination(roomA), roomB);
            Assert.AreSame(exitBehavior.GetDestination(roomA), roomB);
            Assert.AreNotSame(exitBehavior.GetDestination(roomB), roomA);

            // Create an unmovable actor, and ensure that said actor cannot move through.
            actor = new Thing()
            {
                Name = "Actor"
            };
            roomA.Add(actor);
            exitBehavior.MoveThrough(actor);
            Assert.AreSame(actor.Parent, roomA);

            // Make the actor movable, and try moving the actor through again.
            actor.Behaviors.Add(new MovableBehavior());
            exitBehavior.MoveThrough(actor);
            Assert.AreSame(actor.Parent, roomB);

            // Ensure the actor does not end up in room A if we try to shove the actor through again.
            exitBehavior.MoveThrough(actor);
            Assert.AreSame(actor.Parent, roomB);

            // TODO: Place the actor back in room A, and try using the context command to move it?
            roomA.Add(actor);
        }
Esempio n. 2
0
        public void Init()
        {
            // Create the basic actor instances and behavior for test.
            witnessThing = new Thing()
            {
                Name = "WitnessThing", Id = TestThingID.Generate("testthing")
            };
            actingThing = new Thing()
            {
                Name = "ActingThing", Id = TestThingID.Generate("testthing")
            };
            openableThing = new Thing()
            {
                Name = "OpenableThing", Id = TestThingID.Generate("testthing")
            };
            opensClosesBehavior = new OpensClosesBehavior();

            // Set up the actors inside another (which we'll call a "room" although it needn't actually be a room).
            room = new Thing()
            {
                Name = "Room", Id = TestThingID.Generate("room")
            };
            room.Add(witnessThing);
            room.Add(actingThing);
            room.Add(openableThing);

            // Prepare to verify correct eventing occurs.
            witnessThing.Eventing.MiscellaneousRequest += (root, e) => { lastWitnessRequest = e; };
            witnessThing.Eventing.MiscellaneousEvent   += (root, e) => { lastWitnessEvent = e; };
            actingThing.Eventing.MiscellaneousRequest  += (root, e) => { lastActorRequest = e; };
            actingThing.Eventing.MiscellaneousEvent    += (root, e) => { lastActorEvent = e; };
        }
Esempio n. 3
0
        public void TestOpeningClosingAndMovementForExits()
        {
            // Create two one-way exits and two rooms to attach them to.
            var openableExitA = new Thing()
            {
                Name = "OpenableExitA", Id = TestThingID.Generate("testthing")
            };
            var openableExitB = new Thing()
            {
                Name = "OpenableExitB", Id = TestThingID.Generate("testthing")
            };
            var roomA = new Thing(new RoomBehavior())
            {
                Name = "Room A", Id = TestThingID.Generate("testroom")
            };
            var roomB = new Thing(new RoomBehavior())
            {
                Name = "Room B", Id = TestThingID.Generate("testroom")
            };

            roomA.Add(openableExitA);
            roomB.Add(openableExitB);

            // Attach ExitBehavior and OpensClosesBehaviors in different orders though, to verify in test that
            // eventing and such work correctly regardless of attachment order.
            var exitBehaviorA        = new ExitBehavior();
            var exitBehaviorB        = new ExitBehavior();
            var opensClosesBehaviorB = new OpensClosesBehavior();

            openableExitA.Behaviors.Add(exitBehaviorA);
            openableExitA.Behaviors.Add(opensClosesBehavior);
            openableExitB.Behaviors.Add(opensClosesBehaviorB);
            openableExitB.Behaviors.Add(exitBehaviorB);

            // Rig up behaviors so the actor can move, and move from one A to B, and from B to A.
            actingThing.Behaviors.Add(new MovableBehavior());
            exitBehaviorA.AddDestination("toB", roomB.Id);
            exitBehaviorB.AddDestination("toA", roomA.Id);

            // Ensure that the actingThing cannot move through either exit while it is in default (closed) state.
            roomA.Add(actingThing);
            exitBehaviorA.MoveThrough(actingThing);
            Assert.AreSame(roomA, actingThing.Parent);

            roomB.Add(actingThing);
            exitBehaviorB.MoveThrough(actingThing);
            Assert.AreSame(roomB, actingThing.Parent);

            // Ensure that the actingThing can open and move through each openable exit to get between rooms.
            opensClosesBehaviorB.Open(actingThing);
            exitBehaviorB.MoveThrough(actingThing);
            Assert.AreSame(roomA, actingThing.Parent);

            opensClosesBehavior.Open(actingThing);
            exitBehaviorA.MoveThrough(actingThing);
            Assert.AreSame(roomB, actingThing.Parent);
        }
Esempio n. 4
0
        /// <summary>Executes the command.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        public override void Execute(ActionInput actionInput)
        {
            string      itemID = actionInput.Params[0];
            IController sender = actionInput.Controller;
            Thing       parent = sender.Thing.Parent;
            Thing       thing  = parent.FindChild(t => t.Id == itemID);

            if (thing == null)
            {
                parent = sender.Thing;
                thing  = parent.FindChild(t => t.Id == itemID);
                if (thing == null)
                {
                    sender.Write(string.Format("Cannot find {0}.", itemID));
                    return;
                }
            }

            Thing clonedThing = thing.Clone();

            parent.Add(clonedThing);
            var userControlledBehavior = sender.Thing.Behaviors.FindFirst <UserControlledBehavior>();

            userControlledBehavior.Controller.Write("You clone " + thing.Id + ". New item is " + clonedThing.Id + ".");
        }
Esempio n. 5
0
        // @@@ OpensClosesBehavior needs to listen for movement events and set e.Cancel if the transition object
        //     is closed at the time.
        /// <summary>
        /// Move the entity to the specified room.
        /// </summary>
        /// <param name="destination">
        /// @@@ TODO: The destination to move the entity to; if the destination has an ExitBehavior then this Thing is
        /// automatically moved to the other destination of the exit (IE an adjacent room, portal destination,
        /// or inside/outside of a vehicle, et cetera).
        /// </param>
        /// <param name="goingVia">The thing we are travelling via (IE an Exit, an Enterable thing, etc.)</param>
        /// <param name="leavingMessage">A sensory message describing this sort of 'leaving' movement.</param>
        /// <param name="arrivingMessage">A sensory message describing this sort of 'arriving' movement.</param>
        /// <returns>True if the entity was successfully moved, else false.</returns>
        public bool Move(Thing destination, Thing goingVia, SensoryMessage leavingMessage, SensoryMessage arrivingMessage)
        {
            Thing actor = this.Parent;
            Thing goingFrom = actor.Parent;

            // Prepare events to request and send (if not cancelled).
            var leaveEvent = new LeaveEvent(actor, goingFrom, destination, goingVia, leavingMessage);
            var arriveEvent = new ArriveEvent(actor, goingFrom, destination, goingVia, arrivingMessage);

            // Broadcast the Leave Request first to see if the player is allowed to leave.
            actor.Eventing.OnMovementRequest(leaveEvent, EventScope.ParentsDown);
            if (!leaveEvent.IsCancelled)
            {
                // Next see if the player is allowed to Arrive at the new location.
                destination.Eventing.OnMovementRequest(arriveEvent, EventScope.SelfDown);
                if (!arriveEvent.IsCancelled)
                {
                    actor.Eventing.OnMovementEvent(leaveEvent, EventScope.ParentsDown);
                    actor.RemoveFromParents();
                    destination.Add(actor);

                    // @@@ TODO: Ensure these automatically enqueue a save.
                    destination.Eventing.OnMovementEvent(arriveEvent, EventScope.SelfDown);
                    return true;
                }
            }

            return false;
        }
        public void TestMultipleParentingBehavior()
        {
            // Verify we can add and retrieve the MultipleParentsBehavior of a Thing.
            this.child.Behaviors.Add(this.multipleParentsBehavior);
            Verify.IsTrue(this.child.Behaviors.FindFirst<MultipleParentsBehavior>() == this.multipleParentsBehavior);

            // Verify it can now be a child of multiple parents, and one of those can be found as the primary Parent.
            this.parent1.Add(this.child);
            this.parent2.Add(this.child);
            Verify.IsTrue(this.parent1.Children.Contains(this.child));
            Verify.IsTrue(this.parent2.Children.Contains(this.child));
            Verify.IsTrue(this.child.Parent == this.parent1 || this.child.Parent == this.parent2);

            // Verify we can remove the item from a secondary parent, and still be attached well to the primary.
            this.parent2.Remove(this.child);
            Verify.IsTrue(this.parent1.Children.Contains(this.child));
            Verify.IsTrue(!this.parent2.Children.Contains(this.child));
            Verify.IsTrue(this.child.Parent == this.parent1);
            this.parent2.Add(this.child);

            // Verify we can remove the item from a primary parent, and a secondary parent becomes the primary.
            this.parent1.Remove(this.child);
            Verify.IsTrue(!this.parent1.Children.Contains(this.child));
            Verify.IsTrue(this.parent2.Children.Contains(this.child));
            Verify.IsTrue(this.child.Parent == this.parent2);
            this.parent1.Add(this.child);

            // Verify we can be attached to more than 2 parents.
            Thing parent3 = new Thing() { Name = "Thing3", ID = TestThingID.Generate("testthing") };
            parent3.Add(this.child);
            Verify.IsTrue(this.parent1.Children.Contains(this.child));
            Verify.IsTrue(this.parent2.Children.Contains(this.child));
            Verify.IsTrue(parent3.Children.Contains(this.child));
            Verify.IsTrue(this.child.Parent != null);
        }
Esempio n. 7
0
        /// <summary>Executes the command.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        public override void Execute(ActionInput actionInput)
        {
            // TODO: Move item from one owner to another transactionally, if applicable.
            // TODO: Test, may be broken now... especially for only putting SOME of a stack...
            thing.Parent.Remove(thing);
            newParent.Add(thing);

            actionInput.Controller.Write(new OutputBuilder().AppendLine($"You put {thing.FullName} in {newParent.Name}."));
        }
Esempio n. 8
0
 /// <summary>Executes the command.</summary>
 /// <param name="actionInput">The full input specified for executing the command.</param>
 public override void Execute(ActionInput actionInput)
 {
     // TODO: Move item from one owner to another transactionally, if applicable.
     // TODO: Single sensory message too?  $"You put {thing.FullName} in {newParent.Name}."
     // TODO: Test, may be broken now... especially for only putting SOME of a stack...
     if (thing.Parent.Remove(thing))
     {
         newParent.Add(thing);
     }
 }
Esempio n. 9
0
        /// <summary>Executes the command.</summary>
        /// <param name="actionInput">The full input specified for executing the command.</param>
        public override void Execute(ActionInput actionInput)
        {
            // TODO: Move item from one owner to another transactionally, if applicable.
            // TODO: Test, may be broken now... especially for only putting SOME of a stack...
            thing.Parent.Remove(thing);
            newParent.Add(thing);

            string message = string.Format("You put {0} in {1}", thing.FullName, newParent.Name);

            actionInput.Controller.Write(message);
        }
Esempio n. 10
0
        public void TestSingleParentingBehavior()
        {
            // Verify that a thing which has not yet been added to a parent, has none.
            Assert.IsTrue(child.Parent == null);

            // Verify that a basic thing can be added to a parent correctly.
            parent1.Add(child);
            Assert.IsTrue(parent1.Children.Contains(child));
            Assert.IsTrue(!parent2.Children.Contains(child));
            Assert.IsTrue(child.Parent == parent1);

            // Verify adding it to a second parent actually reassigns the parent.
            parent2.Add(child);
            Assert.IsTrue(parent2.Children.Contains(child));
            Assert.IsTrue(!parent1.Children.Contains(child));
            Assert.IsTrue(child.Parent == parent2);

            // Verify removing it from the last parent, cleans up the parent/child relationships.
            parent2.Remove(child);
            Assert.IsTrue(!parent1.Children.Contains(child));
            Assert.IsTrue(!parent2.Children.Contains(child));
            Assert.IsTrue(child.Parent == null);
        }
Esempio n. 11
0
        public void TestMultipleParentingBehavior()
        {
            // Verify we can add and retrieve the MultipleParentsBehavior of a Thing.
            child.Behaviors.Add(multipleParentsBehavior);
            Assert.IsTrue(child.Behaviors.FindFirst <MultipleParentsBehavior>() == multipleParentsBehavior);

            // Verify it can now be a child of multiple parents, and one of those can be found as the primary Parent.
            parent1.Add(child);
            parent2.Add(child);
            Assert.IsTrue(parent1.Children.Contains(child));
            Assert.IsTrue(parent2.Children.Contains(child));
            Assert.IsTrue(child.Parent == parent1 || child.Parent == parent2);

            // Verify we can remove the item from a secondary parent, and still be attached well to the primary.
            parent2.Remove(child);
            Assert.IsTrue(parent1.Children.Contains(child));
            Assert.IsTrue(!parent2.Children.Contains(child));
            Assert.IsTrue(child.Parent == parent1);
            parent2.Add(child);

            // Verify we can remove the item from a primary parent, and a secondary parent becomes the primary.
            parent1.Remove(child);
            Assert.IsTrue(!parent1.Children.Contains(child));
            Assert.IsTrue(parent2.Children.Contains(child));
            Assert.IsTrue(child.Parent == parent2);
            parent1.Add(child);

            // Verify we can be attached to more than 2 parents.
            Thing parent3 = new Thing()
            {
                Name = "Thing3", Id = TestThingID.Generate("testthing")
            };

            parent3.Add(child);
            Assert.IsTrue(parent1.Children.Contains(child));
            Assert.IsTrue(parent2.Children.Contains(child));
            Assert.IsTrue(parent3.Children.Contains(child));
            Assert.IsTrue(child.Parent != null);
        }
        public void TestOpeningClosingAndMovementForExits()
        {
            // Create two one-way exits and two rooms to attach them to.
            var openableExitA = new Thing() { Name = "OpenableExitA", ID = TestThingID.Generate("testthing") };
            var openableExitB = new Thing() { Name = "OpenableExitB", ID = TestThingID.Generate("testthing") };
            var roomA = new Thing(new RoomBehavior()) { Name = "Room A", ID = TestThingID.Generate("testroom") };
            var roomB = new Thing(new RoomBehavior()) { Name = "Room B", ID = TestThingID.Generate("testroom") };
            roomA.Add(openableExitA);
            roomB.Add(openableExitB);

            // Attach ExitBehavior and OpensClosesBehaviors in different orders though, to verify in test that
            // eventing and such work correctly regardless of attachment order.
            var exitBehaviorA = new ExitBehavior();
            var exitBehaviorB = new ExitBehavior();
            var opensClosesBehaviorB = new OpensClosesBehavior();
            openableExitA.Behaviors.Add(exitBehaviorA);
            openableExitA.Behaviors.Add(this.opensClosesBehavior);
            openableExitB.Behaviors.Add(opensClosesBehaviorB);
            openableExitB.Behaviors.Add(exitBehaviorB);

            // Rig up behaviors so the actor can move, and move from one A to B, and from B to A.
            this.actingThing.Behaviors.Add(new MovableBehavior());
            exitBehaviorA.AddDestination("toB", roomB.ID);
            exitBehaviorB.AddDestination("toA", roomA.ID);

            // Ensure that the actingThing cannot move through either exit while it is in default (closed) state.
            roomA.Add(this.actingThing);
            exitBehaviorA.MoveThrough(this.actingThing);
            Verify.AreSame(roomA, this.actingThing.Parent);

            roomB.Add(this.actingThing);
            exitBehaviorB.MoveThrough(this.actingThing);
            Verify.AreSame(roomB, this.actingThing.Parent);

            // Ensure that the actingThing can open and move through each openable exit to get between rooms.
            opensClosesBehaviorB.Open(this.actingThing);
            exitBehaviorB.MoveThrough(this.actingThing);
            Verify.AreSame(roomA, this.actingThing.Parent);

            this.opensClosesBehavior.Open(this.actingThing);
            exitBehaviorA.MoveThrough(this.actingThing);
            Verify.AreSame(roomB, this.actingThing.Parent);
        }
Esempio n. 13
0
        public void Init()
        {
            // Create the basic actor instances and behavior for test.
            witness = new Thing()
            {
                Name = "Witness", Id = TestThingID.Generate("testthing")
            };
            stalker1 = new Thing()
            {
                Name = "Stalker1", Id = TestThingID.Generate("testthing")
            };
            stalker2 = new Thing()
            {
                Name = "Stalker2", Id = TestThingID.Generate("testthing")
            };
            victim1 = new Thing()
            {
                Name = "Victim1", Id = TestThingID.Generate("testthing")
            };
            victim2 = new Thing()
            {
                Name = "Victim2", Id = TestThingID.Generate("testthing")
            };

            // Set up the rooms.
            room1 = new Thing()
            {
                Name = "Room", Id = TestThingID.Generate("room")
            };
            room2 = new Thing()
            {
                Name = "Room 2", Id = TestThingID.Generate("room")
            };

            // Set up an exit connecting the two rooms.
            exit = new Thing()
            {
                Name = "East Exit", Id = TestThingID.Generate("exit")
            };
            var exitBehavior = new ExitBehavior();

            ////exitBehavior.AddDestination("west", room1.ID);
            ////exitBehavior.AddDestination("east", room1.ID);
            ////exit.BehaviorManager.Add(exitBehavior);

            room1.Add(exit);
            room2.Add(exit);

            // Populate the first room.
            room1.Add(witness);
            room1.Add(stalker1);
            room1.Add(stalker2);
            room1.Add(victim1);
            room1.Add(victim2);

            // Prepare to verify correct eventing occurs.
            witness.Eventing.MovementRequest  += (root, e) => { lastWitnessRequest = e; };
            witness.Eventing.MovementEvent    += (root, e) => { lastWitnessEvent = e; };
            stalker1.Eventing.MovementRequest += (root, e) => { lastStalkerRequest = e; };
            stalker1.Eventing.MovementEvent   += (root, e) => { lastStalkerEvent = e; };
            stalker2.Eventing.MovementRequest += (root, e) => { lastStalkerRequest = e; };
            stalker2.Eventing.MovementEvent   += (root, e) => { lastStalkerEvent = e; };
            victim1.Eventing.MovementRequest  += (root, e) => { lastVictimRequest = e; };
            victim1.Eventing.MovementEvent    += (root, e) => { lastVictimEvent = e; };
            victim2.Eventing.MovementRequest  += (root, e) => { lastVictimRequest = e; };
            victim2.Eventing.MovementEvent    += (root, e) => { lastVictimEvent = e; };
        }