public void Init() { // Create the basic actor instances and behavior for test. this.witness = new Thing() { Name = "Witness", ID = TestThingID.Generate("testthing") }; this.stalker1 = new Thing() { Name = "Stalker1", ID = TestThingID.Generate("testthing") }; this.stalker2 = new Thing() { Name = "Stalker2", ID = TestThingID.Generate("testthing") }; this.victim1 = new Thing() { Name = "Victim1", ID = TestThingID.Generate("testthing") }; this.victim2 = new Thing() { Name = "Victim2", ID = TestThingID.Generate("testthing") }; // Set up the rooms. this.room1 = new Thing() { Name = "Room", ID = TestThingID.Generate("room") }; this.room2 = new Thing() { Name = "Room 2", ID = TestThingID.Generate("room") }; // Set up an exit connecting the two rooms. this.exit = new Thing() { Name = "East Exit", ID = TestThingID.Generate("exit") }; var exitBehavior = new ExitBehavior(); ////exitBehavior.AddDestination("west", room1.ID); ////exitBehavior.AddDestination("east", room1.ID); ////this.exit.BehaviorManager.Add(exitBehavior); this.room1.Add(this.exit); this.room2.Add(this.exit); // Populate the first room. this.room1.Add(this.witness); this.room1.Add(this.stalker1); this.room1.Add(this.stalker2); this.room1.Add(this.victim1); this.room1.Add(this.victim2); // Prepare to verify correct eventing occurs. this.witness.Eventing.MovementRequest += (root, e) => { this.lastWitnessRequest = e; }; this.witness.Eventing.MovementEvent += (root, e) => { this.lastWitnessEvent = e; }; this.stalker1.Eventing.MovementRequest += (root, e) => { this.lastStalkerRequest = e; }; this.stalker1.Eventing.MovementEvent += (root, e) => { this.lastStalkerEvent = e; }; this.stalker2.Eventing.MovementRequest += (root, e) => { this.lastStalkerRequest = e; }; this.stalker2.Eventing.MovementEvent += (root, e) => { this.lastStalkerEvent = e; }; this.victim1.Eventing.MovementRequest += (root, e) => { this.lastVictimRequest = e; }; this.victim1.Eventing.MovementEvent += (root, e) => { this.lastVictimEvent = e; }; this.victim2.Eventing.MovementRequest += (root, e) => { this.lastVictimRequest = e; }; this.victim2.Eventing.MovementEvent += (root, e) => { this.lastVictimEvent = e; }; }
public void Init() { // Create the basic actor instances and behavior for test. this.witnessThing = new Thing() { Name = "WitnessThing", ID = TestThingID.Generate("testthing") }; this.actingThing = new Thing() { Name = "ActingThing", ID = TestThingID.Generate("testthing") }; this.lockableThing = new Thing() { Name = "LockableThing", ID = TestThingID.Generate("testthing") }; this.locksUnlocksBehavior = new LocksUnlocksBehavior(); // Set up the actors inside another (which we'll call a "room" although it needn't actually be a room). this.room = new Thing() { Name = "Room", ID = TestThingID.Generate("room") }; this.room.Add(witnessThing); this.room.Add(actingThing); this.room.Add(lockableThing); // Prepare to verify correct eventing occurs. this.witnessThing.Eventing.MiscellaneousRequest += (root, e) => { this.lastWitnessRequest = e; }; this.witnessThing.Eventing.MiscellaneousEvent += (root, e) => { this.lastWitnessEvent = e; }; this.actingThing.Eventing.MiscellaneousRequest += (root, e) => { this.lastActorRequest = e; }; this.actingThing.Eventing.MiscellaneousEvent += (root, e) => { this.lastActorEvent = e; }; }
private void OnRequest(Func <ThingEventing, CancellableGameEventHandler> handlerSelector, CancellableGameEvent e, EventScope eventScope) { // Determine what layer(s) we're broadcasting to; beyond the first layer, these should all be to Children. switch (eventScope) { case EventScope.ParentsDown: // Send the request to each parent, until cancellation is noticed or we've finished. Queue <Thing> requestQueue = new Queue <Thing>(this.owner.Parents); while (requestQueue.Count > 0 && !e.IsCancelled) { Thing currentParent = requestQueue.Dequeue(); currentParent.Eventing.OnRequest(handlerSelector, e); } break; case EventScope.SelfDown: this.OnRequest(handlerSelector, e); break; default: throw new NotImplementedException(); } }
/// <summary> /// Shared code for request handling. /// </summary> /// <param name="handlerSelector">A function which returns the appropriate Handler for a given Thing.</param> /// <param name="e">The game event args to pass through.</param> private void OnRequest(Func <ThingEventing, CancellableGameEventHandler> handlerSelector, CancellableGameEvent e) { // Build a request target queue which starts with our owner Thing and visits all it's Children. // (This is a queue instead of recursion to help avoid stack overflows and such with very large object trees.) Queue <Thing> requestTargetQueue = new Queue <Thing>(); requestTargetQueue.Enqueue(this.owner); while (requestTargetQueue.Count > 0) { // If anything (like one of the thing's Behaviors) is subscribed to this request, send it there. Thing currentRequestTarget = requestTargetQueue.Dequeue(); var handler = handlerSelector(currentRequestTarget.Eventing); if (handler != null) { handler(currentRequestTarget, e); // If the event has been cancelled by the handler, we no longer need to look for further permission. if (e.IsCancelled) { break; } } // Enqueue all the current target's children for processing. foreach (Thing child in currentRequestTarget.Children) { requestTargetQueue.Enqueue(child); } } }
/// <summary> /// Shared code for request handling. /// </summary> /// <param name="handlerSelector">A function which returns the appropriate Handler for a given Thing.</param> /// <param name="e">The game event args to pass through.</param> private void OnRequest(Func<ThingEventing, CancellableGameEventHandler> handlerSelector, CancellableGameEvent e) { // Build a request target queue which starts with our owner Thing and visits all it's Children. // (This is a queue instead of recursion to help avoid stack overflows and such with very large object trees.) Queue<Thing> requestTargetQueue = new Queue<Thing>(); requestTargetQueue.Enqueue(this.owner); while (requestTargetQueue.Count > 0) { // If anything (like one of the thing's Behaviors) is subscribed to this request, send it there. Thing currentRequestTarget = requestTargetQueue.Dequeue(); var handler = handlerSelector(currentRequestTarget.Eventing); if (handler != null) { handler(currentRequestTarget, e); // If the event has been cancelled by the handler, we no longer need to look for further permission. if (e.IsCancelled) { break; } } // Enqueue all the current target's children for processing. foreach (Thing child in currentRequestTarget.Children) { requestTargetQueue.Enqueue(child); } } }
/// <summary> /// Raises the <see cref="CombatRequest"/> event. /// </summary> /// <param name="e">The <see cref="WheelMUD.Core.Events.CancellableGameEvent"/> instance containing the event data.</param> /// <param name="eventScope">The base target(s) to broadcast to, including their children.</param> public void OnCombatRequest(CancellableGameEvent e, EventScope eventScope) { Func<ThingEventing, CancellableGameEventHandler> handlerSelector = (t) => { return t.CombatRequest; }; this.OnRequest(handlerSelector, e, eventScope); }
/// <summary> /// Handle any requests this behavior is registered to. /// </summary> /// <param name="root">The root Thing where this event broadcast started.</param> /// <param name="e">The cancellable event/request arguments.</param> private void RequestHandler(Thing root, CancellableGameEvent e) { // Only cancel requestes to open our parent if it is currently locked. if (this.IsLocked) { var parent = this.Parent; if (parent != null) { // If this is a standard open request, find out if we need to cancel it. var openCloseEvent = e as OpenCloseEvent; if (openCloseEvent != null && openCloseEvent.IsBeingOpened && openCloseEvent.Target == this.Parent) { string message = string.Format("You cannot open {0} since it is locked!", this.Parent.Name); openCloseEvent.Cancel(message); } } } }
private void OnRequest(Func<ThingEventing, CancellableGameEventHandler> handlerSelector, CancellableGameEvent e, EventScope eventScope) { // Determine what layer(s) we're broadcasting to; beyond the first layer, these should all be to Children. switch (eventScope) { case EventScope.ParentsDown: // Send the request to each parent, until cancellation is noticed or we've finished. Queue<Thing> requestQueue = new Queue<Thing>(this.owner.Parents); while (requestQueue.Count > 0 && !e.IsCancelled) { Thing currentParent = requestQueue.Dequeue(); currentParent.Eventing.OnRequest(handlerSelector, e); } break; case EventScope.SelfDown: this.OnRequest(handlerSelector, e); break; default: throw new NotImplementedException(); } }
/// <summary> /// Clear all potentially tracked events so we can verify new ones. /// </summary> private void ClearTrackedEvents() { this.lastStalkerEvent = null; this.lastStalkerRequest = null; this.lastVictimEvent = null; this.lastVictimRequest = null; this.lastWitnessEvent = null; this.lastWitnessRequest = null; }
/// <summary> /// Clear all potentially tracked events so we can verify new ones. /// </summary> private void ClearTrackedEvents() { this.lastActorEvent = null; this.lastActorRequest = null; this.lastWitnessEvent = null; this.lastWitnessRequest = null; }
/// <summary>Raises the <see cref="CommunicationRequest"/> event.</summary> /// <param name="e">The <see cref="WheelMUD.Core.Events.CancellableGameEvent"/> instance containing the event data.</param> /// <param name="eventScope">The base target(s) to broadcast to, including their children.</param> public void OnCommunicationRequest(CancellableGameEvent e, EventScope eventScope) { this.OnRequest(t => t.CommunicationRequest, e, eventScope); }
/// <summary>Raises the <see cref="MiscellaneousRequest"/> event.</summary> /// <param name="e">The <see cref="WheelMUD.Core.Events.CancellableGameEvent"/> instance containing the event data.</param> /// <param name="eventScope">The base target(s) to broadcast to, including their children.</param> public void OnMiscellaneousRequest(CancellableGameEvent e, EventScope eventScope) { this.OnRequest(t => t.MiscellaneousRequest, e, eventScope); }
/// <summary>Raises the <see cref="MovementRequest"/> event.</summary> /// <param name="e">The <see cref="WheelMUD.Core.Events.CancellableGameEvent"/> instance containing the event data.</param> /// <param name="eventScope">The base target(s) to broadcast to, including their children.</param> public void OnMovementRequest(CancellableGameEvent e, EventScope eventScope) { this.OnRequest(t => t.MovementRequest, e, eventScope); }
/// <summary>Raises the <see cref="CombatRequest"/> event.</summary> /// <param name="e">The <see cref="WheelMUD.Core.Events.CancellableGameEvent"/> instance containing the event data.</param> /// <param name="eventScope">The base target(s) to broadcast to, including their children.</param> public void OnCombatRequest(CancellableGameEvent e, EventScope eventScope) { OnRequest(t => t.CombatRequest, e, eventScope); }
private void DenyCommunicationRequest(IThing root, CancellableGameEvent e) { var communicationRequest = e as VerbalCommunicationEvent; if (communicationRequest != null && communicationRequest.ActiveThing == this.Parent) { e.Cancel("You are currently muted."); } }
/// <summary> /// Raises the <see cref="MiscellaneousRequest"/> event. /// </summary> /// <param name="e">The <see cref="WheelMUD.Core.Events.CancellableGameEvent"/> instance containing the event data.</param> /// <param name="eventScope">The base target(s) to broadcast to, including their children.</param> public void OnMiscellaneousRequest(CancellableGameEvent e, EventScope eventScope) { Func <ThingEventing, CancellableGameEventHandler> handlerSelector = (t) => { return(t.MiscellaneousRequest); }; this.OnRequest(handlerSelector, e, eventScope); }
/// <summary>Called when a player is trying to log out, to raise the player log out request.</summary> /// <param name="player">The player.</param> /// <param name="e">The event arguments.</param> public static void OnPlayerLogOutRequest(Thing player, CancellableGameEvent e) { var eventHandler = GlobalPlayerLogOutRequest; if (eventHandler != null) { eventHandler(player.Parent, e); } }
/// <summary> /// Event handler for denying the changing of the parent of a Thing which has a WorldBehavior since World should be highest. /// </summary> /// <param name="sender">The sender of the event.</param> /// <param name="e">The event arguments.</param> private void DenyWorldParentChanges(Thing sender, CancellableGameEvent e) { if (e.ActiveThing == this.Parent) { var addChildRequest = e as AddChildEvent; if (addChildRequest != null) { addChildRequest.Cancel("World cannot become a child of anything."); } } }
/// <summary> /// Handle any movement requests. /// </summary> /// <param name="root">The root Thing where this event broadcast started.</param> /// <param name="e">The cancellable event/request arguments.</param> private void MovementRequestHandler(Thing root, CancellableGameEvent e) { // Only cancel movement requests through our parent if it is currently closed. if (!this.IsOpen) { var parent = this.Parent; if (parent != null) { // If this is a standard movement request, find out if we need to cancel it. var movementEvent = e as MovementEvent; if (movementEvent != null && movementEvent.GoingVia == this.Parent) { // @@@ TODO: If the actor also cannot perceive our parent properly, perhaps broadcast // a sensory event like "Dude blindly ran into a door." string message = string.Format("You cannot move through {0} since it is closed!", this.Parent.Name); movementEvent.Cancel(message); } } } }
private void Parent_MovementRequest(Thing root, CancellableGameEvent e) { // @@@ TODO: When our parent Thing gets an Arrive request (such as when a thing is attempting to enter an // enterable portal), we want to cancel the event and replace it with our own movement request to enter the // portal's target location. }
/// <summary> /// Intercepts and cancels a movement request for the wielded item. /// This way a player will not accidentally drop a wielded weapon, etc. /// </summary> /// <param name="root">The root.</param> /// <param name="e">The event.</param> private void Eventing_MovementRequest(Thing root, CancellableGameEvent e) { var evt = e as ChangeOwnerEvent; if (evt != null) { if (evt.Thing.ID == this.itemToWield.ID) { evt.Cancel(string.Format("The {0} is still wielded!", this.itemToWield.Name)); } } }