private List <GoapWorldState> CompareWorldStatesContainAny(List <GoapWorldState> set1, List <GoapWorldState> set2) { //returns any state in set2 that's part of set1 //returns null if there's conflict List <GoapWorldState> result = new List <GoapWorldState>(); foreach (GoapWorldState state2 in set2) { foreach (GoapWorldState state1 in set1) { //Debug.Log("GoapPlanner/CompareWorldStatesContainAny: Comparing state1 " + state1.Name + state1.Value + " vs state2 " + state2.Name + state2.Value); if (state1.Name == state2.Name) { if (state1.Operator != state2.Operator) { //CsDebug.Inst.Log("GoapPlanner/CompareWorldStatesContain: Operator mismatch!"); return(null); } else if (GoapWorldState.Compare(state1, state2) == true) { //Debug.Log("GoapPlanner/CompareWorldStatesContainAny: state 1 " + state1.Name + " equals to state 2 " + state2.Name); result.Add(state2); } else { //Debug.Log("GoapPlanner/CompareWorldStatesContainAny: States with same name and operator have different values!"); return(null); } } } } return(result); }
public GoapWorldState ParseWorldState(IDataReader reader) { int c_id = reader.GetInt32(0); string c_desc = reader.GetString(1); bool isBool = (reader.GetInt32(2) == 1); WorldStateOperator op = (WorldStateOperator)Enum.Parse(typeof(WorldStateOperator), reader.GetString(5)); bool valBool = (reader.GetInt32(6) == 1); float valFloat = reader.GetFloat(6); object value; if (isBool) { value = valBool; } else { value = valFloat; } GoapWorldState state = new GoapWorldState(c_id, c_desc, op, value); return(state); }
public GoapGoal GetGoalByID(int id) { IDataReader goalReader = GameManager.Inst.DBManager.RunAIQuery( "SELECT goap_goals.* " + "FROM goap_goals " + "WHERE goap_goals.id = '" + id + "'"); while (goalReader.Read()) { string goalName = goalReader.GetString(1); GoapGoal goal = new GoapGoal(); goal.Name = goalName; //query for conditions for each goal IDataReader condReader = GameManager.Inst.DBManager.RunAIQuery( "SELECT world_states.*, goal_conditions.* " + "FROM goal_conditions INNER JOIN world_states " + "ON goal_conditions.world_state_id = world_states.id AND goal_conditions.goal_id = '" + id + "'"); List <GoapWorldState> conditions = new List <GoapWorldState>(); while (condReader.Read()) { GoapWorldState state = ParseWorldState(condReader); conditions.Add(state); } condReader.Close(); condReader = null; goal.GoalStates = conditions; return(goal); } return(null); }
public static bool Compare(GoapWorldState state1, GoapWorldState state2) { //CsDebug.Inst.Log("GoapWorldState/Compare: Comparing state1 " + state1.Name + " " + state1.Operator + " " + state1.Value + // " vs state 2 "+ state2.Name + " " + state2.Operator + " " + state2.Value, CsDLevel.Trace, CsDComponent.AI); //returns true if state1 includes or equals to state2 if(state1.ID != state2.ID) { return false; } switch(state1.Operator) { case WorldStateOperator.Equals: return state1.Value.Equals(state2.Value); break; case WorldStateOperator.NotEquals: return state1.Value.Equals(state2.Value); break; case WorldStateOperator.Greater: return Convert.ToSingle(state1.Value) < Convert.ToSingle(state2.Value); break; case WorldStateOperator.Less: return Convert.ToSingle(state1.Value) > Convert.ToSingle(state2.Value); break; } return false; }
private bool AddStateToSet(List <GoapWorldState> set, GoapWorldState state) { //CsDebug.Inst.Log("GoapPlanner/AddStateToSet: Adding state " + state.Name + " = " + state.Value + " to set"); //returns true if no conflict; false if there's conflict foreach (GoapWorldState s in set) { //CsDebug.Inst.Log("GoapPlanner/AddStateToSet: checking state " + state.Name + "=" + state.Value + " against set state " // + s.Name + "=" + s.Value); if (s.Name == state.Name) { //duplicates found, try to combine if (s.Operator != state.Operator) { //CsDebug.Inst.Log("GoapPlanner/AddStateToSet: operator mismatch!"); return(false); } return(s.CombineValue(state)); } } //no duplicates found, add it //CsDebug.Inst.Log("GoapPlanner/AddStateToSet: No duplicate found, adding state"); set.Add(state); return(true); }
private bool CompareWorldStatesContain(List <GoapWorldState> set1, List <GoapWorldState> set2) { //returns true if all states in set2 exists in set1 //CsDebug.Inst.Log("Set1 contains " + set1.Count + " states", CsDLevel.Debug, CsDComponent.AI); foreach (GoapWorldState state2 in set2) { bool matchFound = false; foreach (GoapWorldState state1 in set1) { if (GoapWorldState.Compare(state1, state2) == false) { CsDebug.Inst.Log("GoapPlanner/CompareWorldStatesContain: state 1 " + state1.Name + state1.Value + " not equal to state 2 " + state2.Name + state2.Value, CsDLevel.Debug, CsDComponent.AI); } else { CsDebug.Inst.Log("GoapPlanner/CompareWorldStatesContain: state 1 " + state1.Name + state1.Value + " equals to state 2 " + state2.Name + state2.Value, CsDLevel.Debug, CsDComponent.AI); matchFound = true; } } if (!matchFound) { return(false); } } return(true); }
private void RemoveStateFromSet(List <GoapWorldState> set, GoapWorldState state) { List <GoapWorldState> copy = new List <GoapWorldState>(set); foreach (GoapWorldState s in copy) { if (s.Name == state.Name) { set.Remove(s); } } }
public void SetCurrentWorldState(GoapWorldState state, object newValue) { GoapWorldState existing = (from s in _currentWorldStates where s.Name == state.Name select s).FirstOrDefault(); if (existing != null) { existing.Value = newValue; } else { //if a world state with same name is not found in current list of world states, create a new one and add to current world states GoapWorldState newState = new GoapWorldState(state.ID, state.Name, state.Operator, newValue); _currentWorldStates.Add(newState); } }
public bool CombineValue(GoapWorldState targetState) { //tries to combine the value of target state to this state. returns true if combine successful. returns false if combine unsuccessful and there's conflict //if the value and operator combination of state is broader or equal to set, then we can assign the value //of state to s. If state's value is less broad or not equal, then we have a conflict. //if state's value is less braod than set, then we keep the value of s. //CsDebug.Inst.Log("GoapWorldState/CombineValue: checking target state " + targetState.Name + " = " + targetState.Value // + "vs myself " + Name + " = " + Value, CsDLevel.Trace, CsDComponent.AI); if (Operator != targetState.Operator) { return(false); } switch (Operator) { case WorldStateOperator.Equals: return(Value.Equals(targetState.Value)); break; case WorldStateOperator.NotEquals: return(Value.Equals(targetState.Value)); break; case WorldStateOperator.Greater: if (Convert.ToSingle(targetState.Value) < Convert.ToSingle(Value)) { Value = targetState.Value; } return(true); break; case WorldStateOperator.Less: if (Convert.ToSingle(targetState.Value) > Convert.ToSingle(Value)) { Value = targetState.Value; } return(true); break; } return(false); }
private object CheckWorldState(GoapWorldState state) { //first check if the state has already been checked, i.e. in the evaluated states list //if not in the list run parent AI evaluate world state //if in the list just return current world state foreach (GoapWorldState s in _evaluatedStates) { if (state.Name == s.Name) { return(s.Value); } } object value = _parentAI.EvaluateWorldState(state); _evaluatedStates.Add(state); return(value); }
public List <GoapGoal> GetCharacterGoalSet(int characterID) { IDataReader goalReader = GameManager.Inst.DBManager.RunAIQuery( "SELECT goap_goals.*, character_goals.priority " + "FROM goap_goals INNER JOIN character_goals " + "ON goap_goals.id = character_goals.goal_id AND character_goals.character_id = '" + characterID + "'"); List <GoapGoal> goals = new List <GoapGoal>(); while (goalReader.Read()) { int goalID = goalReader.GetInt32(0); string goalName = goalReader.GetString(1); int priority = goalReader.GetInt32(2); GoapGoal goal = new GoapGoal(); goal.Name = goalName; goal.Priority = priority; //query for conditions for each goal IDataReader condReader = GameManager.Inst.DBManager.RunAIQuery( "SELECT world_states.*, goal_conditions.* " + "FROM goal_conditions INNER JOIN world_states " + "ON goal_conditions.world_state_id = world_states.id AND goal_conditions.goal_id = '" + goalID + "'"); List <GoapWorldState> conditions = new List <GoapWorldState>(); while (condReader.Read()) { GoapWorldState state = ParseWorldState(condReader); conditions.Add(state); } condReader.Close(); condReader = null; goal.GoalStates = conditions; goals.Add(goal); } goalReader.Close(); goalReader = null; return(goals); }
public bool CombineValue(GoapWorldState targetState) { //tries to combine the value of target state to this state. returns true if combine successful. returns false if combine unsuccessful and there's conflict //if the value and operator combination of state is broader or equal to set, then we can assign the value //of state to s. If state's value is less broad or not equal, then we have a conflict. //if state's value is less braod than set, then we keep the value of s. //CsDebug.Inst.Log("GoapWorldState/CombineValue: checking target state " + targetState.Name + " = " + targetState.Value // + "vs myself " + Name + " = " + Value, CsDLevel.Trace, CsDComponent.AI); if(Operator != targetState.Operator) { return false; } switch(Operator) { case WorldStateOperator.Equals: return Value.Equals(targetState.Value); break; case WorldStateOperator.NotEquals: return Value.Equals(targetState.Value); break; case WorldStateOperator.Greater: if(Convert.ToSingle(targetState.Value) < Convert.ToSingle(Value)) { Value = targetState.Value; } return true; break; case WorldStateOperator.Less: if(Convert.ToSingle(targetState.Value) > Convert.ToSingle(Value)) { Value = targetState.Value; } return true; break; } return false; }
public GoapWorldState ParseWorldStateJoint(IDataReader reader) { int c_id = reader.GetInt32(0); string c_desc = reader.GetString(1); bool isBool = (reader.GetInt32(2) == 1); WorldStateOperator op = (WorldStateOperator)Enum.Parse(typeof(WorldStateOperator), reader.GetString(5)); bool valBool = (reader.GetInt32(6) == 1); float valFloat = reader.GetFloat(6); object value; if(isBool) { value = valBool; } else { value = valFloat; } GoapWorldState state = new GoapWorldState(c_id, c_desc, op, value); return state; }
public static bool Compare(GoapWorldState state1, GoapWorldState state2) { //CsDebug.Inst.Log("GoapWorldState/Compare: Comparing state1 " + state1.Name + " " + state1.Operator + " " + state1.Value + // " vs state 2 "+ state2.Name + " " + state2.Operator + " " + state2.Value, CsDLevel.Trace, CsDComponent.AI); //returns true if state1 includes or equals to state2 if (state1.ID != state2.ID) { return(false); } switch (state1.Operator) { case WorldStateOperator.Equals: return(state1.Value.Equals(state2.Value)); break; case WorldStateOperator.NotEquals: return(state1.Value.Equals(state2.Value)); break; case WorldStateOperator.Greater: return(Convert.ToSingle(state1.Value) < Convert.ToSingle(state2.Value)); break; case WorldStateOperator.Less: return(Convert.ToSingle(state1.Value) > Convert.ToSingle(state2.Value)); break; } return(false); }
private void RefreshGoalsTab() { IDataReader reader = RunQuery("SELECT goap_goals.* FROM goap_goals"); Dictionary <int, GoalData> goals = new Dictionary <int, GoalData>(); int i = 1; while (reader.Read()) { int c_id = reader.GetInt32(0); string c_desc = reader.GetString(1); GoalData data = new GoalData(); data.ID = c_id; data.Description = c_desc; goals.Add(i, data); i++; } string [] dropDownOptions = new string[goals.Count + 1]; dropDownOptions[0] = "Add New.."; if (goals.Count > 0) { for (int index = 1; index <= goals.Count; index++) { dropDownOptions[index] = goals[index].Description; } } GUI.Label(new Rect(10, 40, 200, 20), "Available Goals:"); _tab1Goal = EditorGUI.Popup(new Rect(10, 60, 150, 20), _tab1Goal, dropDownOptions); GUI.Label(new Rect(10, 90, 250, 20), "Description: " + dropDownOptions[_tab1Goal]); _tab1Description = GUI.TextField(new Rect(10, 110, 150, 15), _tab1Description, 100); if (GUI.Button(new Rect(170, 110, 60, 20), "Save")) { if (_tab1Goal > 0) { RunQuery("UPDATE goap_goals SET description = '" + _tab1Description + "' WHERE id = " + goals[_tab1Goal].ID); } else if (_tab1Goal == 0) { RunQuery("INSERT INTO goap_goals (id, description) VALUES (null, '" + _tab1Description + "')"); } } if (_tab1Goal > 0 && GUI.Button(new Rect(240, 110, 60, 20), "Delete")) { RunQuery("DELETE FROM goap_goals WHERE id = " + goals[_tab1Goal].ID); RunQuery("DELETE FROM goal_conditions WHERE goal_id = " + goals[_tab1Goal].ID); RunQuery("DELETE FROM character_goals WHERE goal_id = " + goals[_tab1Goal].ID); _tab1Goal = 0; } if (_tab1Goal > 0) { GUI.Label(new Rect(10, 140, 200, 20), "Conditions:"); IDataReader conditionReader = RunQuery( "SELECT world_states.*, goal_conditions.* " + "FROM goal_conditions INNER JOIN world_states " + "ON goal_conditions.world_state_id = world_states.id AND goal_conditions.goal_id = '" + goals[_tab1Goal].ID + "'"); List <GoapWorldState> conditions = new List <GoapWorldState>(); while (conditionReader.Read()) { GoapWorldState state = ParseWorldStateJoint(conditionReader); conditions.Add(state); } //get all the world states in order to form a drop down list IDataReader worldStatesReader = RunQuery("SELECT world_states.* FROM world_states"); _worldStates = new Dictionary <int, WorldStatesData>(); int stateIndex = 0; while (worldStatesReader.Read()) { int c_id = worldStatesReader.GetInt32(0); string c_desc = worldStatesReader.GetString(1); int isBool = worldStatesReader.GetInt32(2); WorldStatesData data = new WorldStatesData(); data.ID = c_id; data.Description = c_desc; data.IsBool = isBool; _worldStates.Add(stateIndex, data); stateIndex++; } string [] conditionOptions = new string[_worldStates.Count]; int rectHeight = 160; int heightStep = 30; int condIndex = 0; //remove existing goal conditions in db RunQuery("DELETE FROM goal_conditions WHERE goal_id = " + goals[_tab1Goal].ID); foreach (GoapWorldState state in conditions) { int selectedName = 0; if (_worldStates.Count > 0) { for (int index = 0; index < _worldStates.Count; index++) { conditionOptions[index] = _worldStates[index].Description; if (state.Name == _worldStates[index].Description) { selectedName = index; } } int height = rectHeight + heightStep * condIndex; selectedName = EditorGUI.Popup(new Rect(10, height, 150, 20), selectedName, conditionOptions); GUI.Label(new Rect(170, height, 40, 20), "Equals"); int selectedValue = EditorGUI.Popup(new Rect(220, height, 60, 20), ((bool)state.Value) == true ? 1 : 0, new string[] { "False", "True" }); bool toBeDeleted = false; if (GUI.Button(new Rect(290, height, 15, 15), "-")) { toBeDeleted = true; } //add new entries to db if (!toBeDeleted) { RunQuery("INSERT INTO goal_conditions (goal_id, world_state_id, operator_id, value) VALUES (" + goals[_tab1Goal].ID + ", " + _worldStates[selectedName].ID + ", 0, " + selectedValue + ")"); } } condIndex++; } //a button to add new condition if (GUI.Button(new Rect(290, rectHeight + heightStep * conditions.Count, 20, 20), "+")) { RunQuery("INSERT INTO goal_conditions (goal_id, world_state_id, operator_id, value) VALUES (" + goals[_tab1Goal].ID + ", " + _worldStates[0].ID + ", 0, 1)"); } } }
/* * public void AddContextPrecondition(List<GoapWorldState> conditions) * { * _contextPreconditions.AddRange(conditions); * } */ public void AddPrecondition(GoapWorldState condition) { _preconditions.Add(condition); }
public void AddEffect(GoapWorldState effect) { _effects.Add(effect); }
private void RemoveStateFromSet(List<GoapWorldState> set, GoapWorldState state) { List<GoapWorldState> copy = new List<GoapWorldState>(set); foreach(GoapWorldState s in copy) { if(s.Name == state.Name) { set.Remove(s); } } }
private object CheckWorldState(GoapWorldState state) { //first check if the state has already been checked, i.e. in the evaluated states list //if not in the list run parent AI evaluate world state //if in the list just return current world state foreach(GoapWorldState s in _evaluatedStates) { if(state.Name == s.Name) { return s.Value; } } object value = _parentAI.EvaluateWorldState(state); _evaluatedStates.Add(state); return value; }
private bool AddStateToSet(List<GoapWorldState> set, GoapWorldState state) { //CsDebug.Inst.Log("GoapPlanner/AddStateToSet: Adding state " + state.Name + " = " + state.Value + " to set"); //returns true if no conflict; false if there's conflict foreach(GoapWorldState s in set) { //CsDebug.Inst.Log("GoapPlanner/AddStateToSet: checking state " + state.Name + "=" + state.Value + " against set state " // + s.Name + "=" + s.Value); if(s.Name == state.Name) { //duplicates found, try to combine if(s.Operator != state.Operator) { //CsDebug.Inst.Log("GoapPlanner/AddStateToSet: operator mismatch!"); return false; } return s.CombineValue(state); } } //no duplicates found, add it //CsDebug.Inst.Log("GoapPlanner/AddStateToSet: No duplicate found, adding state"); set.Add(state); return true; }
public object EvaluateWorldState(GoapWorldState state) { if (state.Name == "IsThreatInSightInArea") { //loop through all known enemies whose confidence is 1 (in sight) //return true if any is found List <WorkingMemoryFact> knownEnemies = WorkingMemory.FindExistingFactOfType(FactType.KnownEnemy); foreach (WorkingMemoryFact fact in knownEnemies) { if (fact.Confidence >= 1 && fact.ThreatLevel > 0.1f) { //if enemy is in sight, return true even if not in area CsDebug.Inst.CharLog(_parentCharacter, "Evaluating IsThreatInSightInArea, enemy in sight " + ((Character)fact.Target).name); SetCurrentWorldState(state, true); return(true); } } //now loop through all known neutrals whose confidence is 1 //return true if any is within area List <WorkingMemoryFact> knownNeutrals = WorkingMemory.FindExistingFactOfType(FactType.KnownNeutral); foreach (WorkingMemoryFact fact in knownNeutrals) { if (fact.Confidence >= 1 && fact.ThreatLevel > 0.1f) { Vector3 position = ((Character)fact.Target).transform.position; //check if the neutral is within patrol range Vector3 targetLoc = BlackBoard.PatrolLoc; Vector3 targetRange = BlackBoard.CombatRange; if (IsPositionInArea(position, targetLoc, targetRange)) { CsDebug.Inst.CharLog(_parentCharacter, "Evaluation IsThreatInSightInArea, true, visible neutrals in area"); SetCurrentWorldState(state, true); return(true); } } } CsDebug.Inst.CharLog(_parentCharacter, "Evaluation IsThereThreatInArea, false"); SetCurrentWorldState(state, false); return(false); } else if (state.Name == "IsThereInvisibleEnemy") { bool result = (_parentCharacter.MyAI.BlackBoard.InvisibleEnemy != null); SetCurrentWorldState(state, result); return(result); } else if (state.Name == "IsTargetAThreat") { Character target = BlackBoard.TargetEnemy; if (BlackBoard.TargetEnemyThreat < 0.1f) { SetCurrentWorldState(state, false); return(false); } if (target != null && target.MyStatus.Health <= 0) { SetCurrentWorldState(state, false); return(false); } if (target == null && BlackBoard.InvisibleEnemy != null) { target = BlackBoard.InvisibleEnemy; } if (target == null) { SetCurrentWorldState(state, false); return(false); } WorkingMemoryFact fact = WorkingMemory.FindExistingFact(FactType.KnownEnemy, target); if (fact != null && fact.Confidence >= 1) { SetCurrentWorldState(state, true); return(true); } else if (fact != null && fact.ThreatLevel >= 0.6f) { SetCurrentWorldState(state, true); return(true); } else if (fact != null) { //check if last known pos is inside area Vector3 position = fact.LastKnownPos; //check if the enemy is within patrol range Vector3 targetLoc = BlackBoard.PatrolLoc; Vector3 targetRange = BlackBoard.CombatRange; if (IsPositionInArea(position, targetLoc, targetRange)) { SetCurrentWorldState(state, true); return(true); } } SetCurrentWorldState(state, false); return(false); } else if (state.Name == "IsTherePersonalThreat") { bool result = BlackBoard.HighestPersonalThreat > 0; SetCurrentWorldState(state, result); CsDebug.Inst.CharLog(_parentCharacter, "Is there personal threat? " + BlackBoard.HighestPersonalThreat); return(result); } else if (state.Name == "IsThereCriticalPersonalThreat") { bool result = BlackBoard.HighestPersonalThreat >= 1; SetCurrentWorldState(state, result); return(result); } else if (state.Name == "IsRangedWeaponEquipped") { if (BlackBoard.EquippedWeapon != null) { SetCurrentWorldState(state, true); return(true); } else { SetCurrentWorldState(state, false); return(false); } } else if (state.Name == "IsThreatInSight") { List <WorkingMemoryFact> knownEnemies = WorkingMemory.FindExistingFactOfType(FactType.KnownEnemy); foreach (WorkingMemoryFact fact in knownEnemies) { //Debug.Log("Is Threat In Sight fact confidence " + fact.Confidence); if (fact.Confidence >= 1 && fact.ThreatLevel > 0.1f) { SetCurrentWorldState(state, true); return(true); } } SetCurrentWorldState(state, false); return(false); } else if (state.Name == "IsAmmoAvailable") { SetCurrentWorldState(state, true); return(true); } else if (state.Name == "IsBehindCover") { bool result = true; if (BlackBoard.SelectedCover == null) { result = false; } else { result = Vector3.Distance(_parentCharacter.transform.position, BlackBoard.SelectedCoverLoc) <= 2 ? true : false; } SetCurrentWorldState(state, result); return(result); } else if (state.Name == "IsBehindAttackCover") { bool result = true; if (BlackBoard.SelectedCover == null) { result = false; } else { if (Vector3.Distance(_parentCharacter.transform.position, BlackBoard.SelectedCoverLoc) <= 1 && BlackBoard.SelectedCover.IsForShooting) { result = true; } else { result = false; } } SetCurrentWorldState(state, result); return(result); } else if (state.Name == "IsThereDisturbance") { bool result = BlackBoard.HighestDisturbanceThreat > 0; SetCurrentWorldState(state, result); CsDebug.Inst.CharLog(_parentCharacter, "Is there disturbance? " + BlackBoard.HighestDisturbanceThreat); return(result); } else if (state.Name == "IsNearDefendPosition") { SetCurrentWorldState(state, false); return(false); if (!BlackBoard.HasPatrolInfo) { SetCurrentWorldState(state, false); return(false); } if (Vector3.Distance(_parentCharacter.transform.position, BlackBoard.PatrolLoc) > 1) { SetCurrentWorldState(state, false); return(false); } SetCurrentWorldState(state, true); return(true); } else if (state.Name == "IsInTargetArea") { bool result = IsPositionInArea(_parentCharacter.transform.position, BlackBoard.PatrolLoc, BlackBoard.PatrolRange); //CsDebug.Inst.CharLog(_parentCharacter, "Checking IsInTargetArea, result is " + result); SetCurrentWorldState(state, result); return(result); } else if (state.Name == "IsNearFollowingTarget") { SetCurrentWorldState(state, false); return(false); } else if (state.Name == "IsThereUncheckedCorpse") { if (BlackBoard.TargetCorpse != null && BlackBoard.TargetCorpse.ThreatLevel > 0 && Vector3.Distance(BlackBoard.TargetCorpse.LastKnownPos, _parentCharacter.transform.position) < 30) { SetCurrentWorldState(state, true); return(true); } SetCurrentWorldState(state, false); return(false); } else if (state.Name == "AlwaysFalse") { SetCurrentWorldState(state, false); return(false); } return(null); }
public void SetCurrentWorldState(GoapWorldState state, object newValue) { GoapWorldState existing = (from s in _currentWorldStates where s.Name == state.Name select s).FirstOrDefault(); if(existing != null) { existing.Value = newValue; } else { //if a world state with same name is not found in current list of world states, create a new one and add to current world states GoapWorldState newState = new GoapWorldState(state.ID, state.Name, state.Operator, newValue); _currentWorldStates.Add(newState); } }
public object EvaluateWorldState(GoapWorldState state) { if(state.Name == "IsThreatInSightInArea") { //loop through all known enemies whose confidence is 1 (in sight) //return true if any is found List<WorkingMemoryFact> knownEnemies = WorkingMemory.FindExistingFactOfType(FactType.KnownEnemy); foreach(WorkingMemoryFact fact in knownEnemies) { if(fact.Confidence >= 1) { //if enemy is in sight, return true even if not in area SetCurrentWorldState(state, true); return true; } } //now loop through all known neutrals whose confidence is 1 //return true if any is within area List<WorkingMemoryFact> knownNeutrals = WorkingMemory.FindExistingFactOfType(FactType.KnownNeutral); foreach(WorkingMemoryFact fact in knownNeutrals) { if(fact.Confidence >= 1) { Vector3 position = ((Character)fact.Target).transform.position; //check if the neutral is within patrol range Vector3 targetLoc = BlackBoard.PatrolLoc; Vector3 targetRange = BlackBoard.PatrolRange; if(IsPosisionInArea(position, targetLoc, targetRange)) { //Debug.Log("Evaluation IsThreatInSightInArea, true"); SetCurrentWorldState(state, true); return true; } } } //Debug.Log("Evaluation IsThereThreatInArea, false"); SetCurrentWorldState(state, false); return false; } else if(state.Name == "IsThereInvisibleEnemy") { bool result = (_parentCharacter.MyAI.BlackBoard.InvisibleEnemy != null); SetCurrentWorldState(state, result); return result; } else if(state.Name == "IsTargetAThreat") { //TO DO: //if target is not in sight, and if last known pos is inside area, return true; //if target is in sight, if target is enemy return true //if target is in sight, if target is neutral and still in area return true Character target = BlackBoard.TargetEnemy; if(target == null && BlackBoard.InvisibleEnemy != null) { target = BlackBoard.InvisibleEnemy; } WorkingMemoryFact fact = WorkingMemory.FindExistingFact(FactType.KnownEnemy, target); if(fact != null && fact.Confidence >= 1) { SetCurrentWorldState(state, true); return true; } else if(fact != null) { //check if last known pos is inside area Vector3 position = fact.LastKnownPos; //check if the neutral is within patrol range Vector3 targetLoc = BlackBoard.PatrolLoc; Vector3 targetRange = BlackBoard.PatrolRange; if(IsPosisionInArea(position, targetLoc, targetRange)) { SetCurrentWorldState(state, true); return true; } } SetCurrentWorldState(state, false); return false; } else if(state.Name == "IsTherePersonalThreat") { bool result = BlackBoard.HighestPersonalThreat > 0; SetCurrentWorldState(state, result); return false; } else if(state.Name == "IsRangedWeaponEquipped") { if(BlackBoard.EquippedWeapon != null) { SetCurrentWorldState(state, true); return true; } else { SetCurrentWorldState(state, false); return false; } } else if(state.Name == "IsThreatInSight") { List<WorkingMemoryFact> knownEnemies = WorkingMemory.FindExistingFactOfType(FactType.KnownEnemy); foreach(WorkingMemoryFact fact in knownEnemies) { if(fact.Confidence >= 1) { SetCurrentWorldState(state, true); return true; } } SetCurrentWorldState(state, false); return false; } else if(state.Name == "IsAmmoAvailable") { SetCurrentWorldState(state, true); return true; } return null; }
public object EvaluateWorldState(GoapWorldState state) { if(state.Name == "IsThreatInSightInArea") { //loop through all known enemies whose confidence is 1 (in sight) //return true if any is found List<WorkingMemoryFact> knownEnemies = WorkingMemory.FindExistingFactOfType(FactType.KnownEnemy); foreach(WorkingMemoryFact fact in knownEnemies) { if(fact.Confidence >= 1) { //if enemy is in sight, return true even if not in area //CsDebug.Inst.CharLog(_parentCharacter, "Evaluating IsThreatInSightInArea, enemy in sight " + ((Character)fact.Target).name); SetCurrentWorldState(state, true); return true; } } //now loop through all known neutrals whose confidence is 1 //return true if any is within area List<WorkingMemoryFact> knownNeutrals = WorkingMemory.FindExistingFactOfType(FactType.KnownNeutral); foreach(WorkingMemoryFact fact in knownNeutrals) { if(fact.Confidence >= 1) { Vector3 position = ((Character)fact.Target).transform.position; //check if the neutral is within patrol range Vector3 targetLoc = BlackBoard.PatrolLoc; Vector3 targetRange = BlackBoard.CombatRange; if(IsPositionInArea(position, targetLoc, targetRange)) { CsDebug.Inst.CharLog(_parentCharacter, "Evaluation IsThreatInSightInArea, true, visible neutrals in area"); SetCurrentWorldState(state, true); return true; } } } //CsDebug.Inst.CharLog(_parentCharacter, "Evaluation IsThereThreatInArea, false"); SetCurrentWorldState(state, false); return false; } else if(state.Name == "IsThereInvisibleEnemy") { bool result = (_parentCharacter.MyAI.BlackBoard.InvisibleEnemy != null); SetCurrentWorldState(state, result); return result; } else if(state.Name == "IsTargetAThreat") { Character target = BlackBoard.TargetEnemy; if(target != null && target.MyStatus.Health <= 0) { SetCurrentWorldState(state, false); return false; } if(target == null && BlackBoard.InvisibleEnemy != null) { target = BlackBoard.InvisibleEnemy; } if(target == null) { SetCurrentWorldState(state, false); return false; } WorkingMemoryFact fact = WorkingMemory.FindExistingFact(FactType.KnownEnemy, target); if(fact != null && fact.Confidence >= 1) { SetCurrentWorldState(state, true); return true; } else if(fact != null && fact.ThreatLevel >= 0.6f) { SetCurrentWorldState(state, true); return true; } else if(fact != null) { //check if last known pos is inside area Vector3 position = fact.LastKnownPos; //check if the enemy is within patrol range Vector3 targetLoc = BlackBoard.PatrolLoc; Vector3 targetRange = BlackBoard.CombatRange; if(IsPositionInArea(position, targetLoc, targetRange)) { SetCurrentWorldState(state, true); return true; } } SetCurrentWorldState(state, false); return false; } else if(state.Name == "IsTherePersonalThreat") { bool result = BlackBoard.HighestPersonalThreat > 0; SetCurrentWorldState(state, result); CsDebug.Inst.CharLog(_parentCharacter, "Is there personal threat? " + BlackBoard.HighestPersonalThreat); return result; } else if(state.Name == "IsThereCriticalPersonalThreat") { bool result = BlackBoard.HighestPersonalThreat >= 1; SetCurrentWorldState(state, result); return result; } else if(state.Name == "IsRangedWeaponEquipped") { if(BlackBoard.EquippedWeapon != null) { SetCurrentWorldState(state, true); return true; } else { SetCurrentWorldState(state, false); return false; } } else if(state.Name == "IsThreatInSight") { List<WorkingMemoryFact> knownEnemies = WorkingMemory.FindExistingFactOfType(FactType.KnownEnemy); foreach(WorkingMemoryFact fact in knownEnemies) { Debug.Log("Is Threat In Sight fact confidence " + fact.Confidence); if(fact.Confidence >= 1) { SetCurrentWorldState(state, true); return true; } } SetCurrentWorldState(state, false); return false; } else if(state.Name == "IsAmmoAvailable") { SetCurrentWorldState(state, true); return true; } else if(state.Name == "IsBehindCover") { bool result = true; if(BlackBoard.SelectedCover == null) { result = false; } else { result = Vector3.Distance(_parentCharacter.transform.position, BlackBoard.SelectedCoverLoc) <= 2 ? true : false; } SetCurrentWorldState(state, result); return result; } else if(state.Name == "IsBehindAttackCover") { bool result = true; if(BlackBoard.SelectedCover == null) { result = false; } else { if(Vector3.Distance(_parentCharacter.transform.position, BlackBoard.SelectedCoverLoc) <= 1 && BlackBoard.SelectedCover.IsForShooting) { result = true; } else { result = false; } } SetCurrentWorldState(state, result); return result; } else if(state.Name == "IsThereDisturbance") { bool result = BlackBoard.HighestDisturbanceThreat > 0; SetCurrentWorldState(state, result); CsDebug.Inst.CharLog(_parentCharacter, "Is there disturbance? " + BlackBoard.HighestDisturbanceThreat); return result; } else if(state.Name == "IsNearDefendPosition") { if(!BlackBoard.HasPatrolInfo) { SetCurrentWorldState(state, false); return false; } if(Vector3.Distance(_parentCharacter.transform.position, BlackBoard.PatrolLoc) > 1) { SetCurrentWorldState(state, false); return false; } SetCurrentWorldState(state, true); return true; } else if(state.Name == "IsInTargetArea") { bool result = IsPositionInArea(_parentCharacter.transform.position, BlackBoard.PatrolLoc, BlackBoard.PatrolRange); //CsDebug.Inst.CharLog(_parentCharacter, "Checking IsInTargetArea, result is " + result); SetCurrentWorldState(state, result); return result; } else if(state.Name == "IsNearFollowingTarget") { SetCurrentWorldState(state, false); return false; } else if(state.Name == "IsThereUncheckedCorpse") { if(BlackBoard.TargetCorpse != null && BlackBoard.TargetCorpse.ThreatLevel > 0 && Vector3.Distance(BlackBoard.TargetCorpse.LastKnownPos, _parentCharacter.transform.position) < 30) { SetCurrentWorldState(state, true); return true; } SetCurrentWorldState(state, false); return false; } return null; }
public List <GoapAction> GetCharacterActionSet(int characterID) { IDataReader actionReader = GameManager.Inst.DBManager.RunAIQuery( "SELECT goap_actions.* " + "FROM goap_actions INNER JOIN character_actions " + "ON goap_actions.id = character_actions.action_id AND character_actions.character_id = '" + characterID + "'"); List <GoapAction> actions = new List <GoapAction>(); while (actionReader.Read()) { int id = actionReader.GetInt32(0); string className = actionReader.GetString(1); string description = actionReader.GetString(2); //Debug.Log("get action " + className + description); float cost = actionReader.GetFloat(3); GoapAction action = (GoapAction)System.Activator.CreateInstance(System.Type.GetType(className), className, description, cost); ///query for preconditions and context preconditions IDataReader condReader = GameManager.Inst.DBManager.RunAIQuery( "SELECT world_states.*, action_preconditions.* " + "FROM action_preconditions INNER JOIN world_states " + "ON action_preconditions.world_state_id = world_states.id AND action_preconditions.action_id = '" + id + "'"); List <GoapWorldState> preconditions = new List <GoapWorldState>(); List <GoapWorldState> context = new List <GoapWorldState>(); while (condReader.Read()) { GoapWorldState state = ParseWorldState(condReader); bool isContext = (condReader.GetInt32(7) == 1); if (isContext) { context.Add(state); } else { preconditions.Add(state); } } condReader.Close(); condReader = null; //query for effects IDataReader effReader = GameManager.Inst.DBManager.RunAIQuery( "SELECT world_states.*, action_effects.* " + "FROM action_effects INNER JOIN world_states " + "ON action_effects.world_state_id = world_states.id AND action_effects.action_id = '" + id + "'"); List <GoapWorldState> effects = new List <GoapWorldState>(); while (effReader.Read()) { GoapWorldState state = ParseWorldState(effReader); effects.Add(state); } effReader.Close(); effReader = null; action.AddPrecondition(preconditions); action.AddEffect(effects); actions.Add(action); } actionReader.Close(); actionReader = null; return(actions); }
/* public void AddContextPrecondition(List<GoapWorldState> conditions) { _contextPreconditions.AddRange(conditions); } */ public void AddPrecondition(GoapWorldState condition) { _preconditions.Add(condition); }
private void RefreshActionsTab() { IDataReader reader = RunQuery("SELECT goap_actions.* FROM goap_actions"); Dictionary <int, ActionData> actions = new Dictionary <int, ActionData>(); int i = 1; while (reader.Read()) { int c_id = reader.GetInt32(0); string c_name = reader.GetString(1); string c_desc = reader.GetString(2); float c_cost = reader.GetFloat(3); ActionData data = new ActionData(); data.ID = c_id; data.ClassName = c_name; data.Description = c_desc; data.DefaultCost = c_cost; actions.Add(i, data); i++; } string [] dropDownOptions = new string[actions.Count + 1]; dropDownOptions[0] = "Add New.."; if (actions.Count > 0) { for (int index = 1; index <= actions.Count; index++) { dropDownOptions[index] = actions[index].Description; } } GUI.Label(new Rect(10, 40, 200, 20), "Available Actions:"); _tab2Action = EditorGUI.Popup(new Rect(10, 60, 150, 20), _tab2Action, dropDownOptions); GUI.Label(new Rect(10, 90, 250, 20), "Description: " + dropDownOptions[_tab2Action]); _tab2Description = GUI.TextField(new Rect(10, 110, 150, 15), _tab2Description, 100); string className = ""; if (_tab2Action > 0) { className = actions[_tab2Action].ClassName; } GUI.Label(new Rect(10, 130, 250, 20), "Class Name: " + className); _tab2ClassName = GUI.TextField(new Rect(10, 150, 150, 15), _tab2ClassName, 100); string cost = ""; if (_tab2Action > 0) { cost = actions[_tab2Action].DefaultCost.ToString(); } GUI.Label(new Rect(10, 170, 250, 20), "Default Cost: " + cost); _tab2CostString = GUI.TextField(new Rect(10, 190, 150, 15), _tab2CostString, 100); if (GUI.Button(new Rect(10, 210, 60, 20), "Save")) { if (_tab2Action > 0) { RunQuery("UPDATE goap_actions SET description = '" + _tab2Description + "', class_name = '" + _tab2ClassName + "', default_cost = '" + actions[_tab2Action].DefaultCost + "' WHERE id = " + actions[_tab2Action].ID); } else if (_tab2Action == 0) { float costFloat = Convert.ToSingle(_tab2CostString); RunQuery("INSERT INTO goap_actions (id, description, class_name, default_cost) VALUES (null, '" + _tab2Description + "', '" + _tab2ClassName + "', " + costFloat + ")"); } _tab2ClassName = ""; _tab2Description = ""; _tab2CostString = ""; } if (_tab2Action > 0 && GUI.Button(new Rect(80, 210, 60, 20), "Delete")) { RunQuery("DELETE FROM goap_actions WHERE id = " + actions[_tab2Action].ID); RunQuery("DELETE FROM action_effects WHERE action_id = " + actions[_tab2Action].ID); RunQuery("DELETE FROM action_preconditions WHERE action_id = " + actions[_tab2Action].ID); RunQuery("DELETE FROM character_actions WHERE action_id = " + actions[_tab2Action].ID); _tab2Action = 0; _tab2ClassName = ""; _tab2Description = ""; _tab2CostString = ""; } if (_tab2Action > 0) { GUI.Label(new Rect(10, 240, 200, 20), "Conditions:"); IDataReader conditionReader = RunQuery( "SELECT world_states.*, action_preconditions.* " + "FROM action_preconditions INNER JOIN world_states " + "ON action_preconditions.world_state_id = world_states.id AND action_preconditions.action_id = '" + actions[_tab2Action].ID + "'"); List <GoapWorldState> conditions = new List <GoapWorldState>(); while (conditionReader.Read()) { GoapWorldState state = ParseWorldStateJoint(conditionReader); conditions.Add(state); } //get all the world states in order to form a drop down list IDataReader worldStatesReader = RunQuery("SELECT world_states.* FROM world_states"); _worldStates = new Dictionary <int, WorldStatesData>(); int stateIndex = 0; while (worldStatesReader.Read()) { int c_id = worldStatesReader.GetInt32(0); string c_desc = worldStatesReader.GetString(1); int isBool = worldStatesReader.GetInt32(2); WorldStatesData data = new WorldStatesData(); data.ID = c_id; data.Description = c_desc; data.IsBool = isBool; _worldStates.Add(stateIndex, data); stateIndex++; } string [] conditionOptions = new string[_worldStates.Count]; int rectHeight = 260; int heightStep = 30; int condIndex = 0; foreach (GoapWorldState state in conditions) { int selectedName = 0; if (_worldStates.Count > 0) { for (int index = 0; index < _worldStates.Count; index++) { conditionOptions[index] = _worldStates[index].Description; if (state.Name == _worldStates[index].Description) { selectedName = index; } } int height = rectHeight + heightStep * condIndex; int newSelectedName = EditorGUI.Popup(new Rect(10, height, 150, 20), selectedName, conditionOptions); GUI.Label(new Rect(170, height, 40, 20), "Equals"); int selectedValue = EditorGUI.Popup(new Rect(220, height, 60, 20), ((bool)state.Value) == true ? 1 : 0, new string[] { "False", "True" }); bool toBeUpdated = false; if (newSelectedName != selectedName || selectedValue != (((bool)state.Value) == true ? 1 : 0)) { toBeUpdated = true; } bool toBeDeleted = false; if (GUI.Button(new Rect(290, height, 15, 15), "-")) { toBeDeleted = true; } if (toBeUpdated) { RunQuery("UPDATE action_preconditions SET world_state_id = " + _worldStates[newSelectedName].ID + ", value = " + selectedValue + " WHERE action_id = " + actions[_tab2Action].ID + " AND world_state_id = " + _worldStates[selectedName].ID); } if (toBeDeleted) { RunQuery("DELETE FROM action_preconditions WHERE world_state_id = " + _worldStates[newSelectedName].ID + " AND action_id = " + actions[_tab2Action].ID); } } condIndex++; } rectHeight = rectHeight + heightStep * conditions.Count; //a button to add new condition if (GUI.Button(new Rect(290, rectHeight, 20, 20), "+")) { RunQuery("INSERT INTO action_preconditions (action_id, world_state_id, operator_id, value, is_context) VALUES (" + actions[_tab2Action].ID + ", " + _worldStates[0].ID + ", 0, 1, 0)"); } //now list effects GUI.Label(new Rect(10, rectHeight + 30, 200, 20), "Effects:"); IDataReader effectsReader = RunQuery( "SELECT world_states.*, action_effects.* " + "FROM action_effects INNER JOIN world_states " + "ON action_effects.world_state_id = world_states.id AND action_effects.action_id = '" + actions[_tab2Action].ID + "'"); List <GoapWorldState> effects = new List <GoapWorldState>(); while (effectsReader.Read()) { GoapWorldState state = ParseWorldStateJoint(effectsReader); effects.Add(state); } string [] effectOptions = new string[_worldStates.Count]; int effectIndex = 0; rectHeight += 50; foreach (GoapWorldState state in effects) { int selectedName = 0; if (_worldStates.Count > 0) { for (int index = 0; index < _worldStates.Count; index++) { effectOptions[index] = _worldStates[index].Description; if (state.Name == _worldStates[index].Description) { selectedName = index; } } int height = rectHeight + heightStep * effectIndex; int newSelectedName = EditorGUI.Popup(new Rect(10, height, 150, 20), selectedName, effectOptions); GUI.Label(new Rect(170, height, 40, 20), "Equals"); int selectedValue = EditorGUI.Popup(new Rect(220, height, 60, 20), ((bool)state.Value) == true ? 1 : 0, new string[] { "False", "True" }); bool toBeUpdated = false; if (newSelectedName != selectedName || selectedValue != (((bool)state.Value) == true ? 1 : 0)) { toBeUpdated = true; } bool toBeDeleted = false; if (GUI.Button(new Rect(290, height, 15, 15), "-")) { toBeDeleted = true; } if (toBeUpdated) { RunQuery("UPDATE action_effects SET world_state_id = " + _worldStates[newSelectedName].ID + ", value = " + selectedValue + " WHERE action_id = " + actions[_tab2Action].ID + " AND world_state_id = " + _worldStates[selectedName].ID); } if (toBeDeleted) { RunQuery("DELETE FROM action_effects WHERE world_state_id = " + _worldStates[newSelectedName].ID + " AND action_id = " + actions[_tab2Action].ID); } } effectIndex++; } rectHeight = rectHeight + heightStep * effects.Count; //a button to add new condition if (GUI.Button(new Rect(290, rectHeight, 20, 20), "+")) { RunQuery("INSERT INTO action_effects (action_id, world_state_id, operator_id, value) VALUES (" + actions[_tab2Action].ID + ", " + _worldStates[0].ID + ", 0, 1)"); } } }