public override ActionSet ComposeActionSet(Reflex reflex, GameActor gameActor) { ClearActionSet(actionSet); UpdateCanBlend(reflex); if (!reflex.targetSet.AnyAction) { return(actionSet); } if (reflex.targetSet.Count > 0) { if (reflex.targetSet.CullToFurthest(gameActor, BlockedFrom)) { // the targetSet is in order by distance SensorTarget target = reflex.targetSet.Furthest; // calculate a vector toward target Vector3 value = target.Direction; bool apply = reflex.ModifyHeading(gameActor, Modifier.ReferenceFrames.World, ref value); if (apply) { // radius should be from object actionSet.AddAttractor(AllocAttractor(target.Range, value, target.GameThing, reflex), 0.4f); } } } return(actionSet); }
public override ActionSet ComposeActionSet(Reflex reflex, GameActor gameActor) { ClearActionSet(actionSet); UpdateCanBlend(reflex); if (!reflex.targetSet.AnyAction) { return(actionSet); } SensorTarget target = reflex.targetSet.Nearest; if (target != null) { // Calculate a vector toward target. Vector3 value = target.Direction; bool apply = reflex.ModifyHeading(gameActor, Modifier.ReferenceFrames.World, ref value); if (apply) { actionSet.AddAction(Action.AllocTargetLocationAction(reflex, target.Position, autoTurn: true)); } } return(actionSet); }
public override void ComposeSensorTargetSet(GameActor gameActor, Reflex reflex) { List <Filter> filters = reflex.Filters; SensorTargetSet.Enumerator senseSetIter = (SensorTargetSet.Enumerator)gameActor.GivenSet.GetEnumerator(); senseSetIter.Reset(); while (senseSetIter.MoveNext()) { SensorTarget target = (SensorTarget)senseSetIter.Current; bool match = true; for (int indexFilter = 0; indexFilter < filters.Count; indexFilter++) { Filter filter = filters[indexFilter] as Filter; if (!filter.MatchTarget(reflex, target)) { match = false; break; } } if (match) { reflex.targetSet.Add(target); } } reflex.targetSet.Action = TestObjectSet(reflex); }
public static void Free(SensorTarget target) { target.refs--; Debug.Assert(target.refs == 0); target.Clear(); spareSensorTargets.Add(target); }
public override bool MatchAction(Reflex reflex, out object param) { param = null; bool match = false; // Do we have enough targets to even bother? if (reflex.targetSet.NearestTargets.Count > count) { for (int i = 0; i < reflex.targetSet.NearestTargets.Count - count; i++) { // Start with the cluster containing just the current element. cluster.Clear(); cluster.Add(reflex.targetSet.NearestTargets[i]); // For each of the remaining elements, see if they are near enough // to cluster with any of the elements already in the cluster. for (int j = i + 1; j < reflex.targetSet.NearestTargets.Count; j++) { SensorTarget target = reflex.targetSet.NearestTargets[j]; foreach (SensorTarget clusterElement in cluster) { float dist = (target.Position - clusterElement.Position).Length(); float range = 2.0f * (target.GameThing.BoundingSphere.Radius + clusterElement.GameThing.BoundingSphere.Radius); if (dist < range) { cluster.Add(target); break; } } } // Did we find a cluster? if (cluster.Count > count) { match = true; // Change targetSet.NearestTargets to just hold the cluster. reflex.targetSet.NearestTargets.Clear(); foreach (SensorTarget target in cluster) { reflex.targetSet.NearestTargets.Add(target); } break; } } // end of outer loop over elements. } // if we have enough elements to form a cluster. // Not strictly needed but it does prevent refs being held longer than needed. cluster.Clear(); return(match); } // end of MatchAction()
public override void ComposeSensorTargetSet(GameActor gameActor, Reflex reflex) { List <Filter> filters = reflex.Filters; // add normal sightSet of items to the targetset // senseSetIter.Reset(); while (senseSetIter.MoveNext()) { SensorTarget target = (SensorTarget)senseSetIter.Current; bool match = true; bool cursorFilterPresent = false; for (int indexFilter = 0; indexFilter < filters.Count; indexFilter++) { Filter filter = filters[indexFilter] as Filter; ClassificationFilter cursorFilter = filter as ClassificationFilter; if (cursorFilter != null && cursorFilter.classification.IsCursor) { cursorFilterPresent = true; } if (!filter.MatchTarget(reflex, target)) { match = false; break; } } if (match) { if (!target.Classification.IsCursor || cursorFilterPresent) { reflex.targetSet.Add(target); } } } if (ListeningForMusic(filters)) { if (HearMusic(filters)) { SensorTarget sensorTarget = SensorTargetSpares.Alloc(); sensorTarget.Init(gameActor, Vector3.UnitZ, 0.0f); reflex.targetSet.AddOrFree(sensorTarget); } } reflex.targetSet.Action = TestObjectSet(reflex); if (reflex.targetSet.Action) { foreach (SensorTarget targ in reflex.targetSet) { gameActor.AddSoundLine(targ.GameThing); } } }
/// <summary> /// Remove all SensorTargets referencing 'thing' /// </summary> /// <param name="dropThing"></param> public void Remove(GameThing thing) { if (sensorTargets.ContainsKey(thing.UniqueNum)) { SensorTarget target = sensorTargets[thing.UniqueNum]; sensorTargets.Remove(thing.UniqueNum); target.UnRef(); dirty = true; } }
public override bool MatchTarget(Reflex reflex, SensorTarget sensorTarget) { //if ((sensorCategory & Sensor.Category.Distance) != 0) { float range = GetRangeFromTweakSettings(reflex.Task.GameActor); bool match = OperandCompare <float>(sensorTarget.Range, this.operand, range); return(match); } //return true; // not the right type, don't effect the filtering }
public override bool MatchTarget(Reflex reflex, SensorTarget sensorTarget) { // When checking a touchButton filter, the target no longer has a valid position, because // technically the button has no real place in the gameworld. We thus strip that data // from the target. sensorTarget.Position = sensorTarget.GameThing.Movement.Position; sensorTarget.Range = 0.0f; sensorTarget.Direction = Vector3.Zero; return(true); }
public override void FinishUpdate(GameActor gameActor) { if (gameActor.ThingBeingHeldByThisActor != null) { // presence is only thing important here SensorTarget target = SensorTargetSpares.Alloc(); target.Init(gameActor, gameActor.ThingBeingHeldByThisActor); senseSet.AddOrFree(target); } }
public override void ComposeSensorTargetSet(GameActor gameActor, Reflex reflex) { List <Filter> filters = reflex.Filters; // add normal senseSet of items to the targetset // senseSetIter.Reset(); while (senseSetIter.MoveNext()) { SensorTarget target = (SensorTarget)senseSetIter.Current; bool match = true; bool cursorFilterPresent = false; for (int indexFilter = 0; indexFilter < filters.Count; indexFilter++) { Filter filter = filters[indexFilter] as Filter; ClassificationFilter cursorFilter = filter as ClassificationFilter; if (cursorFilter != null && cursorFilter.classification.IsCursor) { cursorFilterPresent = true; } if (!filter.MatchTarget(reflex, target)) { match = false; break; } } if (match) { if (!target.Classification.IsCursor || cursorFilterPresent) { reflex.targetSet.Add(target); } } } reflex.targetSet.Finialize(); if (reflex.targetSet.Nearest == null) { /// Didn't come up with anything, try searching our memory if (SearchMemory(gameActor, reflex)) { /// Find nearest again, but don't check LOS. This matches old /// behavior, which assumes that if we remember it, we could see it. reflex.targetSet.Finialize(); } } else { /// We got something, memorize it. gameActor.Brain.Memory.MemorizeThing(reflex.targetSet.Nearest.GameThing); } reflex.targetSet.Action = TestObjectSet(reflex); } // end of ComposeSensorTargetSet()
public override void ComposeSensorTargetSet(GameActor gameActor, Reflex reflex) { List <Filter> filters = reflex.Filters; foreach (SensorTarget target in sightSet) { // Don't see things we are holding. if (target.GameThing == gameActor.ThingBeingHeldByThisActor) { continue; } bool match = true; bool cursorFilterPresent = false; for (int indexFilter = 0; indexFilter < filters.Count; indexFilter++) { Filter filter = filters[indexFilter] as Filter; ClassificationFilter cursorFilter = filter as ClassificationFilter; if (cursorFilter != null && cursorFilter.classification.IsCursor) { cursorFilterPresent = true; } if (!filter.MatchTarget(reflex, target)) { match = false; break; } } if (match) { if (!target.Classification.IsCursor || cursorFilterPresent) { reflex.targetSet.Add(target); } } } reflex.targetSet.Action = TestObjectSet(reflex); if (reflex.targetSet.Action) { SensorTarget nearest = reflex.targetSet.Nearest; if (nearest != null) { gameActor.AddSightLine(nearest.GameThing); } } else { reflex.targetSet.Clear(); } } // end of ComposeSensorTargetSet()
public bool Add(SensorTarget sensorTarget) { if (sensorTargets.ContainsKey(sensorTarget.GameThing.UniqueNum)) { return(false); } sensorTargets.Add(sensorTarget.GameThing.UniqueNum, sensorTarget.Ref()); dirty = true; return(true); }
public void Add(GameThing gameThing, Vector3 direction, float range) { if (sensorTargets.ContainsKey(gameThing.UniqueNum)) { return; } SensorTarget target = SensorTargetSpares.Alloc(); target.Init(gameThing, direction, range); sensorTargets.Add(gameThing.UniqueNum, target.Ref()); dirty = true; }
/// <summary> /// Try adding to the set, if unsuccessful, free the SensorTarget. /// This is a shortcut for when you've just Alloc'd a sensor target, /// and then: /// if(!Add(targ)) /// SensorTargetSpares.Release(targ); /// This is only appropriate where the target has just been alloc'd, so /// not iterating through a set, and is a local that will just fall out of scope. /// </summary> /// <param name="sensorTarget"></param> /// <returns>false if not added but freed, true if added</returns> public bool AddOrFree(SensorTarget sensorTarget) { Debug.Assert(sensorTarget.refs == 1, "Improper usage, use Add()?"); if (!Add(sensorTarget)) { if (sensorTarget.refs == 1) { SensorTargetSpares.Free(sensorTarget); } return(false); } return(true); }
public override bool MatchTarget(Reflex reflex, SensorTarget sensorTarget) { Vector3 actorPos = reflex.Task.GameActor.Movement.Position; actorPos.Z += reflex.Task.GameActor.EyeOffset; Vector3 actorFacing = reflex.Task.GameActor.Movement.Heading; Vector3 actorRight = Vector3.Cross(actorFacing, Vector3.UnitZ); Vector3 targetPos = sensorTarget.Position; if (sensorTarget.GameThing != null) { targetPos.Z += sensorTarget.GameThing.EyeOffset; } Vector3 toTarget = targetPos - actorPos; bool match = true; switch (upid) { case "filter.infront": match = Vector3.Dot(actorFacing, toTarget) >= 0; break; case "filter.behind": match = Vector3.Dot(actorFacing, toTarget) <= 0; break; case "filter.toleft": match = Vector3.Dot(actorRight, toTarget) <= 0; break; case "filter.toright": match = Vector3.Dot(actorRight, toTarget) >= 0; break; case "filter.over": match = toTarget.Z > 0; break; case "filter.under": match = toTarget.Z < 0; break; case "filter.lineofsight": Vector3 hit = Vector3.Zero; match = !Terrain.LOSCheckTerrainAndPath(actorPos, targetPos, ref hit); break; } return(match); }
/// <summary> /// Either sorts the full target list or just grabs the nearest target. /// Dependson whether this is called by Nearest or NearestTargets. /// </summary> /// <returns></returns> private void SortTargets(bool justGetFirst) { if (dirty) { nearestTargets.Clear(); // Copy all non-ignored targets to list. foreach (SensorTarget target in sensorTargets.Values) { if (target.GameThing != null || !target.GameThing.Ignored) { nearestTargets.Add(target); } } if (justGetFirst) { // Find the nearest target and copy into position 0. // This leaves the nearest target at position 0 but // leaves the rest of the list in kind of a mess so // don't use it for anything else. for (int i = 1; i < nearestTargets.Count; i++) { if (nearestTargets[0].Range > nearestTargets[i].Range) { nearestTargets[0] = nearestTargets[i]; } } } else { // Sort full list. Rarely used and the general case // will be a very short list so just bubble sort. for (int i = 0; i < nearestTargets.Count - 1; i++) { for (int j = i + 1; j < nearestTargets.Count; j++) { if (nearestTargets[i].Range > nearestTargets[j].Range) { // Swap. SensorTarget tmp = nearestTargets[i]; nearestTargets[i] = nearestTargets[j]; nearestTargets[j] = tmp; } } } } dirty = false; } // end if dirty } // end of SortTargets()
public override bool MatchTarget(Reflex reflex, SensorTarget sensorTarget) { bool result = false; // Try matching each line. for (int i = 0; i < reflex.Data.saidStrings.Count; i++) { bool atBeginning = reflex.Data.saidMode == 0; if (SaidStringManager.MatchText(sensorTarget.GameThing as GameActor, reflex.Data.saidStrings[i], atBeginning)) { result = true; break; } } return(result); }
} // end of c'tor public override bool MatchTarget(Reflex reflex, SensorTarget sensorTarget) { bool matched = false; if (sensorTarget.GameThing is NullActor) { return(matched); // Always false. } GameActor actor = sensorTarget.GameThing as GameActor; if (actor != null && actor.DisplayName == name) { matched = true; } return(matched); } // end of MatchTarget()
public static SensorTarget Alloc() { SensorTarget target; if (spareSensorTargets.Count > 0) { int index = spareSensorTargets.Count - 1; target = spareSensorTargets[index]; spareSensorTargets.RemoveAt(index); } else { target = new SensorTarget(); } target.refs++; return(target); }
public override void FinishUpdate(GameActor gameActor) { if (terrainSensor != null) { //if (TouchEdit.HitInfo.TerrainHit) { terrainSensor.OverrideSenseMaterial = TouchEdit.HitInfo.TerrainMaterial; } terrainSensor.FinishUpdate(gameActor); } else { if (TouchEdit.HitInfo.HaveActor) { GameActor touchdActor = TouchEdit.HitInfo.ActorHit; Vector3 actorCenter = Vector3.Transform( gameActor.BoundingSphere.Center, gameActor.Movement.LocalMatrix); Vector3 thingCenter = Vector3.Transform( touchdActor.BoundingSphere.Center, touchdActor.Movement.LocalMatrix); Vector3 direction = thingCenter - actorCenter; float range = direction.Length(); if (range > 0.0f) { direction *= 1.0f / range; // Normalize. } SensorTarget target = SensorTargetSpares.Alloc(); target.Init(touchdActor, direction, range); senseSet.AddOrFree(target); } senseSet.Add(NullActor.Instance, Vector3.Zero, float.MaxValue); } }
public override void ComposeSensorTargetSet(GameActor gameActor, Reflex reflex) { List <Filter> filters = reflex.Filters; SensorTargetSet.Enumerator beamedSetIter = gameActor.BeamedSetIter; beamedSetIter.Reset(); while (beamedSetIter.MoveNext()) { SensorTarget target = (SensorTarget)beamedSetIter.Current; bool match = true; bool cursorFilterPresent = false; for (int indexFilter = 0; indexFilter < filters.Count; indexFilter++) { Filter filter = filters[indexFilter] as Filter; ClassificationFilter cursorFilter = filter as ClassificationFilter; if (cursorFilter != null && cursorFilter.classification.IsCursor) { cursorFilterPresent = true; } if (!filter.MatchTarget(reflex, target)) { match = false; break; } } if (match) { if (!target.Classification.IsCursor || cursorFilterPresent) { reflex.targetSet.Add(target); } } } reflex.targetSet.Action = TestObjectSet(reflex); }
public override SensorTargetSet ComposeSensorTargetSet(GameActor gameActor, Reflex reflex) { List <Filter> filters = reflex.Filters; targetSet.Clear(); for (int iSet = 0; iSet < heardSet.Count; iSet++) { bool match = true; bool cursorFilterPresent = false; SensorTarget target = heardSet[iSet]; for (int indexFilter = 0; indexFilter < filters.Count; indexFilter++) { Filter filter = filters[indexFilter] as Filter; ClassificationFilter cursorFilter = filter as ClassificationFilter; if (cursorFilter != null && cursorFilter.classification.IsCursor) { cursorFilterPresent = true; } if (!filter.MatchTarget(reflex, target, this.category)) { match = false; break; } } if (match) { if (!target.Classification.IsCursor || cursorFilterPresent) { targetSet.Add(target.Ref()); } } } targetSet.Finialize(); targetSet.Action = TestObjectSet(reflex); return(targetSet); }
public int CompareTo(Object right) { if (right is SensorTarget) { SensorTarget rightTarget = right as SensorTarget; int result = 0; if (range < rightTarget.range) { result = -1; } else if (range > rightTarget.range) { result = 1; } else { result = gameThing.CompareTo(rightTarget.gameThing); } return(result); } throw new ArgumentException("object is not a SensorTarget"); }
public override bool MatchTarget(Reflex reflex, SensorTarget sensorTarget) { return(false); }
public override ActionSet ComposeActionSet(Reflex reflex, GameActor gameActor) { ClearActionSet(actionSet); UpdateCanBlend(reflex); if (!reflex.targetSet.AnyAction) { return(actionSet); } Vector3 direction = Vector3.Zero; // This is either the direction to the nearest target or, if no target, the direction we want (forward, etc). GameThing gameThing = null; float range = 0.0f; // TODO (****) This was causing a null ref in the "Green Ghost V Looper" level // when the user pressed the mouse button to launch a wisp. In that case the // targetSet has 1 element in it but it's not "valid" so it never goes into // the nearestTargets list, hence targetSet.Nearest is null. // Note I also pulled the Finalize call out of the if statement since Finialize(sic) // is what creates the nearestTargets list. // Still need to investigate the underlying cause. // Turns out to be an issue with Ghost. Ghosted objects are "ignored" so not valid // for the Nearest list. Should probably rethink how invisible and ghosted work. if (reflex.targetSet.Nearest != null && !(reflex.targetSet.Nearest.GameThing is NullActor)) { // We have a "real" target. // The targetSet is in order by distance. // Pick the nearest member of the target set. SensorTarget target = reflex.targetSet.Nearest; direction = target.Direction; gameThing = target.GameThing; range = target.Range; } else { // No explicit target. // This handles the case of WHEN GamePad AButton DO Shoot // where instead of having a target we just have a direction. if (reflex.targetSet.Param != null && reflex.targetSet.Param is Vector2) { direction = new Vector3((Vector2)reflex.targetSet.Param, 0.0f); } else { direction = Vector3.Zero; } gameThing = null; range = 1.0f; } bool apply = reflex.ModifyHeading(gameActor, Modifier.ReferenceFrames.World, ref direction); if (apply) { // TODO (****) Probably need a TargetObject Action. // radius should be from object actionSet.AddActionTarget(Action.AllocAttractor(range, direction, gameThing, reflex), 0.4f); } return(actionSet); }
public override bool MatchTarget(Reflex reflex, SensorTarget sensorTarget) { return(true); // not the right type, don't effect the filtering }
public override bool MatchTarget(Reflex reflex, SensorTarget sensorTarget) { bool match = sensorTarget.GameThing.CurrentState == GameThing.State.Dead || sensorTarget.GameThing.PendingState == GameThing.State.Dead; return(match); }
public override void ComposeSensorTargetSet(GameActor gameActor, Reflex reflex) { if (terrainSensor != null) { terrainSensor.ComposeSensorTargetSet(gameActor, reflex); } else { List <Filter> filters = reflex.Filters; // The sensor will use the first TouchGestureFilter it finds. Since any given reflex // can only have a single one of these, this works well. TouchGestureFilter gestureFilter = null; TouchButtonFilter buttonFilter = null; GUIButtonFilter guiButtonFilter = null; for (int i = 0; i < filters.Count; i++) { if (filters[i] is TouchGestureFilter) { Debug.Assert(null == gestureFilter); gestureFilter = filters[i] as TouchGestureFilter; } if (filters[i] is TouchButtonFilter) { Debug.Assert(null == buttonFilter); buttonFilter = filters[i] as TouchButtonFilter; } if (filters[i] is GUIButtonFilter) { Debug.Assert(null == guiButtonFilter); guiButtonFilter = filters[i] as GUIButtonFilter; } } //if we don't have a filter, do nothing if (null == gestureFilter && null == buttonFilter && null == guiButtonFilter) { //Debug.Assert(false, "Did not find a touch filter for touch sensor."); return; } // Cause the filter to detect what is under the touch cursor and set that information on the reflex. // MatchAction will be true if the TouchFilter passes but then we still need to filter on any other // filters including the ever annoying "not", "me" and "anything" filters. Object param = null; bool matchAction = false; bool notFilter = reflex.Data.FilterExists("filter.not"); bool anythingFilter = reflex.Data.FilterExists("filter.anything"); if (gestureFilter != null) { matchAction = gestureFilter.MatchAction(reflex, out param); } if (buttonFilter != null) { // Make the actual on screen button visible if a reflex contains the touch button filter. //TouchButtons.MakeVisible(buttonFilter.button); matchAction = buttonFilter.MatchAction(reflex, out param); } if (guiButtonFilter != null) { matchAction = guiButtonFilter.MatchAction(reflex, out param); } // Give the anythingFilter a chance to kill the action. if (anythingFilter && reflex.TouchActor == null) { matchAction = false; } // Handle the "Not" filter if (notFilter) { if (matchAction) { matchAction = false; reflex.TouchActor = null; reflex.TouchPosition = null; } else { matchAction = true; } } bool touchCursorTarget = false; // We are moving towards a remembered target position if we're the movement actuator. // We do not require a match on the current frame to continue the movement. // Note, in the presence of a "Not" filter, there is no target to "not move" to, so this // is negated. // Also, support turning toward a remembered position. bool movingToTouchPos = (reflex.actuatorUpid == "actuator.movement" && !notFilter); movingToTouchPos |= (reflex.actuatorUpid == "actuator.turn" && !notFilter); if (movingToTouchPos && (reflex.TouchActor == reflex.Task.GameActor)) { // When moving with touch, going towards oneself doesn't make sense. By discarding // the touch actor and using the terrain position, we have a better definition of this // movement. This allows for small positional corrections around the target's bounding // box as well as letting slide movements that begin on oneself to work. reflex.TouchActor = null; reflex.TouchPosition = TouchEdit.HitInfo.TerrainPosition; } if (matchAction || movingToTouchPos) { bool validTarget = false; SensorTarget target = SensorTargetSpares.Alloc(); // If we have an actor touch target, check if it passes the filters. // If not, null it out. if (reflex.TouchActor != null) { // Create a target. target.Init(reflex.Task.GameActor, reflex.TouchActor); validTarget = true; } else { target.Init(reflex.Task.GameActor, reflex.Task.GameActor); // If we've got a me filter and not TouchActor we've failed. if (reflex.Data.FilterExists("filter.me")) { matchAction = false; } // NOTE: For classification purposes, if the user doesn't touch a particular actor, // we create an 'empty' classification. This is because we need a classification object // in order to do reflexes such as 'tap move blimp -> shoot'. If you don't tap an actor, // it needs to compare the absence of an actor to the blimp. if (reflex.TouchPosition != null) { // We need to add the touch position to the targetSet. target.Classification = new Classification(); target.GameThing = senseSet.Nearest.GameThing; target.Position = reflex.TouchPosition.Value; target.Direction = target.Position - reflex.Task.GameActor.Movement.Position; target.Range = target.Direction.Length(); // If we've arrived at the target position, clear MousePosition. Vector2 dir2d = new Vector2(target.Direction.X, target.Direction.Y); if (dir2d.LengthSquared() < 0.1f) { reflex.TouchPosition = null; } target.Direction /= target.Range; touchCursorTarget = true; validTarget = true; } else { // We don't have an actor or a position. Only with an action match should we // create a sensor target. if (matchAction) { // Calc a fake position for this target. GameActor actor = reflex.Task.GameActor; Vector3 pos = actor.Movement.Position; target.Classification = new Classification(); target.GameThing = senseSet.Nearest.GameThing; target.Position = pos; target.Direction = target.Position - reflex.Task.GameActor.Movement.Position; target.Range = target.Direction.Length(); target.Direction /= target.Range; validTarget = true; } } } // Test the target against the filters. if (validTarget) { for (int i = 0; i < filters.Count; i++) { if (!(filters[i] is TouchGestureFilter)) { if (!filters[i].MatchTarget(reflex, target) || !filters[i].MatchAction(reflex, out param)) { if (!notFilter) { // Failed a match on one of the filters and we don't have a negation // so null things out and short circuit. reflex.TouchActor = null; validTarget = false; matchAction = false; touchCursorTarget = false; break; } } } } } // If we still have a target, add it to the target set. if (validTarget) { reflex.targetSet.Add(target); } else { // Don't really need this target so free it. SensorTargetSpares.Free(target); } } reflex.targetSet.Action = reflex.targetSet.Count > 0; // && TestObjectSet(reflex); //reflex.targetSet.Action |= matchAction; // This forces the movement to keep going toward the clicked position/bot // even if the touch is no longer clicked. reflex.targetSet.ActionMouseTarget = touchCursorTarget; if (matchAction) { bool postProcessCheck = PostProcessAction(matchAction, reflex); if (!postProcessCheck) { // We matched the action, but it failed the post process check (used by "Once" modifier), // so we clear the target set. reflex.targetSet.Clear(); } } } }
public override bool MatchTarget(Reflex reflex, SensorTarget sensorTarget) { if (sensorTarget.GameThing is NullActor) { return(false); } bool match = true; // By default, don't filter. // Skip if no sensor category if (MatchType != ClassificationType.None) { switch (MatchType) { case ClassificationType.Object: if (string.IsNullOrEmpty(classification.name)) { match = true; } else if (classification.name == "bot") // Handle "Any Bots" tile. { GameActor actor = sensorTarget.GameThing as GameActor; if (actor == null || !actor.IsBot) { match = false; } } else if (classification.name == "building") // Handle "Any Building" tile. { GameActor actor = sensorTarget.GameThing as GameActor; if (actor == null || !actor.IsBuilding) { match = false; } } else { match = classification.name == sensorTarget.Classification.name; } break; case ClassificationType.Color: match = classification.color == sensorTarget.Classification.color || classification.color == sensorTarget.Classification.glowColor; break; case ClassificationType.PathColor: //path color only matches if the color matches the last end of path color this actor has seen if (sensorTarget.GameThing is GameActor) { match = classification.color == (sensorTarget.GameThing as GameActor).ReachedEOP; } else { match = false; } break; case ClassificationType.Expression: match = (classification.expression != Boku.SimWorld.Face.FaceState.NotApplicable && classification.expression == sensorTarget.Classification.expression) || (classification.emitter != ExpressModifier.Emitters.NotApplicable && classification.emitter == sensorTarget.Classification.emitter); break; case ClassificationType.Moving: match = sensorTarget.Movement.Velocity.LengthSquared() > 0.01f; break; case ClassificationType.Camouflage: match = sensorTarget.GameThing.Camouflaged; break; default: // If this fires you should probably put in a new case statement for ht6e new category. Debug.Assert(false); match = OnMatch(sensorTarget.Classification); break; } // TODO (****) Remove this once we're sure the changes are // good so that we get decent perf in debug, too. /* * if (classification.name != "building" && classification.name != "bot") * { * Debug.Assert(match == OnMatch(sensorTarget.Classification), "Tell *** to fix."); * } */ } return(match); }