Example #1
0
	// ================================================================================================================

	public static void Show(UniRPGBasicEventHandler onAccept, RPGSkill selectedSkill, int helper)
	{
		// make sure DB is loaded
		if (!UniRPGEditorGlobal.LoadDatabase()) return;

		// create window
		SkillSelectWiz window = EditorWindow.GetWindow<SkillSelectWiz>(true, "Select Skill", true);
		window.inited = false;
		window.selectedSkill = selectedSkill;
		window.helper = helper;
		window.OnAccept = onAccept;

		// show window
		window.ShowUtility();
	}
Example #2
0
	void OnGUI()
	{
		if (!inited) Init();
		UniRPGEdGui.UseSkin();
		scroll = UniRPGEdGui.BeginScrollView(scroll);
		{
			if (UniRPGEditorGlobal.DB.Skills.Length > 0)
			{
				for (int i = 0; i < UniRPGEditorGlobal.DB.Skills.Length; i++)
				{
					Rect r = EditorGUILayout.BeginHorizontal();
					{
						r.x = 3; r.width = 19; r.height = 19;
						GUI.DrawTexture(r, (UniRPGEditorGlobal.DB.Skills[i].icon[0] != null ? UniRPGEditorGlobal.DB.Skills[i].icon[0] : UniRPGEdGui.Texture_NoPreview));
						GUILayout.Space(21);
						if (UniRPGEdGui.ToggleButton(selectedSkill == UniRPGEditorGlobal.DB.Skills[i], UniRPGEditorGlobal.DB.Skills[i].screenName, UniRPGEdGui.ButtonRightStyle, UniRPGEdGui.ButtonOnColor, GUILayout.Width(150)))
						{
							selectedSkill = UniRPGEditorGlobal.DB.Skills[i];
						}
					}
					EditorGUILayout.EndHorizontal();
				}
			}
			else
			{
				GUILayout.Label("No Skills are defined", UniRPGEdGui.WarningLabelStyle);
			}
		}
		UniRPGEdGui.EndScrollView();
		UniRPGEdGui.DrawHorizontalLine(1, UniRPGEdGui.DividerColor, 0, 10);

		EditorGUILayout.BeginHorizontal();
		{
			GUILayout.FlexibleSpace();

			if (selectedSkill == null) GUI.enabled = false;
			if (GUILayout.Button("Accept", UniRPGEdGui.ButtonStyle)) accepted = true;
			GUI.enabled = true;

			if (GUILayout.Button("Cancel", UniRPGEdGui.ButtonStyle)) this.Close();
			GUILayout.FlexibleSpace();
		}
		EditorGUILayout.EndHorizontal();
		GUILayout.Space(10);
	}
Example #3
0
	private GameObject aoeTargetingMarker; // this is the instance of aoeTargetingMarkerPrefab , when used

	// ================================================================================================================

	public void CopyTo(RPGSkill s)
	{
		s.id = this.id.Copy();

		s.screenName = this.screenName;
		s.description = this.description;
		s.notes = this.notes;
		s.icon = new Texture2D[3] { this.icon[0], this.icon[1], this.icon[2] };
		s.guiHelper = this.guiHelper;

		s.onUseMaxTargetDistance = this.onUseMaxTargetDistance;
		s.validTargetsMask = this.validTargetsMask;

		s.castTimeSetting = this.castTimeSetting;
		s.cooldownTimeSetting = this.cooldownTimeSetting;
		s.startCooldownAfterCast = this.startCooldownAfterCast;
		s.canBeInterrupted = this.canBeInterrupted;
		s.ownerCanInterrupt = this.ownerCanInterrupt;

		s.onUseActions = new List<Action>(0);
		GameObject g = s.gameObject;
		foreach (Action act in this.onUseActions)
		{
			Action newAct = (Action)g.AddComponent(act.GetType());
			newAct.hideFlags = HideFlags.HideInInspector;
			act.CopyTo(newAct);
			s.onUseActions.Add(newAct);
		}

		s.rightActions = new List<Action>(0);
		foreach (Action act in this.rightActions)
		{
			Action newAct = (Action)g.AddComponent(act.GetType());
			newAct.hideFlags = HideFlags.HideInInspector;
			act.CopyTo(newAct);
			s.rightActions.Add(newAct);
		}

	}
Example #4
0
	// ================================================================================================================
	#region Init/Start

	public void Awake()
	{
		_tr = gameObject.transform;
		_character = gameObject.GetComponent<CharacterBase>();

		InAOESelectMode = false;
		currSkill = null;
		nextSkill = null;
		autoSkill = null;
		nextSkillTarget = null;
		autoSkillTarget = null;
		nextSkillMaxDistance = 0f;
	}
Example #5
0
	/// <summary>called by actor class when a skill's execution has stopped</summary>
	public virtual void DonePerformingSkill(RPGSkill skill) { }
Example #6
0
	/// <summary>
	/// called by actor to find out if it is ok to execute the skill?
	/// a plugin might want to return false here if it is still 
	/// turning the character to look at the skill's target
	/// </summary>
	public virtual bool CanPerformSkillNow(RPGSkill skill, Vector3 skillTargetLocation) { return true; }
Example #7
0
	// ================================================================================================================
	#region Skills panel

	private void DrawSkills()
	{
		if (!gui.plrMoveSkills) UniRPGGlobal.GUIConsumedInput = true;
		if (ShowRightPopMenu >= 0) GUI.enabled = false;
		GUILayout.BeginArea(r[1], gui.skillPanelName, GUI.skin.window);
		{
			if (GUI.Button(new Rect(r[1].width - gui.WindowCloseButton.fixedWidth - GUI.skin.window.padding.right,
									GUI.skin.window.padding.top + GUI.skin.window.contentOffset.y,
									gui.WindowCloseButton.fixedWidth, gui.WindowCloseButton.fixedHeight), GUIContent.none, gui.WindowCloseButton))
			{
				PlayButtonFX();
				showSkills = false;
			}

			scroll[2] = GUILayout.BeginScrollView(scroll[2]);
			{
				for (int i = 0; i < UniRPGGlobal.Player.Actor.skills.Count; i++)
				{
					if (!string.IsNullOrEmpty(UniRPGGlobal.Player.Actor.skills[i].guiHelper)) continue;
					if (GUILayout.Button(new GUIContent(" " + UniRPGGlobal.Player.Actor.skills[i].screenName, UniRPGGlobal.Player.Actor.skills[i].icon[0] == null ? gui.txNoIcon : UniRPGGlobal.Player.Actor.skills[i].icon[0], i.ToString()), gui.ListButton))
					{
						PlayButtonFX();
						ShowRightPopMenu = i;
					}
					if (GUI.tooltip == i.ToString() && GUI.enabled) SetHoverSkill(UniRPGGlobal.Player.Actor.skills[i]);
				}
			}
			GUILayout.EndScrollView();
		}
		GUILayout.EndArea();
		if (!showOptions) GUI.enabled = true;

		int cnt = 2;
		if (popMenuHelperSkill != null)
		{
			cnt = gui.actionSlotsCount + 1;
		}

		if (ShowRightPopMenu >= 0 && popRectCalced)
		{
			GUILayout.BeginArea(rPopMenu, GUI.skin.box);
			{
				if (popMenuHelperSkill != null)
				{
					scroll[3] = GUILayout.BeginScrollView(scroll[3]);
					{
						if (GUILayout.Button("Cancel"))
						{
							PlayButtonFX();
							popMenuHelperSkill = null;
							ShowRightPopMenu = -1;
						}
						for (int i = 0; i < gui.actionSlotsCount; i++)
						{							
							if (GUILayout.Button("Slot " + (i + 1)))
							{
								PlayButtonFX();
								UniRPGGlobal.Player.Actor.SetActionSlot(i, popMenuHelperSkill);
								popMenuHelperSkill = null;
								ShowRightPopMenu = -1;
							}
						}
					}
					GUILayout.EndScrollView();
				}
				else
				{
					if (GUILayout.Button("Equip"))
					{
						PlayButtonFX();
						popRectCalced = false;
						scroll[3] = Vector2.zero;
						popMenuHelperSkill = UniRPGGlobal.Player.Actor.skills[ShowRightPopMenu];
					}
					if (GUILayout.Button("Cancel"))
					{
						PlayButtonFX();
						popMenuHelperSkill = null;
						ShowRightPopMenu = -1;
					}
				}
			}
			GUILayout.EndArea();
		}
		CalcPopMenuRect(cnt, ShowRightPopMenu, popMenuHelperSkill!=null);
		DrawHoverSkillInfo();
	}
Example #8
0
	/// <summary>
	/// will queue the skill to be used as soon as current skill is done and/or queued skill is avail for use (cool down might be running)
	/// setAsAutoQueueSkill=true will cause the skill to be queued and performed as long as target is valid or stopped by an action by the player
	/// </summary>
	public void UseSkill(RPGSkill skill, GameObject target, bool setAsAutoQueueSkill)
	{
		if (skill.targetMech == RPGSkill.TargetingMechanic.AroundLocation)
		{
			// the player must first select a spot with the mouse
			InAOESelectMode = true;
			AOESkill = skill;
			nextSkill = null;
			autoSkill = null;
			nextSkillTarget = null;
			autoSkillTarget = null;
		}

		else if ((skill.targetMech == RPGSkill.TargetingMechanic.SingleTarget || skill.targetMech == RPGSkill.TargetingMechanic.AroundTargeted) &&
				skill.validTargetsMask != 0 && ((int)UniRPGGlobal.Target.Self & (int)skill.validTargetsMask) == 0)
		{
			if (skill.IsValidTarget(target))
			{
				if (setAsAutoQueueSkill) { autoSkill = skill; autoSkillTarget = target; }
				nextSkill = skill;
				nextSkillTarget = target;
				if (target == null) nextSkillLocation = transform.position;
				else nextSkillLocation = target.transform.position;
				nextSkillMaxDistance = nextSkill.onUseMaxTargetDistance;
				nextSkillMaxDistance = nextSkillMaxDistance * nextSkillMaxDistance; // cause I'm using sqrMagnitude for distance check				
			}
			else
			{
				nextSkill = null;
				autoSkill = null;
				nextSkillTarget = null;
				autoSkillTarget = null;
				InAOESelectMode = false;
				AOESkill = null;
			}
		}
		else
		{
			if (setAsAutoQueueSkill) { autoSkill = skill; autoSkillTarget = target; }
			nextSkill = skill;

			if (skill.targetMech == RPGSkill.TargetingMechanic.AroundOwner)
			{
				nextSkillTarget = null;
				nextSkillLocation = transform.position; //UniRPGGlobal.Player.transform.position;
			}
			else
			{
				nextSkillTarget = target;
				nextSkillLocation = Vector3.zero;
			}

			if (skill.validTargetsMask == 0 || ((int)UniRPGGlobal.Target.Self & (int)skill.validTargetsMask) != 0)
			{
				nextSkillTarget = ((int)UniRPGGlobal.Target.Self & (int)skill.validTargetsMask) != 0 ? gameObject : null;
				nextSkillLocation = transform.position;
				nextSkillMaxDistance = 0;
			}
			else
			{
				nextSkillMaxDistance = nextSkill.onUseMaxTargetDistance;
				nextSkillMaxDistance = nextSkillMaxDistance * nextSkillMaxDistance; // cause I'm using sqrMagnitude for distance check
			}
		}
	}
Example #9
0
	private void CreateSkill(System.Object sender)
	{
		TextInputWiz wiz = sender as TextInputWiz;
		string name = wiz.text;
		wiz.Close();

		if (string.IsNullOrEmpty(name)) name = "Skill";

		UniRPGEditorGlobal.CheckDatabasePath(UniRPGEditorGlobal.DB_DATA_PATH, UniRPGEditorGlobal.DB_SKILLS_PATH);
		string fn = UniRPGEditorGlobal.DB_SKILLS_PATH + name + ".prefab";
		if (UniRPGEdUtil.RelativeFileExist(fn)) fn = AssetDatabase.GenerateUniqueAssetPath(fn);

		Object prefab = PrefabUtility.CreateEmptyPrefab(fn);
		GameObject go = new GameObject(name);							// create temp object in scene 
		go.AddComponent<RPGSkill>();
		GameObject toRef = PrefabUtility.ReplacePrefab(go, prefab);		// save prefab
		GameObject.DestroyImmediate(go);								// clear temp object from scene

		curr = toRef.GetComponent<RPGSkill>();
		curr.screenName = name;
		ed.db.skillPrefabs.Add(toRef);

		EditorUtility.SetDirty(curr);
		EditorUtility.SetDirty(ed.db);
		AssetDatabase.SaveAssets();

		ed.Repaint();
	}
Example #10
0
	// ================================================================================================================

	private void LeftPanel()
	{
		EditorGUILayout.BeginVertical(GUILayout.Width(DatabaseEditor.LeftPanelWidth));
		GUILayout.Space(5);
		// -------------------------------------------------------------

		// the add button
		EditorGUILayout.Space();
		EditorGUILayout.BeginHorizontal();
		{
			GUILayout.FlexibleSpace();
			if (GUILayout.Button(new GUIContent("Add Skill", UniRPGEdGui.Icon_Plus), EditorStyles.miniButtonLeft))
			{
				GUI.FocusControl("");
				TextInputWiz.Show("New Skill", "Enter name for new skill", "", CreateSkill);
			}
			if (curr == null) GUI.enabled = false;
			if (GUILayout.Button(new GUIContent(UniRPGEdGui.Icon_Copy, "Copy"), EditorStyles.miniButtonMid))
			{
				GUI.FocusControl("");
				CreateSkillCopy();
			}
			GUI.enabled = true;
		}
		EditorGUILayout.EndHorizontal();
		EditorGUILayout.Space();

		scroll[0] = UniRPGEdGui.BeginScrollView(scroll[0], GUILayout.Width(DatabaseEditor.LeftPanelWidth));
		{
			if (ed.db.Skills.Length > 0)
			{
				foreach (RPGSkill skill in ed.db.Skills)
				{
					if (skill == null) continue;
					
					Rect r = EditorGUILayout.BeginHorizontal(GUILayout.Width(DatabaseEditor.LeftPanelWidth - 20), GUILayout.ExpandWidth(false));
					{
						r.x = 3; r.width = 19; r.height = 19;
						GUI.DrawTexture(r, (skill.icon[0] != null ? skill.icon[0] : UniRPGEdGui.Texture_NoPreview));
						GUILayout.Space(21);
						if (UniRPGEdGui.ToggleButton(curr == skill, skill.screenName, UniRPGEdGui.ButtonMidStyle, GUILayout.Width(140), GUILayout.ExpandWidth(false)))
						{
							curr = skill;
							GUI.FocusControl("");
						}
						if (GUILayout.Button("X", UniRPGEdGui.ButtonRightStyle, GUILayout.Width(20)))
						{
							del = skill;
						}
					}
					EditorGUILayout.EndHorizontal();
				}
			}
			else
			{
				GUILayout.Label("No Skills are defined", UniRPGEdGui.WarningLabelStyle);
			}
		}
		UniRPGEdGui.EndScrollView();

		// -------------------------------------------------------------
		GUILayout.Space(3);
		EditorGUILayout.EndVertical();

		if (del != null)
		{
			if (curr == del) curr = null;
			ed.db.skillPrefabs.Remove(del.gameObject);
			EditorUtility.SetDirty(ed.db);
			AssetDatabase.SaveAssets();

			string path = AssetDatabase.GetAssetPath(del.gameObject);
			AssetDatabase.DeleteAsset(path);
			AssetDatabase.Refresh();
			del = null;
		}
	}
Example #11
0
		private void UpdateHostileAI()
		{
			// try to use the primary skill on the player (it is most likely an attack skill)
			if (_actor.skills.Count == 0 || TargetedCharacter == null) return;
			if (_actor.IsPerformingSkill) return;

			if (skill != null && false == UniRPGGlobal.Player.canBeTargeted || actorType != UniRPGGlobal.ActorType.Hostile)
			{	// player became non-targetable (or the NPC is not hostile any longer)
				skill = null;
				ClearTarget();
				_actor.ClearQueuedSkill();
				return;
			}

			chaseTimer -= Time.deltaTime;
			if (chaseTimer <= 0.0f)
			{
				skill = null;
				ClearTarget();
				_actor.ClearQueuedSkill();
				return;
			}

			// if it has a skill 2 when 1st check if that skill can't rather be used
			skill = null;
			if (_actor.skills.Count > 1)
			{
				if (_actor.skills[1])
				{
					float distance = Vector3.Distance(UniRPGGlobal.Player.transform.position, _tr.position);
					if (distance >= detectionRadius * chooseSkill2DistanceMod) skill = _actor.skills[1];
				}
			}

			if (skill == null) skill = _actor.skills[0];
			if (skill)
			{
				if (false == UniRPGGlobal.Player.canBeTargeted || actorType != UniRPGGlobal.ActorType.Hostile)
				{	// player became non-targetable (or the NPC is not hostile any longer)
					ClearTarget();
					_actor.ClearQueuedSkill();
					return;
				}

				if (skill.IsReady)
				{
					int r = CheckIfCanPerform(skill, TargetedCharacter.transform.position);
					if (r == 0)
					{
						chaseTimer = chaseTimeout;
						navi.Stop();
						_actor.UseSkill(skill, TargetedCharacter.gameObject, false);
						navi.LookAt(TargetedCharacter.transform.position);
					}
					else
					{
						scanTimer -= Time.deltaTime;
						if (navi.IsMovingOrPathing() == false || scanTimer <= 0f)
						{
							scanTimer = 1f;
							// these updates can only happen in intervals. Do not want MoveTo() called continuously
							if (r == 1)
							{	// move closer to target
								navi.MoveTo(TargetedCharacter.transform.position, chaseSpeed, turnSpeed);
							}
							else
							{	// at least look in correct direction
								navi.LookAt(TargetedCharacter.transform.position);
							}
						}
					}
				}
			}
		}
Example #12
0
	/// <summary>remove queued skill, only if it has the mentioned target</summary>
	public void ClearQueuedSkill(GameObject ifTargeted)
	{
		// only untarget if this target
		if (nextSkillTarget != ifTargeted) return;

		CancelAOETargeting();
		nextSkill = null;
		autoSkill = null;
		nextSkillTarget = null;
		autoSkillTarget = null;
	}
Example #13
0
	/// <summary>Put the Skill in the slot. skill must already be instantiated</summary>
	public bool SetActionSlot(int slot, RPGSkill skill)
	{
		if (skill == null) return false;
		if (slot < 0 || slot >= actionSlots.Count) return false;
		actionSlots[slot].SetAsSkill(skill);

		// clear any other slot that has same skill in it
		for (int i = 0; i < actionSlots.Count; i++)
		{
			if (actionSlots[i].Skill == null) continue;
			if (i != slot && actionSlots[i].Skill.id == skill.id) ClearActionSlot(i);
		}

		return true;
	}		
Example #14
0
	/// <summary>Get instance of the skill from skill list. return null if actor does not have the skill</summary>
	public RPGSkill GetSkill(RPGSkill skill)
	{
		if (skill) return GetSkill(skill.id);
		return null;
	}
Example #15
0
	/// <summary>return true of the actor has the mentioned skill in skill list</summary>
	public bool HasSKill(RPGSkill skill)
	{
		if (skill) return HasSkill(skill.id);
		return false;
	}
Example #16
0
	/// <summary>will remove the skill from the list of available skills and from any slot it is mounted and then destroy the instance of the skill</summary>
	public void RemoveSkill(RPGSkill skill)
	{
		if (skill) RemoveSkill(skill.id);
	}
Example #17
0
	/// <summary>Cancel queued skill and target. useful for AI to cancel any targeting when the player is out of range</summary>
	public void ClearQueuedSkill()
	{
		CancelAOETargeting();
		nextSkill = null;
		autoSkill = null;
		nextSkillTarget = null;
		autoSkillTarget = null;
	}
Example #18
0
		// 0: yes, 1:too far, 2:turn
		private int CheckIfCanPerform(RPGSkill skill, Vector3 skillTargetLocation) 
		{
			Vector3 d = (skillTargetLocation - _tr.position);
			float m = d.magnitude;
			if (m > skill.onUseMaxTargetDistance) return 1; // too far
			d = d.normalized; d.y = _tr.forward.y;
			if (Vector3.Dot(_tr.forward, d) > 0.8f) return 0; // all good
			return 2; // need to turn
		}
Example #19
0
		// ============================================================================================================

		/// <summary>called by actor class when a skill is about to be executed</summary>
		public override void AboutToPerformSkill(RPGSkill skill)
		{
			navi.Stop();
			ani.ForceIdle();
			IsPerformingSkill = true;
		}
Example #20
0
		/// <summary>called by actor class when a skill's execution has stopped</summary>
		public override void DonePerformingSkill(RPGSkill skill)
		{
			IsPerformingSkill = false;
		}
Example #21
0
		/// <summary>
		/// called by actor to find out if it is ok to execute the skill?
		/// a plugin might want to return false here if it is still 
		/// turning the character to look at the skill's target
		/// </summary>
		public override bool CanPerformSkillNow(RPGSkill skill, Vector3 skillTargetLocation) { return true; }
Example #22
0
	private void CreateSkillCopy()
	{
		string name = curr.name;
		if (string.IsNullOrEmpty(name)) name = "Skill";

		UniRPGEditorGlobal.CheckDatabasePath(UniRPGEditorGlobal.DB_DATA_PATH, UniRPGEditorGlobal.DB_SKILLS_PATH);
		string fn = UniRPGEditorGlobal.DB_SKILLS_PATH + name + ".prefab";
		if (UniRPGEdUtil.RelativeFileExist(fn)) fn = AssetDatabase.GenerateUniqueAssetPath(fn);

		Object prefab = PrefabUtility.CreateEmptyPrefab(fn);
		GameObject go = new GameObject(name);							// create temp object in scene 
		go.AddComponent<RPGSkill>();
		GameObject toRef = PrefabUtility.ReplacePrefab(go, prefab);		// save prefab
		GameObject.DestroyImmediate(go);								// clear temp object from scene

		RPGSkill sk = toRef.GetComponent<RPGSkill>();
		sk.screenName = name;
		curr.CopyTo(sk);
		sk.id = UniRPG.GUID.Create();
		curr = sk;

		ed.db.skillPrefabs.Add(toRef);

		EditorUtility.SetDirty(curr);
		EditorUtility.SetDirty(ed.db);
		AssetDatabase.SaveAssets();
	}
Example #23
0
	/// <summary>checks if the character can use the skill. does it need a target and is target in range?</summary>
	public virtual bool IsSkillTargetInRange(RPGSkill s)
	{
		if (s == null) return false;
		if (s.targetMech == RPGSkill.TargetingMechanic.AroundOwner || s.targetMech == RPGSkill.TargetingMechanic.AroundLocation) return true;
		if (s.validTargetsMask == 0) return true; // "Nothing"
		if (s.validTargetsMask == UniRPGGlobal.Target.Self) return true;
		if (((int)UniRPGGlobal.Target.Self & (int)s.validTargetsMask) != 0) return true;
		if (s.validTargetsMask == 0 && TargetInteract == null) return true;
		if (TargetInteract == null) return false;
		if (s.IsValidTarget(TargetInteract.gameObject))
		{
			return (Mathf.Abs((TargetInteract.transform.position - _tr.position).sqrMagnitude) <= (s.onUseMaxTargetDistance * s.onUseMaxTargetDistance));
		}
		return false;
	}
Example #24
0
		public override bool CanPerformSkillNow(RPGSkill skill, Vector3 skillTargetLocation) 
		{
			if (skillTargetLocation == _tr.position) return true; // standing on top of target location
			if (IsLookingAt(skillTargetLocation)) return true;
			else navi.LookAt(skillTargetLocation);
			return false;
		}
Example #25
0
	/// <summary>called by actor class when a skill is about to be executed</summary>
	public virtual void AboutToPerformSkill(RPGSkill skill) { }
Example #26
0
	private void SetHoverSkill(RPGSkill skill)
	{
		if (skill == null)
		{
			if (Event.current.type == EventType.repaint && !hoverDetected)
			{
				hoverSkill = null;
			}
		}
		else
		{
			if (hoverSkill == null) hoverSkip = true;
			hoverDetected = true;
			hoverSkill = skill;
			GUI.tooltip = "";
		}
	}
Example #27
0
	public void CancelAOETargeting()
	{
		if (AOESkill != null)
		{
			AOESkill.HideAOEMarker();
		}

		AOESkill = null;
		InAOESelectMode = false;
	}