/// <summary> /// Draws out the primary weapon debug info /// </summary> protected void DrawWeaponDebug(IWeaponCore rWeapon, Vector3 rForward, float rHorizontalFOA, float rVerticalFOA, Color rColor) { #if UNITY_EDITOR if (rWeapon == null) { return; } if (ShowDebug) { if (mCombatant != null) { if (rWeapon.HasColliders) { WeaponCore lWeaponCore = rWeapon as WeaponCore; if (lWeaponCore != null) { Graphics.GraphicsManager.DrawCollider(lWeaponCore.Collider as BoxCollider, rColor); } } else { float lMinReach = mCombatant.MinMeleeReach + rWeapon.MinRange; float lMaxReach = mCombatant.MaxMeleeReach + rWeapon.MaxRange; Vector3 lCombatOrigin = mCombatant.CombatOrigin; Graphics.GraphicsManager.DrawSolidFrustum(lCombatOrigin, mCombatant.Transform.rotation * Quaternion.LookRotation(rForward, mCombatant.Transform.up), rHorizontalFOA, rVerticalFOA, lMinReach, lMaxReach, rColor); //Graphics.GraphicsManager.DrawText(string.Format("Weapon: {0:f1}/{1:f1}", rWeapon.Health, rWeapon.MaxHealth), rWeapon.gameObject.transform.position + (Vector3.up * 0.4f), Color.black); } } } #endif }
/// <summary> /// Draws out the primary weapon debug info /// </summary> protected void DrawWeaponDebug(ICombatant rCombatant, IWeaponCore rWeapon, ICombatStyle rAttackStyle, Color rColor) { #if UNITY_EDITOR if (rCombatant == null) { return; } if (rWeapon == null) { return; } if (ShowDebug) { if (rWeapon.HasColliders) { WeaponCore lWeaponCore = rWeapon as WeaponCore; if (lWeaponCore != null) { Graphics.GraphicsManager.DrawCollider(lWeaponCore.Collider as BoxCollider, rColor); } } else if (rAttackStyle != null) { float lMinReach = (rAttackStyle.MinRange > 0f ? rAttackStyle.MinRange : rCombatant.MinMeleeReach + rWeapon.MinRange); float lMaxReach = (rAttackStyle.MaxRange > 0f ? rAttackStyle.MaxRange : rCombatant.MaxMeleeReach + rWeapon.MaxRange); Vector3 lCombatOrigin = rCombatant.CombatOrigin; Graphics.GraphicsManager.DrawSolidFrustum(lCombatOrigin, rCombatant.Transform.rotation * Quaternion.LookRotation(rAttackStyle.Forward, rCombatant.Transform.up), rAttackStyle.HorizontalFOA, rAttackStyle.VerticalFOA, lMinReach, lMaxReach, rColor); } } #endif }
/// <summary> /// Creates the item and attaches it to the parent mount point /// </summary> /// <param name="rParent">GameObject that is the parent (typically a character)</param> /// <param name="rResourcePath">String that is the resource path to the item</param> /// <param name="rLocalPosition">Position the item will have relative to the parent mount point</param> /// <param name="rLocalRotation">Rotation the item will have relative to the parent mount pont</param> /// <returns></returns> protected GameObject CreateAndMountItem(GameObject rParent, string rResourcePath, Vector3 rLocalPosition, Quaternion rLocalRotation, string rParentMountPoint = "Left Hand", string rItemMountPoint = "Handle") { GameObject lItem = null; if (rResourcePath.Length > 0) { #if USE_MOUNT_POINTS if (mMountPoints != null) { lItem = mMountPoints.ConnectMountPoints(rParentMountPoint, rResourcePath, rItemMountPoint); } #endif // Create and mount if we need to if (lItem == null) { Animator lAnimator = rParent.GetComponentInChildren <Animator>(); if (lAnimator != null) { UnityEngine.Object lResource = Resources.Load(rResourcePath); if (lResource != null) { lItem = GameObject.Instantiate(lResource) as GameObject; MountItem(rParent, lItem, rLocalPosition, rLocalRotation, rParentMountPoint); } else { Debug.LogWarning("Resource not found. Resource Path: " + rResourcePath); } } } // Inform the combatant of the change else { ICombatant lCombatant = gameObject.GetComponent <ICombatant>(); if (lCombatant != null) { IWeaponCore lWeaponCore = lItem.GetComponent <IWeaponCore>(); if (lWeaponCore != null) { string lCleanParentMountPoint = StringHelper.CleanString(rParentMountPoint); if (lCleanParentMountPoint == "righthand") { lCombatant.PrimaryWeapon = lWeaponCore; } else if (lCleanParentMountPoint == "lefthand" || lCleanParentMountPoint == "leftlowerarm") { lCombatant.SecondaryWeapon = lWeaponCore; } } } } } return(lItem); }
/// <summary> /// Mounts the item to the specified position based on the ItemCore /// </summary> /// <param name="rParent"></param> /// <param name="rItem"></param> /// <param name="rParentMountPoint"></param> protected void MountItem(GameObject rParent, GameObject rItem, string rParentMountPoint, string rItemMountPoint = "Handle") { if (rParent == null || rItem == null) { return; } bool lIsConnected = false; #if USE_MOUNT_POINTS com.ootii.Actors.MountPoints lMountPoints = rParent.GetComponent <com.ootii.Actors.MountPoints>(); if (lMountPoints != null) { lIsConnected = lMountPoints.ConnectMountPoints(rParentMountPoint, rItem, rItemMountPoint); } #endif if (!lIsConnected) { Transform lParentBone = FindTransform(rParent.transform, rParentMountPoint); rItem.transform.parent = lParentBone; //IItemCore lItemCore = InterfaceHelper.GetComponent<IItemCore>(rItem); IItemCore lItemCore = rItem.GetComponent <IItemCore>(); if (lItemCore != null) { lItemCore.Owner = gameObject; rItem.transform.localPosition = (lItemCore != null ? lItemCore.LocalPosition : Vector3.zero); rItem.transform.localRotation = (lItemCore != null ? lItemCore.LocalRotation : Quaternion.identity); } } // Inform the combatant of the change if (rItem != null) { ICombatant lCombatant = gameObject.GetComponent <ICombatant>(); if (lCombatant != null) { IWeaponCore lWeaponCore = rItem.GetComponent <IWeaponCore>(); if (lWeaponCore != null) { string lCleanParentMountPoint = StringHelper.CleanString(rParentMountPoint); if (lCleanParentMountPoint == "righthand") { lCombatant.PrimaryWeapon = lWeaponCore; } else if (lCleanParentMountPoint == "lefthand") { lCombatant.SecondaryWeapon = lWeaponCore; } } } } }
/// <summary> /// Clear this instance. /// </summary> public override void Clear() { Attacker = null; Defender = null; Weapon = null; StyleIndex = -1; CombatStyle = null; HitTransform = null; base.Clear(); }
/// <summary> /// Grab all the combat targets that could be affected by the style and weapon /// </summary> /// <param name="rStyle">AttackStyle that defines the field-of-attack</param> /// <param name="rWeapon">Weapon that is currently being used</param> /// <param name="rCombatTargets">List of CombatTargets we will fill with the results</param> /// <param name="rIgnore">Combatant to ignore. Typically this is the character asking for the query.</param> /// <returns></returns> public virtual int QueryCombatTargets(AttackStyle rAttackStyle, IWeaponCore rWeapon, List <CombatTarget> rCombatTargets, Transform rIgnore) { IWeaponCore lWeapon = (rWeapon != null ? rWeapon : mPrimaryWeapon); CombatFilter lFilter = new CombatFilter(rAttackStyle); lFilter.MinDistance = (rAttackStyle.MinRange > 0f ? rAttackStyle.MinRange : _MinMeleeReach + lWeapon.MinRange); lFilter.MaxDistance = (rAttackStyle.MaxRange > 0f ? rAttackStyle.MaxRange : _MaxMeleeReach + lWeapon.MaxRange); rCombatTargets.Clear(); int lTargetCount = CombatManager.QueryCombatTargets(_Transform, CombatOrigin, lFilter, rCombatTargets, rIgnore); return(lTargetCount); }
/// <summary> /// Creates the item and attaches it to the parent mount point /// </summary> /// <param name="rParent">GameObject that is the parent (typically a character)</param> /// <param name="rResourcePath">String that is the resource path to the item</param> /// <param name="rLocalPosition">Position the item will have relative to the parent mount point</param> /// <param name="rLocalRotation">Rotation the item will have relative to the parent mount pont</param> /// <returns></returns> protected GameObject CreateAndMountItem(GameObject rParent, string rResourcePath, string rParentMountPoint = "Left Hand", string rItemMountPoint = "Handle") { GameObject lItem = null; if (rResourcePath.Length > 0) { #if USE_MOUNT_POINTS com.ootii.Actors.MountPoints lMountPoints = rParent.GetComponent <com.ootii.Actors.MountPoints>(); if (lMountPoints != null) { lItem = lMountPoints.ConnectMountPoints(rParentMountPoint, rResourcePath, rItemMountPoint); } #endif // Create and mount if we need to if (lItem == null) { Animator lAnimator = rParent.GetComponentInChildren <Animator>(); if (lAnimator != null) { lItem = GameObject.Instantiate(Resources.Load(rResourcePath)) as GameObject; MountItem(rParent, lItem, rParentMountPoint); } } // Inform the combatant of the change else { ICombatant lCombatant = gameObject.GetComponent <ICombatant>(); if (lCombatant != null) { IWeaponCore lWeaponCore = lItem.GetComponent <IWeaponCore>(); if (lWeaponCore != null) { string lCleanParentMountPoint = StringHelper.CleanString(rParentMountPoint); if (lCleanParentMountPoint == "righthand") { lCombatant.PrimaryWeapon = lWeaponCore; } else if (lCleanParentMountPoint == "lefthand") { lCombatant.SecondaryWeapon = lWeaponCore; } } } } } return(lItem); }
/// <summary> /// Capture Unity's collision event. We use triggers since IsKinematic Rigidbodies don't /// raise collisions... only triggers. /// </summary> protected virtual void OnTriggerEnter(Collider rCollider) { //com.ootii.Utilities.Debug.Log.FileWrite(transform.name + ".OnTriggerEnter(" + rCollider.name + ")"); if (!mIsActive) { return; } // Ensure we're not hitting ourselves if (mOwner != null) { if (rCollider.gameObject == mOwner) { return; } IWeaponCore lWeaponCore = rCollider.gameObject.GetComponent <WeaponCore>(); if (lWeaponCore != null && lWeaponCore.Owner == mOwner) { return; } if (IsDescendant(mOwner.transform, rCollider.transform)) { return; } } Vector3 lClosestPoint = GeometryExt.ClosestPoint(mLastPosition, rCollider); if (lClosestPoint != Vector3Ext.Null) { Vector3 lVector = (mTransform.position - mLastPosition).normalized; if (lVector.sqrMagnitude == 0 && mOwner != null) { lVector = mOwner.transform.forward; } mLastHit.Collider = rCollider; mLastHit.Point = lClosestPoint; mLastHit.Normal = -lVector; mLastHit.Vector = lVector; mLastHit.Distance = 0f; mLastHit.Index = mImpactCount; OnImpact(mLastHit, mAttackStyle); } }
/// <summary> /// Clear this instance. /// </summary> public virtual void Clear() { mType = ""; mSender = null; mRecipient = null; mID = 0; mData = null; mIsSent = false; mIsHandled = false; mDelay = 0.0f; Attacker = null; Defender = null; Weapon = null; CombatStyle = null; HitTransform = null; }
/// <summary> /// Instantiates the specified item and equips it. We return the instantiated item. /// </summary> /// <param name="rSlotID">String representing the name or ID of the slot to clear</param> public virtual void StoreItem(string rSlotID) { int lSlotIndex = -1; for (int i = 0; i < Slots.Count; i++) { if (Slots[i].ID == rSlotID) { lSlotIndex = i; break; } } if (lSlotIndex < 0) { return; } BasicInventorySlot lSlot = Slots[lSlotIndex]; if (lSlot == null) { return; } BasicInventoryItem lItem = null; for (int i = 0; i < Items.Count; i++) { if (Items[i].ID == lSlot.ItemID) { lItem = Items[i]; break; } } // We need to disconnect the item, but we may need to destroy it as well if (lItem != null && lItem.Instance != null) { IItemCore lItemCore = lItem.Instance.GetComponent <IItemCore>(); if (lItemCore != null) { lItemCore.OnStored(); } // If we know about a combatant, disconnect the weapon ICombatant lCombatant = gameObject.GetComponent <ICombatant>(); if (lCombatant != null) { IWeaponCore lWeaponCore = lItem.Instance.GetComponent <IWeaponCore>(); if (lWeaponCore != null) { if (lCombatant.PrimaryWeapon == lWeaponCore) { lCombatant.PrimaryWeapon = null; } if (lCombatant.SecondaryWeapon == lWeaponCore) { lCombatant.SecondaryWeapon = null; } } } #if USE_MOUNT_POINTS if (mMountPoints != null) { MountPoint lParentMountPoint = mMountPoints.GetMountPoint(lSlot.ID); if (lParentMountPoint != null) { mMountPoints.DisconnectMountPoints(lParentMountPoint, lItem.Instance); } } #endif // Without a stored parent, we destroy it if (lItem.StoredParent == null) { GameObject.Destroy(lItem.Instance); lItem.Instance = null; } else { bool lIsAttached = false; #if USE_MOUNT_POINTS // See if we can attach it using a mount point if (mMountPoints != null) { MountPoint lParentMountPoint = mMountPoints.GetMountPoint(lItem.StoredParent.name); if (lParentMountPoint == null) { lParentMountPoint = mMountPoints.GetMountPoint(lItem.StoredParent); } if (lParentMountPoint != null) { lIsAttached = mMountPoints.ConnectMountPoints(lParentMountPoint, lItem.Instance, "Handle"); } } #endif if (!lIsAttached) { lItem.Instance.transform.parent = lItem.StoredParent; lItem.Instance.transform.localPosition = lItem.StoredPosition; lItem.Instance.transform.localRotation = lItem.StoredRotation; } } } lSlot.ItemID = ""; }
/// <summary> /// Mounts the item to the specified position based on the ItemCore /// </summary> /// <param name="rParent">Parent GameObject</param> /// <param name="rItem">Child GameObject that is this item</param> /// <param name="rLocalPosition">Vector3 that is the local position to set when the item is parented.</param> /// <param name="rLocalRotation">Quaternion that is the local rotation to set when the item is parented.</param> /// <param name="rParentMountPoint">Name of the parent mount point we're tying the item to</param> /// <param name="rItemMountPoint">Name of the child mount point we're tying the item to</param> protected virtual void MountItem(GameObject rParent, GameObject rItem, Vector3 rLocalPosition, Quaternion rLocalRotation, string rParentMountPoint, string rItemMountPoint = "Handle") { if (rParent == null || rItem == null) { return; } bool lIsConnected = false; Transform lParentBone = FindTransform(rParent.transform, rParentMountPoint); rItem.transform.parent = lParentBone; //IItemCore lItemCore = InterfaceHelper.GetComponent<IItemCore>(rItem); IItemCore lItemCore = rItem.GetComponent <IItemCore>(); if (lItemCore != null) { lItemCore.Owner = mMotionController.gameObject; if (rLocalPosition.sqrMagnitude == 0f && QuaternionExt.IsIdentity(rLocalRotation)) { rItem.transform.localPosition = (lItemCore.LocalPosition); rItem.transform.localRotation = (lItemCore.LocalRotation); } else { rItem.transform.localPosition = rLocalPosition; rItem.transform.localRotation = rLocalRotation; } } else { rItem.transform.localPosition = rLocalPosition; rItem.transform.localRotation = rLocalRotation; } // Reenable the item as needed rItem.SetActive(true); rItem.hideFlags = HideFlags.None; // Inform the combatant of the change ICombatant lCombatant = mMotionController.gameObject.GetComponent <ICombatant>(); if (lCombatant != null) { IWeaponCore lWeaponCore = rItem.GetComponent <IWeaponCore>(); if (lWeaponCore != null) { string lCleanParentMountPoint = StringHelper.CleanString(rParentMountPoint); if (lCleanParentMountPoint == "righthand") { lCombatant.PrimaryWeapon = lWeaponCore; } else if (lCleanParentMountPoint == "lefthand" || lCleanParentMountPoint == "leftlowerarm") { lCombatant.SecondaryWeapon = lWeaponCore; } } } }
/// <summary> /// Activates the action on a single target /// </summary> /// <param name="rTarget">Target to activate on</param> protected void ActivateInstance(GameObject rTarget) { Vector3 lPoint = rTarget.transform.position; Vector3 lForward = rTarget.transform.forward; // Combatant that is attacking ICombatant lAttacker = (_Spell.Owner != null ? _Spell.Owner.GetComponent <ICombatant>() : null); // Determine who we're colliding with IActorCore lDefenderCore = rTarget.GetComponent <IActorCore>(); IDamageable lDamageable = rTarget.GetComponent <IDamageable>(); if (lDefenderCore == null) { IWeaponCore lWeaponCore = rTarget.GetComponent <IWeaponCore>(); if (lWeaponCore != null) { lDefenderCore = lWeaponCore.Owner.GetComponent <IActorCore>(); if (lDamageable == null) { lDamageable = lWeaponCore.Owner.GetComponent <IDamageable>(); } } } // Save the hit information Transform lHitTransform = GetClosestTransform(lPoint, rTarget.transform); Vector3 lCombatCenter = lHitTransform.position; Vector3 lHitDirection = Vector3.zero; if (lDefenderCore != null) { ICombatant lDefenderCombatant = lDefenderCore.gameObject.GetComponent <ICombatant>(); if (lDefenderCombatant != null) { lHitDirection = Quaternion.Inverse(lDefenderCore.Transform.rotation) * (lPoint - lDefenderCombatant.CombatOrigin).normalized; } } else { lHitDirection = Quaternion.Inverse(lHitTransform.rotation) * (lPoint - lCombatCenter).normalized; } // Determine the damage float lDamage = UnityEngine.Random.Range(_MinDamage, _MaxDamage); if (_DamageFloatValueIndex >= 0 && _Spell.Data.FloatValues != null) { lDamage = _Spell.Data.FloatValues[_DamageFloatValueIndex]; } // Put together the combat round info CombatMessage lCombatMessage = CombatMessage.Allocate(); lCombatMessage.ID = CombatMessage.MSG_DEFENDER_ATTACKED; lCombatMessage.Attacker = (lAttacker != null ? lAttacker.Transform.gameObject : _Spell.Owner); lCombatMessage.Defender = (lDefenderCore != null ? lDefenderCore.Transform.gameObject : rTarget); lCombatMessage.Weapon = null; lCombatMessage.DamageType = _DamageType; lCombatMessage.ImpactType = _ImpactType; lCombatMessage.Damage = lDamage; lCombatMessage.AnimationEnabled = _PlayAnimation; lCombatMessage.HitPoint = lPoint; lCombatMessage.HitDirection = lHitDirection; lCombatMessage.HitVector = lForward; lCombatMessage.HitTransform = lHitTransform; // Let the defender react to the damage if (lDefenderCore != null) { lDefenderCore.SendMessage(lCombatMessage); } // If needed, send the damage directly to the actor core else if (lDamageable != null) { lDamageable.OnDamaged(lCombatMessage); } // Without an actor core, check if we can set attributes else { IAttributeSource lAttributeSource = rTarget.GetComponent <IAttributeSource>(); if (lAttributeSource != null) { float lHealth = lAttributeSource.GetAttributeValue <float>(EnumAttributeIDs.HEALTH); lAttributeSource.SetAttributeValue(EnumAttributeIDs.HEALTH, Mathf.Max(lHealth - lCombatMessage.Damage, 0f)); } } // Release the message lCombatMessage.Release(); }
/// <summary> /// Draws out the primary weapon debug info /// </summary> protected void DrawWeaponDebug(IWeaponCore rWeapon, ICombatStyle rAttackStyle, Color rColor) { #if UNITY_EDITOR DrawWeaponDebug(mCombatant, rWeapon, rAttackStyle, rColor); #endif }