/// <summary> /// Example code on how to force which attack style to use. /// </summary> /// <param name="rCombatant">Combatant the event was fired for</param> /// <param name="rMotion">Motion that represents the attack</param> /// <returns></returns> private bool OnAttackActivated(Combatant rCombatant, MotionControllerMotion rMotion) { BasicSpellCasting lAttacks = rMotion as BasicSpellCasting; if (lAttacks != null) { lAttacks.SpellIndex = 0; } return(true); }
private void OnGUI() { if (MotionController == null || SpellInventory == null) { GUI.Label(new Rect(10, 10, 300, 20), "No Motion Controller or Spell Inventory Set!"); return; } float lWidth = 60f; float lHeight = 45f; float lSpacer = 10f; int lSpellCount = Mathf.Min(SpellInventory._Spells.Count, SpellIndexes.Count); float lBarWidth = (lSpellCount * lWidth) + ((lSpellCount - 1) * lSpacer); float lBarX = (Screen.width - lBarWidth) * 0.5f; float lBarY = (Screen.height - lHeight - lSpacer); for (int i = 0; i < lSpellCount; i++) { int lIndex = SpellIndexes[i]; string lName = SpellInventory._Spells[lIndex].Name.Replace(" ", "\n"); if (GUI.Button(new Rect(lBarX + ((lWidth + lSpacer) * i), lBarY, lWidth, lHeight), lName)) { BasicSpellCasting lCastMotion = MotionController.GetMotion <BasicSpellCasting>(); if (!lCastMotion.IsActive && (!lCastMotion.RequiresStance || MotionController.ActorController.State.Stance == EnumControllerStance.SPELL_CASTING)) { MotionController.ActivateMotion(lCastMotion, lIndex); } } } //if (GUI.Button(new Rect(10f, lHeight + lSpacer, lWidth, lHeight), "Interrupt")) //{ // MotionControllerMotion lMotion = MotionController.GetActiveMotion(0); // lMotion.Interrupt(null); //} }
/// <summary> /// Called each frame /// </summary> private void Update() { if (!IsActive) { return; } if (mCombatant == null) { return; } if (Target == null) { return; } MotionControllerMotion lMotion = mMotionController.ActiveMotion; if (lMotion == null) { return; } MotionControllerMotion lTargetMotion = mTargetMotionController.ActiveMotion; // Determine if we rotate to the target bool lRotate = true; // Ensure our weapon is equipped //if (!mBasicInventory.IsWeaponSetEquipped(2)) //{ // if (mLastEquipTime + AttackDelay < Time.time) // { // mBasicInventory.EquipWeaponSet(2); // mLastEquipTime = Time.time; // } //} //// The main AI loop //else //{ Vector3 lToTarget = Target._Transform.position - transform.position; lToTarget.y = 0f; Vector3 lToTargetDirection = lToTarget.normalized; float lToTargetDistance = lToTarget.magnitude; bool lIsTargetAimingAtMe = false; #if USE_ARCHERY_MP || OOTII_AYMP //float lTargetToMeHorizontalAngle = NumberHelper.GetHorizontalAngle(Target._Transform.forward, -lToTargetDirection, Target._Transform.up); //lIsTargetAimingAtMe = ((lTargetMotion is Bow_WalkRunTarget || lTargetMotion is Bow_BasicAttacks) && Mathf.Abs(lTargetToMeHorizontalAngle) < 10f); #endif // Determine if we should move to the target float lRange = Range; if (!mFollow && lToTargetDistance > lRange + 1f) { mFollow = true; } if (mFollow && lToTargetDistance <= lRange) { mFollow = false; } if (mFollow && (lMotion.Category != EnumMotionCategories.IDLE && lMotion.Category != EnumMotionCategories.WALK)) { mFollow = false; } if (mFollow && lIsTargetAimingAtMe) { mFollow = false; } if (!Move) { mFollow = false; } // Ensure we're not casting if (mMotionController.ActiveMotion is BasicSpellCasting) { } // Cast a healing spell else if (Cast && mLastCastTime + CastDelay < Time.time && mBasicAttributes != null && mBasicAttributes.GetAttributeValue <float>("Health", 100f) < 40f && mSpellInventory != null && mSpellInventory.GetSpellIndex("Heal Self") >= 0) { int lSpellIndex = mSpellInventory.GetSpellIndex("Heal Self"); if (lSpellIndex >= 0) { BasicSpellCasting lCastMotion = mMotionController.GetMotion <BasicSpellCasting>(); mMotionController.ActivateMotion(lCastMotion, lSpellIndex); mLastCastTime = Time.time; } } // Move to the target else if (mFollow) { float lSpeed = Mathf.Min(MovementSpeed * Time.deltaTime, lToTargetDistance); transform.position = transform.position + (lToTargetDirection * lSpeed); } // If we're being shot at, block else if (Block && lIsTargetAimingAtMe) { mFollow = false; CombatMessage lMessage = CombatMessage.Allocate(); lMessage.ID = CombatMessage.MSG_COMBATANT_BLOCK; lMessage.Attacker = null; lMessage.Defender = gameObject; mMotionController.SendMessage(lMessage); CombatMessage.Release(lMessage); } // Let the movement finish up else if (lMotion.Category == EnumMotionCategories.WALK) { } // Attack with the sword else if (Attack && lMotion.Category == EnumMotionCategories.IDLE && (mLastAttackTime + AttackDelay < Time.time)) { CombatMessage lMessage = CombatMessage.Allocate(); lMessage.ID = CombatMessage.MSG_COMBATANT_ATTACK; lMessage.Attacker = gameObject; lMessage.Defender = Target.gameObject; mMotionController.SendMessage(lMessage); CombatMessage.Release(lMessage); mLastAttackTime = Time.time; } // Block with the shield else if (Block && lMotion.Category == EnumMotionCategories.IDLE && lMotion.Age > 0.5f) { CombatMessage lMessage = CombatMessage.Allocate(); lMessage.ID = CombatMessage.MSG_COMBATANT_BLOCK; lMessage.Attacker = null; lMessage.Defender = gameObject; mMotionController.SendMessage(lMessage); CombatMessage.Release(lMessage); } // Free the block else if (lMotion.Category == EnumMotionCategories.COMBAT_MELEE_BLOCK && (lToTargetDistance > lRange + 1f || lMotion.Age > BlockHold)) { CombatMessage lMessage = CombatMessage.Allocate(); lMessage.ID = CombatMessage.MSG_COMBATANT_CANCEL; lMessage.Attacker = null; lMessage.Defender = gameObject; mMotionController.SendMessage(lMessage); CombatMessage.Release(lMessage); } // Allow rotation only if (mMotionController.enabled && lRotate) { float lAngle = NumberHelper.GetHorizontalAngle(transform.forward, lToTargetDirection, transform.up); if (lAngle != 0f) { float lRotationSpeed = Mathf.Sign(lAngle) * Mathf.Min(RotationSpeed * Time.deltaTime, Mathf.Abs(lAngle)); transform.rotation = transform.rotation * Quaternion.AngleAxis(lRotationSpeed, transform.up); } } //} // If we're dead, we can just stop if (lMotion.Category == EnumMotionCategories.DEATH) { IsActive = false; } // Clear the target if they are dead else if (Target != null && !Target.enabled) { Target = null; //StartCoroutine(WaitAndStoreEquipment(2f)); } }