internal void BehaviorNameChanged(BehaviorData b) { switch (b.BehaviorType) { case Skill.Framework.AI.BehaviorType.Action: BehaviorNameChanged(b, _InsertActions); break; case Skill.Framework.AI.BehaviorType.Condition: BehaviorNameChanged(b, _InsertConditions); break; case Skill.Framework.AI.BehaviorType.Decorator: BehaviorNameChanged(b, _InsertDecorators); break; case Skill.Framework.AI.BehaviorType.Composite: BehaviorNameChanged(b, _InsertComposites); break; case Skill.Framework.AI.BehaviorType.ChangeState: BehaviorNameChanged(b, _InsertChangeStates); break; default: break; } }
public TreeViewItem(BehaviorData data) { this.Data = data; this.Height = 20; RefreshContent(); base.Content.image = Data.GetIcon(); }
private static void CheckParameterError(BehaviorData b) { for (int i = 0; i < b.Count; i++) { ParameterDataCollection parameters = b.GetParameters(i); if (parameters != null) { foreach (var item in parameters) { if (string.IsNullOrEmpty(b.Name)) { Debug.LogError(string.Format("Invalid parameter of Behavior node {0} (can not be null or empty).", b[i].Name)); _ErrorFound = true; } else { int count = parameters.Count(p => p.Name == item.Name); if (count > 1) { Debug.LogError(string.Format("There are {0} parameters for behaviors node {1} with same name ({2}).", count, b[i].Name, item.Name)); _ErrorFound = true; } } } } } }
public ListItem(BehaviorList ownerList, BehaviorData data, bool canRemove) { this.CanRemove = canRemove; this.OwnerList = ownerList; this.Data = data; this.Height = 16; this.Margin = new Thickness(0, 4, 0, 0); this.ColumnDefinitions.Add(20, GridUnitType.Pixel); this.ColumnDefinitions.Add(1, GridUnitType.Star); if (CanRemove) { Skill.Editor.UI.Rectangle redRect = new UI.Rectangle() { Row = 0, Column = 0, ColumnSpan = 2, Color = new Color(1, 0, 0, 0.2f) }; this.Controls.Add(redRect); } _ImgIcon = new Image() { Row = 0, Column = 0, Scale = ScaleMode.ScaleToFit, Texture = data.GetIcon() }; this.Controls.Add(_ImgIcon); _LblName = new Label() { Row = 0, Column = 1 }; this.Controls.Add(_LblName); UpdateContent(); }
public TreeViewFolder(BehaviorData data) { this.Data = data; this.Height = 20; LoadChildren(); RefreshContent(); base.Foldout.Content.image = Data.GetIcon(); }
/// <summary> /// Remove specyfied child /// </summary> /// <param name="child">child to remove</param> /// <returns>true if sucess, otherwise false</returns> public IBehaviorItem AddBehavior(BehaviorData newBehavior) { this.Data.Add(newBehavior); var item = CreateItem(newBehavior); this.Controls.Add(item); Editor.RefreshTree(); return(item as IBehaviorItem); }
private void SelectItem(BehaviorData behavior) { foreach (var control in _TreeView.Controls) { if (control is TreeViewFolder) { SelectItem((TreeViewFolder)control, behavior); } } }
private static void CreateBehaviorList(BehaviorData parent) { if (!_Behaviors.Contains(parent)) { _Behaviors.Add(parent); } foreach (var child in parent) { CreateBehaviorList(child); } }
private void BehaviorNameChanged(BehaviorData b, MenuItem items) { for (int i = 0; i < items.Count; i++) { if (b == items[i].UserData) { items[i].Name = b.Name; break; } } }
/// <summary> /// Check where is there a child that contains given behavior /// </summary> /// <param name="behavior">Behavior</param> /// <returns>true if contains, otherwise false</returns> public bool Contains(BehaviorData behavior) { foreach (IBehaviorItem item in this.Controls) { if (item.Data == behavior) { return(true); } } return(false); }
private IBehaviorItem Find(List <IBehaviorItem> controls, BehaviorData behavior) { foreach (var item in controls) { if (item.Data == behavior) { return(item); } } return(null); }
/// <summary> /// add behaviors in hierarchy to given list /// </summary> /// <param name="list">List of Behaviors to fill</param> /// <param name="behavior">behavior to add to list</param> private void CreateList(List <BehaviorData> list, BehaviorData behavior) { if (!list.Contains(behavior)) { list.Add(behavior); } foreach (BehaviorData b in behavior) { CreateList(list, b); } }
private bool CheckAddCauseLoop(TreeViewFolder parent, BehaviorData newBehavior) { while (parent != null) { if (parent.Data == newBehavior) { return(true); } parent = parent.Parent as TreeViewFolder; } return(false); }
internal void AddToList(BehaviorData behavior) { if (!_Behaviors.Contains(behavior)) { _Behaviors.Add(behavior); _TreeViewEditor.BehaviorsChanged(); } foreach (var item in behavior) { AddToList(item); } }
private void AddNewState() { BehaviorTreeStateData state = new BehaviorTreeStateData(); state.Name = _Editor.GetUniqueName("NewState"); BehaviorData[] preStates = _Editor.BehaviorTree.States; BehaviorData[] newStates = new BehaviorData[preStates.Length + 1]; preStates.CopyTo(newStates, 0); newStates[newStates.Length - 1] = state; _Editor.BehaviorTree.States = newStates; Add(state); SetButtonsEnable(); }
/// <summary> /// Check whether specyfied behavior is in hierarchy or unused /// </summary> /// <param name="behavior">Behavior to check</param> /// <returns>True if is in hierarchy, otherwise false</returns> public bool IsInHierarchy(BehaviorData behavior) { if (States != null) { foreach (var s in States) { if (IsInHierarchy(s, behavior)) { return(true); } } } return(false); }
private bool IsInHierarchy(BehaviorData node, BehaviorData behavior) { if (behavior == node) { return(true); } foreach (var item in node) { if (IsInHierarchy(item, behavior)) { return(true); } } return(false); }
internal void RemoveFromList(BehaviorData behavior) { if (_Behaviors.Contains(behavior)) { if (!_BehaviorTree.IsInHierarchy(behavior)) { _Behaviors.Remove(behavior); _TreeViewEditor.BehaviorsChanged(); } else { Debug.LogError("can not delete behavior. this behavior is in use"); } } }
private void SelectItem(TreeViewFolder folder, BehaviorData behavior) { foreach (var control in folder.Controls) { IBehaviorItem item = (IBehaviorItem)control; if (item.Data == behavior) { _TreeView.SelectedItem = control; return; } if (control is TreeViewFolder) { SelectItem((TreeViewFolder)control, behavior); } } }
void InsertMenuItem_Click(object sender, System.EventArgs e) { if (_TreeView.SelectedItem == null) { return; } if (!(_TreeView.SelectedItem is TreeViewFolder)) { return; } Skill.Editor.UI.MenuItem item = (Skill.Editor.UI.MenuItem)sender; BehaviorData behavior = (BehaviorData)item.UserData; if (behavior != null) { TreeViewFolder tvf = (TreeViewFolder)_TreeView.SelectedItem; string msg; if (tvf.CanAddBehavior(behavior, out msg)) { tvf.Foldout.IsOpen = true; tvf.AddBehavior(behavior); if (behavior is IParameterData) { var parameters = tvf.Data.GetParameters(tvf.Controls.Count - 1); if (parameters != null) { parameters.Match(((IParameterData)behavior).ParameterDifinition); } } var addedControl = tvf.Controls[tvf.Controls.Count - 1]; if (addedControl is IBehaviorItem) { ((IBehaviorItem)addedControl).RefreshContent(); } _Editor.AddToList(behavior); _Editor.RefreshTree(); SelectItem(tvf, behavior); } else { Debug.LogError(msg); } } }
private bool CheckAddCauseLoop(BehaviorData newBehavior) { TreeViewFolder parent = this; if (CheckAddCauseLoop(parent, newBehavior)) { return(true); } foreach (var item in newBehavior) { if (CheckAddCauseLoop(item)) { return(true); } } return(false); }
public bool CanAddBehavior(BehaviorData newBehavior, out string message) { // actions and conditions are leaves and can not have any child. also decorators can have only one child if (this.Data.BehaviorType != Skill.Framework.AI.BehaviorType.Composite && !(this.Data.BehaviorType == Skill.Framework.AI.BehaviorType.Decorator && Controls.Count == 0)) { message = "Can not add child to this node anymore"; return(false); } // check to prevent loop in hierarchy. if a node be twise in hierarchy cause too loop in tree if (CheckAddCauseLoop(newBehavior)) { message = "Adding this child cause to loop in tree"; return(false); } message = null; return(true); }
/// <summary> /// Create view model based on BehaviorType /// </summary> /// <param name="behavior">behavior data</param> /// <returns>Create view model</returns> public static Skill.Framework.UI.BaseControl CreateItem(BehaviorData behavior) { switch (behavior.BehaviorType) { case Skill.Framework.AI.BehaviorType.Action: return(new ActionItem((ActionData)behavior)); case Skill.Framework.AI.BehaviorType.Condition: return(new ConditionItem((ConditionData)behavior)); case Skill.Framework.AI.BehaviorType.ChangeState: return(new ChangeStateItem((ChangeStateData)behavior)); case Skill.Framework.AI.BehaviorType.Decorator: return(CreateDecoratorItem((DecoratorData)behavior)); case Skill.Framework.AI.BehaviorType.Composite: return(CreateCompositeItem((CompositeData)behavior)); } return(null); }
private void RemoveSelectedState() { if (_StateList.SelectedItem != null) { if (_StateList.Items.Count > 1) { BehaviorTreeStateData state = ((StateItem)_StateList.SelectedItem).State; BehaviorData[] preStates = _Editor.BehaviorTree.States; BehaviorData[] newStates = new BehaviorData[preStates.Length - 1]; int preIndex = 0; int newIndex = 0; while (newIndex < newStates.Length && preIndex < preStates.Length) { if (preStates[preIndex] == state) { preIndex++; continue; } newStates[newIndex] = preStates[preIndex]; newIndex++; preIndex++; } _Editor.BehaviorTree.States = newStates; _StateList.Items.Remove(_StateList.SelectedItem); SelectDefaultState(); RefreshItemStyles(); SetButtonsEnable(); } else { Debug.LogWarning("can not delete last state"); } } else { Debug.LogError("there is no selected state to remove"); } }
private void ValidateBehaviors() { int index = 0; while (index < _Behaviors.Count) { BehaviorData behavior = _Behaviors[index]; if (behavior.BehaviorType == Framework.AI.BehaviorType.ChangeState) { if (!HasState(((ChangeStateData)behavior).DestinationState)) { _Behaviors.RemoveAt(index); continue; } } index++; } for (int i = 0; i < _BehaviorTree.States.Length; i++) { GetChangeState(_BehaviorTree.States[i].Name); } }
internal void BehaviorNameChanged(BehaviorData b) { _TreeViewEditor.BehaviorNameChanged(b); }
public void Load(XmlElement e) { this.Name = e.GetAttributeValueAsString("Name", this.Name); this.DefaultState = e.GetAttributeValueAsString("DefaultState", DefaultDestinationState); this.ExpandMethods = e.GetAttributeValueAsBoolean("ExpandMethods", false); this.ExtraBehaviors = null; List <BehaviorData> list = new List <BehaviorData>(); XmlElement behaviorsElement = e["Behaviors"]; if (behaviorsElement != null) { foreach (var behaviorElement in behaviorsElement) { BehaviorData behavior = CreateBehaviorFrom(behaviorElement); if (behavior != null) { behavior.Load(behaviorElement); list.Add(behavior); } } } List <BehaviorTreeStateData> states = new List <BehaviorTreeStateData>(); foreach (var b in list) { if (b.BehaviorType == Skill.Framework.AI.BehaviorType.Composite && ((CompositeData)b).CompositeType == Skill.Framework.AI.CompositeType.State) { states.Add(b as BehaviorTreeStateData); } } // load hierarchy XmlElement hierarchy = e["Hierarchy"]; if (hierarchy != null) { foreach (var behaviorChildrenElement in hierarchy) { int behaviorId = behaviorChildrenElement.GetAttributeValueAsInt("Id", -2); BehaviorData behavior = FindById(list, behaviorId); if (behavior != null) { foreach (var containerElement in behaviorChildrenElement) { int childId = containerElement.GetAttributeValueAsInt("ChildId", -2); BehaviorData child = FindById(list, childId); if (child != null) { XmlElement parametersElement = containerElement[ParameterDataCollection.ElementName]; if (parametersElement != null) { ParameterDataCollection parameters = new ParameterDataCollection(); parameters.Load(parametersElement); behavior.Add(child, parameters); } else { behavior.Add(child); } } } } } } foreach (var b in list) { b.FixParameters(); } if (states.Count > 0) { this.States = states.ToArray(); } else { // try to load as previouse version format int rootId = e.GetAttributeValueAsInt("RootId", 0); BehaviorData root = FindById(list, rootId); if (root != null && root.BehaviorType == Skill.Framework.AI.BehaviorType.Composite && ((CompositeData)root).CompositeType == Skill.Framework.AI.CompositeType.Priority) { PrioritySelectorData ps = root as PrioritySelectorData; BehaviorTreeStateData state = new BehaviorTreeStateData(); state.Comment = ps.Comment; state.Concurrency = ps.Concurrency; state.Id = ps.Id; state.Name = ps.Name; state.Priority = ps.Priority; state.Weight = ps.Weight; foreach (var child in ps) { state.Add(child); } this.States = new BehaviorTreeStateData[] { state }; DefaultState = state.Name; } else { this.States = new BehaviorTreeStateData[] { new BehaviorTreeStateData() { Name = DefaultDestinationState } }; } } List <BehaviorData> extra = new List <BehaviorData>(); foreach (var b in list) { if (!IsInHierarchy(b)) { extra.Add(b); } } if (extra.Count > 0) { ExtraBehaviors = extra.ToArray(); } }
/// <summary> /// Detect Behavior data from Given XmlElement and load it /// </summary> /// <param name="behavior">XmlElement contains Behavior data</param> /// <returns>Loaded Behavior</returns> public static BehaviorData CreateBehaviorFrom(XmlElement behavior) { BehaviorData result = null; Skill.Framework.AI.BehaviorType behaviorType = Skill.Framework.AI.BehaviorType.Action; bool isCorrect = false; try { behaviorType = behavior.GetAttributeValueAsEnum <Skill.Framework.AI.BehaviorType>("BehaviorType", Skill.Framework.AI.BehaviorType.Condition); isCorrect = true; } catch (Exception) { isCorrect = false; } if (isCorrect) { switch (behaviorType) { case Skill.Framework.AI.BehaviorType.Action: result = new ActionData(); break; case Skill.Framework.AI.BehaviorType.Condition: result = new ConditionData(); break; case Skill.Framework.AI.BehaviorType.Decorator: Skill.Framework.AI.DecoratorType decoratorType = behavior.GetAttributeValueAsEnum <Skill.Framework.AI.DecoratorType>("DecoratorType", Skill.Framework.AI.DecoratorType.Default); switch (decoratorType) { case Skill.Framework.AI.DecoratorType.Default: result = new DecoratorData(); break; case Skill.Framework.AI.DecoratorType.AccessLimit: result = new AccessLimitDecoratorData(); break; default: break; } break; case Skill.Framework.AI.BehaviorType.Composite: Skill.Framework.AI.CompositeType selectorType = behavior.GetAttributeValueAsEnum <Skill.Framework.AI.CompositeType>("CompositeType", Skill.Framework.AI.CompositeType.Sequence); switch (selectorType) { case Skill.Framework.AI.CompositeType.Sequence: result = new SequenceSelectorData(); break; case Skill.Framework.AI.CompositeType.Concurrent: result = new ConcurrentSelectorData(); break; case Skill.Framework.AI.CompositeType.Random: result = new RandomSelectorData(); break; case Skill.Framework.AI.CompositeType.Priority: result = new PrioritySelectorData(); break; case Skill.Framework.AI.CompositeType.Loop: result = new LoopSelectorData(); break; case Skill.Framework.AI.CompositeType.State: result = new BehaviorTreeStateData(); break; } break; case Skill.Framework.AI.BehaviorType.ChangeState: result = new ChangeStateData(); break; } } return(result); }
void AddMenuItem_Click(object sender, System.EventArgs e) { if (_TreeView.SelectedItem == null) { return; } if (!(_TreeView.SelectedItem is TreeViewFolder)) { return; } Skill.Editor.UI.MenuItem item = (Skill.Editor.UI.MenuItem)sender; BehaviorData behavior = null; if (string.IsNullOrEmpty(item.Tag)) { Skill.Framework.AI.BehaviorType type = (Framework.AI.BehaviorType)item.UserData; switch (type) { case Skill.Framework.AI.BehaviorType.Action: behavior = new ActionData() { Name = _Editor.GetUniqueName("NewAction") }; break; case Skill.Framework.AI.BehaviorType.Condition: behavior = new ConditionData() { Name = _Editor.GetUniqueName("NewCondition") }; break; default: behavior = null; break; } } else if (item.Tag == "Decorator") { Skill.Framework.AI.DecoratorType type = (Framework.AI.DecoratorType)item.UserData; switch (type) { case Skill.Framework.AI.DecoratorType.Default: behavior = new DecoratorData() { Name = _Editor.GetUniqueName("NewDecorator") }; break; case Skill.Framework.AI.DecoratorType.AccessLimit: behavior = new AccessLimitDecoratorData() { Name = _Editor.GetUniqueName("NewAccessDecorator") }; break; default: behavior = null; break; } } else if (item.Tag == "Composite") { Skill.Framework.AI.CompositeType type = (Framework.AI.CompositeType)item.UserData; switch (type) { case Skill.Framework.AI.CompositeType.Sequence: behavior = new SequenceSelectorData() { Name = _Editor.GetUniqueName("NewSequence") }; break; case Skill.Framework.AI.CompositeType.Concurrent: behavior = new ConcurrentSelectorData() { Name = _Editor.GetUniqueName("NewConcurrent") }; break; case Skill.Framework.AI.CompositeType.Random: behavior = new RandomSelectorData() { Name = _Editor.GetUniqueName("NewRandom") }; break; case Skill.Framework.AI.CompositeType.Priority: behavior = new PrioritySelectorData() { Name = _Editor.GetUniqueName("NewPriority") }; break; case Skill.Framework.AI.CompositeType.Loop: behavior = new LoopSelectorData() { Name = _Editor.GetUniqueName("NewLoop") }; break; default: behavior = null; break; } } if (behavior != null) { TreeViewFolder tvf = (TreeViewFolder)_TreeView.SelectedItem; tvf.Foldout.IsOpen = true; tvf.AddBehavior(behavior); _Editor.AddToList(behavior); _Editor.RefreshTree(); SelectItem(tvf, behavior); } }