public override ProgrammingElement Clone() { ScoreFilter clone = new ScoreFilter(); CopyTo(clone); return(clone); }
} // end of MatchAction() public override void Reset(Reflex reflex) { int pointsRandom = 0; int pointsBase = 0; bool randomScore = false; int scoreCount = 0; // walk filters and set params if found // for (int indexFilter = 0; indexFilter < reflex.Filters.Count; indexFilter++) { Filter filter = reflex.Filters[indexFilter] as Filter; if (filter != null) { if (filter is ScoreFilter) { scoreCount += 1; ScoreFilter scoreFilter = filter as ScoreFilter; if (randomScore) { pointsRandom += scoreFilter.points; } else { pointsBase += scoreFilter.points; } } if (filter is RandomFilter) { randomScore = true; } } if (randomScore && pointsRandom == 0) { pointsRandom = 5; } } if (scoreCount > 0) { scoreTriggerValue = pointsBase + BokuGame.bokuGame.rnd.Next(pointsRandom); } else { scoreTriggerValue = -1; } base.Reset(reflex); }
public override void Reset(Reflex reflex) { int pointsRandom = 0; int pointsBase = 0; bool randomScore = false; int pointsTotal = 0; // walk filters and set params if found // for (int indexFilter = 0; indexFilter < reflex.Filters.Count; indexFilter++) { Filter filter = reflex.Filters[indexFilter] as Filter; if (filter != null) { if (filter is ScoreFilter) { ScoreFilter scoreFilter = filter as ScoreFilter; if (randomScore) { pointsRandom += scoreFilter.points; } else { pointsBase += scoreFilter.points; } } if (filter is ScoreBucketFilter) { } if (filter is RandomFilter) { randomScore = true; } } pointsTotal = pointsBase; // Add in random, may be negative. if (pointsRandom >= 0) { pointsTotal += BokuGame.bokuGame.rnd.Next(pointsRandom); } else { pointsTotal -= BokuGame.bokuGame.rnd.Next(-pointsRandom); } } this.triggerValue = pointsTotal; base.Reset(reflex); }
} // end of PrintTaskProgramming() static private string GetTileString(Reflex reflex) { string tiles = ""; // Ad blanks at beginning for indentation level. for (int i = 0; i < reflex.Indentation; i++) { tiles += " "; } tiles += Strings.Localize("programming.when") + " "; if (reflex.Data.Sensor != null) { tiles += reflex.Data.Sensor.label + " "; } else { tiles += "always "; } for (int i = 0; i < reflex.Data.Filters.Count; i++) { ScoreFilter sf = reflex.Data.Filters[i] as ScoreFilter; if (sf != null) { tiles += sf.points.ToString() + " "; } tiles += reflex.Data.Filters[i].label + " "; TerrainFilter tf = reflex.Data.Filters[i] as TerrainFilter; if (tf != null) { ushort matIdx = (ushort)reflex.MaterialType; int matLabel = Terrain.MaterialIndexToLabel(matIdx); tiles += matLabel.ToString() + " "; } TimerFilter tif = reflex.Data.Filters[i] as TimerFilter; if (tif != null) { tiles += tif.seconds.ToString() + " "; } } tiles += "-- " + Strings.Localize("programming.do") + " "; if (reflex.Data.Actuator != null) { tiles += reflex.Data.Actuator.label + " "; } if (reflex.Data.Selector != null) { tiles += reflex.Data.Selector.label + " "; } for (int i = 0; i < reflex.Data.Modifiers.Count; i++) { ScoreModifier sm = reflex.Data.Modifiers[i] as ScoreModifier; if (sm != null) { tiles += sm.points.ToString() + " "; } CreatableModifier cm = reflex.Data.Modifiers[i] as CreatableModifier; if (cm != null) { GameActor actor = InGame.inGame.GetCreatable(cm.CreatableId); if (actor != null) { tiles += actor.DisplayNameNumber + " "; } else { tiles += "? "; } } else { tiles += reflex.Data.Modifiers[i].label + " "; } } return(tiles); } // end of GetTileString()
} // end of PrintTaskProgramming() static private string SerializeTileString(Reflex reflex) { string tiles = "{'when':{"; if (reflex.Data.Sensor != null) { tiles += "'sensor':'" + reflex.Data.Sensor.label + "',"; if (reflex.Data.Sensor.label == "hear") //if this is a hear sensor. { for (int i = 0; i < reflex.Data.Filters.Count; i++) { if (reflex.Data.Filters[i].label == "said")//see if there is a specific hear text. { tiles += "'hearText':["; for (int j = 0; j < reflex.SaidStrings.Count; j++) { tiles += "'" + reflex.SaidStrings[j] + "',"; } tiles += "],"; } } } } else { tiles += "'sensor':" + "'always',"; } tiles += "'filters':["; for (int i = 0; i < reflex.Data.Filters.Count; i++) { ScoreFilter sf = reflex.Data.Filters[i] as ScoreFilter; if (sf != null) { tiles += "'" + sf.points.ToString() + "',"; } tiles += "'" + reflex.Data.Filters[i].label + "',"; TerrainFilter tf = reflex.Data.Filters[i] as TerrainFilter; if (tf != null) { ushort matIdx = (ushort)reflex.MaterialType; int matLabel = Terrain.MaterialIndexToLabel(matIdx); tiles += "'" + matLabel.ToString() + "',"; } } tiles += "]"; //filters tiles += "},"; //when tiles += "'do':{"; if (reflex.Data.Actuator != null) { tiles += "'action':'" + reflex.Data.Actuator.label + "',"; // If we have a say verb, also output the text. if (reflex.Data.Actuator.upid == "actuator.say") { tiles += "'sayText':["; for (int j = 0; j < reflex.SayStrings.Count; j++) { tiles += "'" + reflex.SayStrings[j] + "',"; } tiles += "],"; } } if (reflex.Data.Selector != null) { tiles += "'selector':'" + reflex.Data.Selector.label + "',"; } tiles += "'modifiers':["; for (int i = 0; i < reflex.Data.Modifiers.Count; i++) { ScoreModifier sm = reflex.Data.Modifiers[i] as ScoreModifier; if (sm != null) { tiles += "points:" + sm.points.ToString() + ","; } CreatableModifier cm = reflex.Data.Modifiers[i] as CreatableModifier; if (cm != null) { GameActor actor = InGame.inGame.GetCreatable(cm.CreatableId); if (actor != null) { tiles += "actorName:" + actor.DisplayNameNumber + ","; } else { tiles += "<unknown>"; } } else { tiles += "'" + reflex.Data.Modifiers[i].label + "',"; } } tiles += "]"; //modifiers tiles += "}"; //do tiles += "},"; //line return(tiles); } // end of GetTileString()
protected void CopyTo(ScoreFilter clone) { base.CopyTo(clone); clone.points = this.points; }
/// <summary> /// Gets the current score values based of the set of filters. /// This used to return the ScoreBucket but by calculating the scores here /// we can allow richer comparisons. /// The Health Filter can also be used as a value as can SettingsFilters. /// /// The result values depend on how the sensor is used. /// /// --Testing for Health /// WHEN Health Comparison Points /// /// --Testing for change. /// WHEN Red DO /// Bucket will contain the bucket to test for changed value from the previous frame. /// /// --Testing against a value. /// WHEN Red 5Points 2Points Green /// Left will contain the value for red. /// Right will contain value to compare against. /// CompareOp will contain the op to apply, in this case equals. /// /// --Comparisons /// WHEN Red White 2Points > Blue Blue Random Green 5Points /// Left will contain the sum of the values to the left of the comparison. /// Right will contain the sum of the values to the right of the comparison. /// CompareOp will contain the op to apply. /// /// </summary> /// <param name="actor"></param> /// <param name="reflex"></param> /// <returns></returns> public static GameScoredSensorResult ScoresFromFilterSet(GameActor actor, Reflex reflex) { List <Filter> filters = reflex.Filters; GameScoredSensorResult result = new GameScoredSensorResult(); bool testingHealth = reflex.sensorUpid == "sensor.health"; if (!testingHealth && TestScoreChange(filters)) { // Find ScoreBucketFilter and grab it's bucket. foreach (Filter filter in filters) { ScoreBucketFilter sbf = filter as ScoreBucketFilter; if (sbf != null) { int curScore = Scoreboard.GetScore(actor, sbf); int prevScore = Scoreboard.GetPrevScore(actor, sbf); result.TestingForChange = true; result.ScoreChanged = curScore != prevScore; } } } else if (!testingHealth && TestScoreValue(filters)) { bool hasScoreBucket = false; // Do we have a scorebucket in our list of filters? int scoreBucketIndex = -1; for (int i = 0; i < filters.Count; i++) { if (filters[i] is ScoreBucketFilter) { hasScoreBucket = true; scoreBucketIndex = i; } } Filter specialFilter = null; // Will be either RandomFilter or PercentFiter if found. int pointsPostSpecial = 0; if (hasScoreBucket) { // Compare first scorebucket value to sum of all other values. // Use first found scorebucket as left value. result.LeftValue = Scoreboard.GetScore(actor, filters[scoreBucketIndex] as ScoreBucketFilter); // Sum remaining tiles for right value. for (int i = 0; i < filters.Count; i++) { if (i == scoreBucketIndex) { // Skip over the first scorebucket filter. continue; } if (filters[i] is RandomFilter || filters[i] is PercentFilter) { Debug.Assert(specialFilter == null, "Two special tiles should not be valid here."); specialFilter = filters[i]; } ScoreFilter sf = filters[i] as ScoreFilter; if (sf != null) { if (specialFilter != null) { pointsPostSpecial += sf.points; } else { result.RightValue += sf.points; } } if (filters[i] is HealthFilter) { if (specialFilter != null) { pointsPostSpecial += actor.HitPoints; } else { result.RightValue += actor.HitPoints; } } SettingsFilter settings = filters[i] as SettingsFilter; if (settings != null) { if (specialFilter != null) { pointsPostSpecial += actor.GetSettingsValue(actor, settings.name); } else { result.RightValue += actor.GetSettingsValue(actor, settings.name); } } } // end of loop over filters. } else { // No scorebucket exists therefore compare the total to the Red score. // Use red bucket as left value. result.LeftValue = Scoreboard.GetGlobalScore((ScoreBucket)Classification.Colors.Red); // Sum point tiles for right value. for (int i = 0; i < filters.Count; i++) { if (filters[i] is RandomFilter || filters[i] is PercentFilter) { Debug.Assert(specialFilter == null, "Two special tiles should not be valid here."); specialFilter = filters[i]; } ScoreFilter sf = filters[i] as ScoreFilter; if (sf != null) { if (specialFilter != null) { pointsPostSpecial += sf.points; } else { result.RightValue += sf.points; } } if (filters[i] is HealthFilter) { if (specialFilter != null) { pointsPostSpecial += actor.HitPoints; } else { result.RightValue += actor.HitPoints; } } SettingsFilter settings = filters[i] as SettingsFilter; if (settings != null) { if (specialFilter != null) { pointsPostSpecial += actor.GetSettingsValue(actor, settings.name); } else { result.RightValue += actor.GetSettingsValue(actor, settings.name); } } } // end of loop over filters. } // Calc effect of special tiles. if (specialFilter != null) { if (specialFilter is RandomFilter) { if (pointsPostSpecial > 0) { result.RightValue += BokuGame.bokuGame.rnd.Next(pointsPostSpecial); } else if (pointsPostSpecial < 0) { result.RightValue -= BokuGame.bokuGame.rnd.Next(-pointsPostSpecial); } } if (specialFilter is PercentFilter) { result.RightValue = (int)Math.Round((float)result.RightValue / 100.0f * (float)pointsPostSpecial); } } // Set op to equals. result.CompareOp = ScoreCompareFilter.ScoreCompare.Is; } else if (TestComparison(filters)) { // If testing health, the lhs is just the # hitkpoints. if (testingHealth) { result.LeftValue = actor.HitPoints; } // Sum left side. Filter specialFilter = null; // Will be either RandomFilter or PercentFiter if found. int pointsPostSpecial = 0; int filterIndex = 0; for (; filterIndex < filters.Count; filterIndex++) { // Did we find a comparison filter, if so we're done with the left side. if (filters[filterIndex] is ScoreCompareFilter) { break; } // Did we find a special filter? if (filters[filterIndex] is RandomFilter || filters[filterIndex] is PercentFilter) { Debug.Assert(specialFilter == null, "Two special tiles should not be valid here."); specialFilter = filters[filterIndex]; } ScoreFilter sf = filters[filterIndex] as ScoreFilter; if (sf != null) { if (specialFilter != null) { pointsPostSpecial += sf.points; } else { result.LeftValue += sf.points; } } ScoreBucketFilter sbf = filters[filterIndex] as ScoreBucketFilter; if (sbf != null) { int sbValue = Scoreboard.GetScore(actor, sbf); if (specialFilter != null) { pointsPostSpecial += sbValue; } else { result.LeftValue += sbValue; } } if (filters[filterIndex] is HealthFilter) { if (specialFilter != null) { pointsPostSpecial += actor.HitPoints; } else { result.LeftValue += actor.HitPoints; } } SettingsFilter settings = filters[filterIndex] as SettingsFilter; if (settings != null) { if (specialFilter != null) { pointsPostSpecial += actor.GetSettingsValue(actor, settings.name); } else { result.LeftValue += actor.GetSettingsValue(actor, settings.name); } } } // end of loop over left hand side // Apply effect of specials. if (specialFilter != null) { if (specialFilter is RandomFilter) { if (pointsPostSpecial > 0) { result.LeftValue += BokuGame.bokuGame.rnd.Next(pointsPostSpecial); } else if (pointsPostSpecial < 0) { result.LeftValue -= BokuGame.bokuGame.rnd.Next(-pointsPostSpecial); } } if (specialFilter is PercentFilter) { result.LeftValue = (int)Math.Round((float)result.LeftValue / 100.0f * (float)pointsPostSpecial); } } // Grab op from ComparisonFilter which we should be looking at. result.CompareOp = (filters[filterIndex] as ScoreCompareFilter).op; ++filterIndex; // Now sum right hand side. specialFilter = null; pointsPostSpecial = 0; for (; filterIndex < filters.Count; filterIndex++) { // Did we find a comparison filter, if so we're broken. There should be only one. if (filters[filterIndex] is ScoreCompareFilter) { Debug.Assert(false, "Invalid to have two compare filters."); } // Did we find a random filter? if (filters[filterIndex] is RandomFilter) { Debug.Assert(specialFilter == null, "Two special tiles should not be valid here."); specialFilter = filters[filterIndex]; } ScoreFilter sf = filters[filterIndex] as ScoreFilter; if (sf != null) { if (specialFilter != null) { pointsPostSpecial += sf.points; } else { result.RightValue += sf.points; } } ScoreBucketFilter sbf = filters[filterIndex] as ScoreBucketFilter; if (sbf != null) { int sbValue = Scoreboard.GetScore(actor, sbf); if (specialFilter != null) { pointsPostSpecial += sbValue; } else { result.RightValue += sbValue; } } if (filters[filterIndex] is HealthFilter) { if (specialFilter != null) { pointsPostSpecial += actor.HitPoints; } else { result.RightValue += actor.HitPoints; } } SettingsFilter settings = filters[filterIndex] as SettingsFilter; if (settings != null) { if (specialFilter != null) { pointsPostSpecial += actor.GetSettingsValue(actor, settings.name); } else { result.RightValue += actor.GetSettingsValue(actor, settings.name); } } } // end of loop over right hand side // Apply effec of special tiles. if (specialFilter != null) { if (specialFilter is RandomFilter) { if (pointsPostSpecial > 0) { result.RightValue += BokuGame.bokuGame.rnd.Next(pointsPostSpecial); } else if (pointsPostSpecial < 0) { result.RightValue -= BokuGame.bokuGame.rnd.Next(-pointsPostSpecial); } } if (specialFilter is PercentFilter) { result.RightValue = (int)Math.Round((float)result.RightValue / 100.0f * (float)pointsPostSpecial); } } } else { Debug.Assert(false, "Not sure what we're testing for. Not good."); } return(result); } // end of ScoresFromFilterSet()