public override ProgrammingElement Clone() { OnceModifier clone = new OnceModifier(); CopyTo(clone); return(clone); }
/// <summary> /// This is called on every update cycle to have this actuator apply its output to its target /// </summary> /// <param name="gameActor"></param> public void Update(Reflex reflex) { // Stun disables actuators if (reflex.Task.Brain.Stunned) { return; } // Avoid recursion into this function if (actuatorUpdateDepth > 0) { return; } actuatorUpdateDepth += 1; double currTime = Time.GameTimeTotalSeconds; if (currTime >= lastTriggerTime + timerDelaySeconds) { if (ActuatorUpdate(reflex)) { lastTriggerTime = currTime; } else { // For some reason we weren't able to do the action. So, // if this reflex has a once modifier, decrement it so // we'll try again. // The only case where I know this currently happens is when // a bot tries to display a fullscreen "say" verb when it's // already displaying another. This allows multiple fullscreen // says to be displayed sequentially. for (int i = 0; i < reflex.Modifiers.Count; i++) { if (reflex.Modifiers[i].upid == "modifier.once") { OnceModifier om = reflex.Modifiers[i] as OnceModifier; om.Fired = false; } } } } actuatorUpdateDepth -= 1; }
/// <summary> /// /// </summary> /// <param name="reflex"></param> /// <param name="param"></param> /// <returns>Return true if the MouseFilter passes. Ignoring the other filters.</returns> public override bool MatchAction(Reflex reflex, out object param) { bool result = IsPressed; // Return as a parameter a vector that can be used for input to the movement system, so // that players can drive and turn bots using mouse buttons. param = new Vector2(0, 0); // Only set the mouse position onto the reflex if the filter actually passes. if (result) { // If we have a Once modifier, clear it on mouse down. if (wasPressed) { for (int i = 0; i < reflex.Modifiers.Count; i++) { OnceModifier om = reflex.Modifiers[i] as OnceModifier; if (om != null) { om.Reset(reflex); } } } if (type == MouseFilterType.Move) { // This is poorly named. What this is doing is not mouse movement but // instead working with a normalized version of the mouse position in // screenspace. // Screen space mouse position, don't care about world space position // or what mouse is over. // Get change in mouse position. Vector2 pos = new Vector2(MouseInput.Position.X, MouseInput.Position.Y); // Rescale and clamp into [-1,1] range. // Scale to 0,1 range pos.X /= BokuGame.bokuGame.GraphicsDevice.Viewport.Width; pos.Y /= BokuGame.bokuGame.GraphicsDevice.Viewport.Height; // Transform from 0,1 to -1,1 pos.X = pos.X * 2.0f - 1.0f; pos.Y = pos.Y * 2.0f - 1.0f; // Clamp pos.X = MathHelper.Clamp(pos.X, -1.0f, 1.0f); pos.Y = MathHelper.Clamp(-pos.Y, -1.0f, 1.0f); // Negate so positive is up. screenPosition = pos; param = pos; } else { bool meFilter = reflex.Data.FilterExists("filter.me"); if (MouseEdit.HitInfo.ActorHit != null) { // If this reflex uses the movement actuator then totally ignore clicks on self. This // allows us to still use clicks on self to change state w/o overwriting movement target. if (!(reflex.IsMovement && MouseEdit.HitInfo.ActorHit == reflex.Task.GameActor)) { // At this point we need to peek at the filters and look for a MeFilter. We just use // this to decide what to put into the MousePosition and MouseActor fields. The real // filtering will be done in the sensor. if (!meFilter || MouseEdit.HitInfo.ActorHit == reflex.Task.GameActor) { reflex.MousePosition = MouseEdit.HitInfo.ActorPosition; reflex.MouseActor = MouseEdit.HitInfo.ActorHit; param = new Vector2(MouseEdit.HitInfo.ActorPosition.X, MouseEdit.HitInfo.ActorPosition.Y); } } } else { if (!meFilter) { reflex.MousePosition = MouseEdit.HitInfo.TerrainPosition; reflex.MouseActor = null; param = new Vector2(MouseEdit.HitInfo.TerrainPosition.X, MouseEdit.HitInfo.TerrainPosition.Y); } } } } // Don't hold onto a ref to a dead bot. if (reflex.MouseActor != null && reflex.MouseActor.CurrentState == GameThing.State.Inactive) { reflex.MouseActor = null; reflex.MousePosition = null; } return(result); }
protected void CopyTo(OnceModifier clone) { base.CopyTo(clone); }
private void RunActuators() { verbExecutions.SetAll(false); GameActor.Movement.UserControlled = IsUserControlled; // Do not update actuators during pre-game. if (InGame.inGame.PreGameActive) { return; } int initialTaskId = Brain.ActiveTaskId; for (int i = 0; i < reflexes.Count; ++i) { Reflex reflex = reflexes[i] as Reflex; if (reflex.Actuator != null && reflex.targetSet.AnyAction) { if (reflex.Actuator is VerbActuator) { // Ugh, be backward compatible with the old arbitrated verb behavior. VerbActuator verbAct = reflex.Actuator as VerbActuator; // If the verb is exclusive AND we've already seen in then don't process it. if (GameThing.VerbIsExclusive(verbAct.Verb) && verbExecutions.Get((int)verbAct.Verb)) { continue; } else { // This is the first time we've seen the verb so flag it. verbExecutions.Set((int)verbAct.Verb, true); } } // If we have a mouse sensor AND a once modifier then // we want to tag the mouse button with IgnoreUntilReleased. // This makes once work correctly without blocking other // reflexes from seeing the mouse. if (reflex.Sensor is MouseSensor) { OnceModifier om = null; for (int j = 0; j < reflex.Modifiers.Count; j++) { om = reflex.Modifiers[j] as OnceModifier; if (om != null) { break; } } if (om != null) { MouseFilter mf = null; for (int j = 0; j < reflex.Filters.Count; j++) { mf = reflex.Filters[j] as MouseFilter; if (mf != null) { break; } } if (mf != null) { // By setting IgnoreUntilReleased, this prevents another // reflex from being triggered until the mouse is released. switch (mf.type) { case MouseFilterType.LeftButton: MouseInput.Left.IgnoreUntilReleased = true; break; case MouseFilterType.RightButton: MouseInput.Right.IgnoreUntilReleased = true; break; default: // Nothing to see here, move along. break; } } } } reflex.Actuator.Update(reflex); // Stop updating actuators if we switched pages. if (Brain.ActiveTaskId != initialTaskId) { break; } } } }
/// <summary> /// /// </summary> /// <param name="reflex"></param> /// <param name="param"></param> /// <returns>Return true if the TouchGestureFilter passes. Ignoring the other filters.</returns> public override bool MatchAction(Reflex reflex, out object param) { // Based on gesture type, we check if the gesture has been recognized/performed this frame to see // if this filter may have something to do! bool result = IsPerformed; // ** UNUSED ** // Return as a parameter a vector that can be used for input to the movement system, so // that players can drive and turn bots using mouse buttons. // The touch filters don't have a use for this parameter at this time. param = null; // Did the gesture just begin this frame? Useful for 'once' filters and such. wasPerformed = WasPerformed; if (result) { // If we have a Once modifier, clear it on wasPerformed if (wasPerformed) { for (int i = 0; i < reflex.Modifiers.Count; i++) { OnceModifier om = reflex.Modifiers[i] as OnceModifier; if (om != null) { om.Reset(reflex); } } } // Set the touch position and touch actor based on TouchEdit data and // whether we've hit an actor or not. bool meFilter = reflex.Data.FilterExists("filter.me"); if (TouchEdit.HitInfo.ActorHit != null) { reflex.TouchPosition = TouchEdit.HitInfo.ActorPosition; reflex.TouchActor = TouchEdit.HitInfo.ActorHit; } else { reflex.TouchActor = null; if (!meFilter) { reflex.TouchPosition = TouchEdit.HitInfo.TerrainPosition; } else { reflex.TouchPosition = null; } } // Gesture-type specific behavior goes here. if (type == TouchGestureFilterType.Rotate) { deltaRotation = TouchGestureManager.Get().RotateGesture.RotationDelta; } else if (type == TouchGestureFilterType.Swipe) { direction = TouchGestureManager.Get().SwipeGesture.SwipeDirection; } else if (type == TouchGestureFilterType.Slide) { // Slide is unique in that it cares about what actor you began the slide on, not where // you are now. The touch position is your current touch position, however. // Here we override the TouchActor set above. reflex.TouchPosition = TouchEdit.HitInfo.TerrainPosition; reflex.TouchActor = TouchInput.InitialActorHit; } else if (type == TouchGestureFilterType.Tap) { tapPosition = TouchGestureManager.Get().TapGesture.Position; } else if (type == TouchGestureFilterType.Touching) { } } // Don't hold onto a ref to a dead bot. if (reflex.TouchActor != null && reflex.TouchActor.CurrentState == GameThing.State.Inactive) { reflex.TouchActor = null; reflex.TouchPosition = null; } return(result); }