protected virtual float TargetAOETick(IAbilityCaster source, Interactable target, AbilityEffectContext abilityEffectInput) { //Debug.Log(DisplayName + "AOEEffect.TargetAOETick(" + (source == null ? "null" : source.AbilityManager.Name) + ", " + (target == null ? "null" : target.name) + ")"); List <AOETargetNode> validTargets = GetValidTargets(source, target, abilityEffectInput, tickAbilityEffectList); float accumulatedDelay = 0f; foreach (AOETargetNode validTarget in validTargets) { PerformAOETick(source, validTarget.targetGameObject, 1f / validTargets.Count, validTarget.abilityEffectInput, accumulatedDelay); accumulatedDelay += interTargetDelay; } return(validTargets.Count); }
private IEnumerator WaitForHitDelay(IAbilityCaster source, Interactable target, AbilityEffectContext modifiedOutput, float castDelay) { //Debug.Log(DisplayName + ".AOEEffect.WaitForHitDelay(" + source.AbilityManager.Name + ", " + (target == null ? "null" : target.name) + ")"); float accumulatedTime = 0f; while (accumulatedTime < castDelay) { yield return(null); accumulatedTime += Time.deltaTime; } PerformAbilityHit(source, target, modifiedOutput); }
public IEnumerator PerformAbilityHitDelay(IAbilityCaster source, GameObject target, AbilityEffectContext abilityEffectInput, ChanneledEffect channeledEffect) { //Debug.Log("ChanelledEffect.PerformAbilityEffectDelay()"); float timeRemaining = channeledEffect.effectDelay; while (timeRemaining > 0f) { yield return(null); timeRemaining -= Time.deltaTime; } channeledEffect.PerformAbilityHit(source, target, abilityEffectInput); abilityHitDelayCoroutine = null; }
public override bool ProcessAbilityHit(Interactable target, int finalAmount, IAbilityCaster source, CombatMagnitude combatMagnitude, AbilityEffect abilityEffect, AbilityEffectContext abilityEffectContext, PowerResource powerResource) { //Debug.Log(DisplayName + ".HealEffect.ProcessAbilityHit(" + (target == null ? "null" : target.gameObject.name) + ", " + finalAmount + ", " + source.AbilityManager.UnitGameObject.name + ")"); abilityEffectContext.powerResource = powerResource; bool returnValue = CharacterUnit.GetCharacterUnit(target).BaseCharacter.CharacterStats.RecoverResource(abilityEffectContext, powerResource, finalAmount, source, true, combatMagnitude); if (returnValue == false) { return(false); } return(base.ProcessAbilityHit(target, finalAmount, source, combatMagnitude, abilityEffect, abilityEffectContext, powerResource)); }
public override bool Cast(IAbilityCaster source, GameObject target, AbilityEffectContext abilityEffectContext) { //Debug.Log(MyName + ".InstantEffectAbility.Cast(" + source.name + ", " + (target == null ? "null" : target.name) + ", " + groundTarget + ")"); // this code could lead to a situation where an instanteffect was allowed to perform its ability effects even if the wrong weapon was equipped. // need to change cast to a bool to pass that success or not up the casting stack bool castResult = base.Cast(source, target, abilityEffectContext); if (castResult) { PerformAbilityEffects(source, target, abilityEffectContext); } return(castResult); }
public override bool CanUseOn(GameObject target, IAbilityCaster source, bool performCooldownChecks = true, AbilityEffectContext abilityEffectContext = null) { //Debug.Log("DirectAbility.CanUseOn(" + (target != null ? target.name : "null") + ")"); if (!base.CanUseOn(target, source, performCooldownChecks, abilityEffectContext)) { return(false); } if (!CanSimultaneousCast) { if (source.PerformingAbility) { return(false); } } return(true); }
private void OnDisable() { //Debug.Log(gameObject.name + " " + gameObject.GetInstanceID() + ".ProjectileScript.OnDisable()"); if (SystemGameManager.IsShuttingDown) { return; } projectileGameObject = null; source = null; target = null; positionOffset = Vector3.zero; targetPosition = Vector3.zero; velocity = 0f; initialized = false; abilityEffectContext = null; OnCollission = delegate { }; }
public override AbilityEffectContext ProcessAbilityEffectContext(IAbilityCaster source, Interactable target, AbilityEffectContext abilityEffectContext) { if (abilityEffectContext.weaponHitHasCast == true) { // can't cast weapon hit effects more than once return(base.ProcessAbilityEffectContext(source, target, abilityEffectContext)); } // since this is called from any attackeffect (even stuff like fireballs) and sets the weapon cast to true, // this will also limit cast time multipliers on future effects. // This should be ok because the primary hit of a fireball would be regular damage, and any hit after that is likely // on hit, burn effect, etc, which should not be multiplied by cast time abilityEffectContext.weaponHitHasCast = true; source.AbilityManager.ProcessWeaponHitEffects(this, target, abilityEffectContext); return(abilityEffectContext); }
public override List <AbilityAttachmentNode> GetHoldableObjectList(IAbilityCaster abilityCaster) { if (CraftingUI.MyInstance.CraftingQueue.Count > 0) { List <AbilityAttachmentNode> returnList = new List <AbilityAttachmentNode>(); foreach (AbilityAttachmentNode prefabProfile in base.GetHoldableObjectList(abilityCaster)) { returnList.Add(prefabProfile); } foreach (AbilityAttachmentNode abilityAttachmentNode in CraftingUI.MyInstance.CraftingQueue[0].HoldableObjectList) { returnList.Add(abilityAttachmentNode); } return(returnList); } return(base.GetHoldableObjectList(abilityCaster)); }
protected virtual float TargetAOEComplete(IAbilityCaster source, Interactable target, AbilityEffectContext abilityEffectInput) { //Debug.Log(MyName + "AOEEffect.TargetAOEComplete(" + (source == null ? "null" : source.name) + ", " + (target == null ? "null" : target.name) + ")"); if (completeAbilityEffectList == null | completeAbilityEffectList.Count == 0) { return(0); } List <AOETargetNode> validTargets = GetValidTargets(source, target, abilityEffectInput, completeAbilityEffectList); float accumulatedDelay = 0f; foreach (AOETargetNode validTarget in validTargets) { PerformAOEComplete(source, validTarget.targetGameObject, 1f / validTargets.Count, validTarget.abilityEffectInput, accumulatedDelay); accumulatedDelay += interTargetDelay; } return(validTargets.Count); }
public override bool CanUseOn(GameObject target, IAbilityCaster sourceCharacter, bool performCooldownChecks = true, AbilityEffectContext abilityEffectContext = null) { //Debug.Log(MyName + ".GatherAbility.CanUseOn(" + (target == null ? "null" : target.name) + ", " + (sourceCharacter == null ? "null" : sourceCharacter.MyName) + ")"); if (target != null) { //Debug.Log("GatherAbility.CanUseOn(" + target.name + ")"); } else { //Debug.Log("GatherAbility.CanUseOn(null)"); } if (!base.CanUseOn(target, sourceCharacter, performCooldownChecks, abilityEffectContext)) { return(false); } // distance from center of character to whereever the raycast hit the object //float distanceToTarget = Vector3.Distance((PlayerManager.MyInstance.MyCharacter.MyCharacterController as PlayerController).MyMouseOverhit.point, source.UnitGameObject.transform.TransformPoint(source.MyCharacterUnit.GetComponent<CapsuleCollider>().center)); //Debug.Log("PlayerManager.MyInstance.MyCharacter.MyCharacterController.MyMouseOverhit.point: " + PlayerManager.MyInstance.MyCharacter.MyCharacterController.MyMouseOverhit.point); /* * if (distanceToTarget > (source.MyCharacterStats.MyHitBox * 2)) { * //Debug.Log(target.name + " is out of range: " + distanceToTarget); * MessageFeedManager.MyInstance.WriteMessage("Gathering node was out of range"); * return false; * } */ GatheringNode _gatheringNode = target.GetComponent <GatheringNode>(); if (_gatheringNode == null) { //Debug.Log("You cannot use " + MyName + " on: " + target.name); return(false); } if (_gatheringNode.MyAbility == this) { return(true); } else { //Debug.Log(target.name + " requires ability: " + _gatheringNode.MyAbility); return(false); } }
public override bool CanUseOn(GameObject target, IAbilityCaster source, AbilityEffectContext abilityEffectContext = null) { if (target == null) { return(false); } CharacterUnit characterUnit = target.GetComponent <CharacterUnit>(); if (characterUnit == null) { return(false); } if (characterUnit.MyCharacter.CharacterStats.IsAlive == false && characterUnit.MyCharacter.CharacterStats.IsReviving == false) { return(true); } return(false); }
public override bool CanUseOn(Interactable target, IAbilityCaster sourceCharacter, bool performCooldownChecks = true, AbilityEffectContext abilityEffectContext = null, bool playerInitiated = false, bool performRangeCheck = true) { //Debug.Log(MyName + ".GatherAbility.CanUseOn(" + (target == null ? "null" : target.name) + ", " + (sourceCharacter == null ? "null" : sourceCharacter.AbilityManager.MyName) + ")"); if (!base.CanUseOn(target, sourceCharacter, performCooldownChecks, abilityEffectContext, playerInitiated, performRangeCheck)) { return(false); } if (target == null) { if (playerInitiated) { sourceCharacter.AbilityManager.ReceiveCombatMessage("Cannot cast " + resourceName + ". Gathering requires a target."); } return(false); } GatheringNodeComponent gatheringNodeComponent = GatheringNodeComponent.GetGatheringNodeComponent(target); if (gatheringNodeComponent == null) { //Debug.Log("You cannot use " + MyName + " on: " + target.name); if (playerInitiated) { sourceCharacter.AbilityManager.ReceiveCombatMessage("Cannot cast " + resourceName + ". This ability must target a gathering node"); } return(false); } if (gatheringNodeComponent.GatheringNodeProps.BaseAbility == this) { return(true); } else { //Debug.Log(target.name + " requires ability: " + _gatheringNode.MyAbility); if (playerInitiated) { sourceCharacter.AbilityManager.ReceiveCombatMessage("Cannot cast " + resourceName + ". This gathering node requires the skill : " + gatheringNodeComponent.GatheringNodeProps.BaseAbility.DisplayName); } return(false); } }
public override bool CanUseOn(Interactable target, IAbilityCaster source, bool performCooldownChecks = true, AbilityEffectContext abilityEffectContext = null, bool playerInitiated = false, bool performRangeChecks = true) { //Debug.Log("DirectAbility.CanUseOn(" + (target != null ? target.name : "null") + ")"); if (!base.CanUseOn(target, source, performCooldownChecks, abilityEffectContext, playerInitiated, performRangeChecks)) { return(false); } if (!CanSimultaneousCast) { if (source.AbilityManager.PerformingAbility) { if (playerInitiated) { source.AbilityManager.ReceiveCombatMessage("Cannot cast " + resourceName + ". another cast is in progress"); } return(false); } } return(true); }
public override Dictionary <PrefabProfile, GameObject> Cast(IAbilityCaster source, Interactable target, Interactable originalTarget, AbilityEffectContext abilityEffectInput) { if (target == null) { //Debug.Log(DisplayName + ".CapturePetEffect.Cast(): target is null, returning"); return(null); } Dictionary <PrefabProfile, GameObject> returnValue = base.Cast(source, target, originalTarget, abilityEffectInput); UnitController targetUnitController = target.GetComponent <UnitController>(); if (targetUnitController != null) { //Debug.Log(DisplayName + ".CapturePetEffect.Cast(): applying control effects"); source.AbilityManager.CapturePet(targetUnitController); } return(returnValue); }
public override bool CanUseOn(Interactable target, IAbilityCaster sourceCharacter, AbilityEffectContext abilityEffectContext = null, bool playerInitiated = false, bool performRangeCheck = true) { if (target == null) { return(false); } UnitController unitController = target as UnitController; if (unitController == null || unitController.UnitProfile == null || unitController.UnitProfile.IsPet == false) { // has to be the right unit type plus needs to be capturable specifically //Debug.Log(DisplayName + ".CapturePetEffect.CanUseOn(): pet was not capturable "); if (playerInitiated) { sourceCharacter.AbilityManager.ReceiveCombatMessage("Cannot cast " + resourceName + ". Target must be a capturable pet"); } return(false); } return(base.CanUseOn(target, sourceCharacter, abilityEffectContext, playerInitiated, performRangeCheck)); }
public override bool Cast(IAbilityCaster source, GameObject target, AbilityEffectContext abilityEffectContext) { if (target == null) { return(false); } bool returnResult = base.Cast(source, target, abilityEffectContext); if (returnResult == true) { if (target != null) { target.GetComponent <GatheringNode>().Gather(); } else { //Debug.Log(MyName + ".GatherAbility.Cast(): target was null"); } } return(returnResult); }
public override bool CanUseOn(Interactable target, IAbilityCaster source, bool performCooldownChecks = true, AbilityEffectContext abilityEffectContext = null, bool playerInitiated = false, bool performRangeChecks = true) { if (!base.CanUseOn(target, source, performCooldownChecks, abilityEffectContext, playerInitiated, performRangeChecks)) { return(false); } // to prevent casting this ability on a valid crafting target from action bars with no recipe to make, it is not possible to cast if there is nothing in the queue if (CraftingUI.MyInstance.CraftingQueue.Count == 0) { return(false); } List <CraftingNodeComponent> craftingNodeComponents = CraftingNodeComponent.GetCraftingNodeComponents(target); if (craftingNodeComponents == null || craftingNodeComponents.Count == 0) { //Debug.Log("You cannot use " + MyName + " on: " + target.name); if (playerInitiated) { source.AbilityManager.ReceiveCombatMessage("Cannot cast " + resourceName + ". This ability must target a crafting node"); } return(false); } foreach (CraftingNodeComponent craftingNodeComponent in craftingNodeComponents) { if (craftingNodeComponent.Props.Ability == this) { return(true); } } //Debug.Log(target.name + " requires ability: " + _gatheringNode.MyAbility); if (playerInitiated) { source.AbilityManager.ReceiveCombatMessage("Cannot cast " + resourceName + ". Target is not valid for this type of crafting"); } return(false); }
public void CheckPetSpawn(IAbilityCaster source, Interactable target, AbilityEffectContext abilityEffectInput) { //Debug.Log(DisplayName + ".PetEffect.CheckPetSpawn()"); CharacterPetManager characterPetManager = null; if ((source as BaseCharacter) is BaseCharacter) { characterPetManager = (source as BaseCharacter).CharacterPetManager; } else { //Debug.Log(DisplayName + ".PetEffect.CheckPetSpawn(): source is not basecharacter"); return; } List <AbilityEffect> castList = new List <AbilityEffect>(); foreach (SummonEffect petEffect in petEffectList) { if (SystemDataFactory.MatchResource(petEffect.DisplayName, DisplayName)) { Debug.LogError(DisplayName + ".PerformAbilityEffects(): circular reference detected. Tried to cast self. CHECK INSPECTOR AND FIX ABILITY EFFECT CONFIGURATION!!!"); } else { //Debug.Log(DisplayName + ".PetEffect.CheckPetSpawn(): adding to cast list"); if (petEffect.UnitProfile != null && characterPetManager.ActiveUnitProfiles.ContainsKey(petEffect.UnitProfile) == false) { //Debug.Log(DisplayName + ".PetEffect.CheckPetSpawn(): adding cast:" + petEffect.DisplayName); castList.Add(petEffect); } } } if (castList.Count > 0) { //Debug.Log(DisplayName + ".PetEffect.CheckPetSpawn(): castlist.count: " + castList.Count); Dictionary <PrefabProfile, GameObject> rawObjectList = PerformAbilityEffects(source, target, abilityEffectInput, castList); } }
public override Dictionary <PrefabProfile, GameObject> Cast(IAbilityCaster source, Interactable target, Interactable originalTarget, AbilityEffectContext abilityEffectInput) { //Debug.Log("StatusEffect.Cast(" + source.name + ", " + (target? target.name : "null") + ")"); if (!CanUseOn(target, source)) { return(null); } if (target == null) { // we can't mount anything if there is no target return(null); } Dictionary <PrefabProfile, GameObject> returnObjects = base.Cast(source, target, originalTarget, abilityEffectInput); UnitController mountUnitController = unitProfile.SpawnUnitPrefab(source.AbilityManager.UnitGameObject.transform.parent, source.AbilityManager.UnitGameObject.transform.position, source.AbilityManager.UnitGameObject.transform.forward, UnitControllerMode.Mount); if (mountUnitController != null) { source.AbilityManager.SetMountedState(mountUnitController, unitProfile); } return(returnObjects); }
public override bool CanUseOn(GameObject target, IAbilityCaster sourceCharacter, AbilityEffectContext abilityEffectContext = null) { if (target == null) { return(false); } CharacterUnit characterUnit = target.GetComponent <CharacterUnit>(); if (characterUnit == null) { return(false); } if (characterUnit.BaseCharacter == null || characterUnit.BaseCharacter.UnitProfile == null) { return(false); } if (!characterUnit.BaseCharacter.UnitProfile.IsPet) { return(false); } return(base.CanUseOn(target, sourceCharacter, abilityEffectContext)); }
public override Dictionary <PrefabProfile, GameObject> Cast(IAbilityCaster source, GameObject target, GameObject originalTarget, AbilityEffectContext abilityEffectContext) { //Debug.Log(MyName + ".ProjectileEffect.Cast(" + source.name + ", " + (target == null ? "null" : target.name) + ")"); Dictionary <PrefabProfile, GameObject> returnObjects = base.Cast(source, target, originalTarget, abilityEffectContext); if (returnObjects != null) { foreach (GameObject go in returnObjects.Values) { //Debug.Log(MyName + ".ProjectileEffect.Cast(): found gameobject: " + go.name); go.transform.parent = PlayerManager.MyInstance.MyEffectPrefabParent.transform; ProjectileScript projectileScript = go.GetComponent <ProjectileScript>(); if (projectileScript != null) { //Debug.Log(MyName + ".ProjectileEffect.Cast(): found gameobject: " + go.name + " and it has projectile script"); abilityEffectContext = ApplyInputMultiplier(abilityEffectContext); projectileScript.Initialize(projectileSpeed, source, target, new Vector3(0, 1, 0), abilityEffectContext); projectileScript.OnCollission += HandleCollission; } } } return(returnObjects); }
/// <summary> /// Does the actual work of hitting the target with an ability /// </summary> /// <param name="ability"></param> /// <param name="source"></param> /// <param name="target"></param> public override Dictionary <PrefabProfile, GameObject> Cast(IAbilityCaster source, Interactable target, Interactable originalTarget, AbilityEffectContext abilityEffectContext) { //Debug.Log(DisplayName + ".AOEEffect.Cast(" + (source == null ? "null" : source.AbilityManager.UnitGameObject.name) + ", " + (target == null ? "null" : target.name) + ")"); if (abilityEffectContext == null) { abilityEffectContext = new AbilityEffectContext(); } Dictionary <PrefabProfile, GameObject> returnObjects = base.Cast(source, target, originalTarget, abilityEffectContext); TargetAOEHit(source, target, abilityEffectContext); // ground targeted spells should play the audio on the prefab object, not the character if (prefabSpawnLocation == PrefabSpawnLocation.GroundTarget) { base.PlayAudioEffects(onHitAudioProfiles, null); } else { base.PlayAudioEffects(onHitAudioProfiles, target); } return(returnObjects); }
public IEnumerator DestroyAbilityEffectObject(Dictionary <PrefabProfile, GameObject> abilityEffectObjects, IAbilityCaster source, GameObject target, float timer, AbilityEffectContext abilityEffectInput, FixedLengthEffect fixedLengthEffect) { //Debug.Log("CharacterAbilityManager.DestroyAbilityEffectObject(" + (source == null ? "null" : source.name) + ", " + (target == null ? "null" : target.name) + ", " + timer + ")"); float timeRemaining = timer; // keep track of temporary elapsed time between ticks float elapsedTime = 0f; bool nullTarget = false; CharacterStats targetStats = null; if (target != null) { CharacterUnit _characterUnit = target.GetComponent <CharacterUnit>(); if (_characterUnit != null) { targetStats = _characterUnit.MyCharacter.CharacterStats; } } else { nullTarget = true; } int milliseconds = (int)((fixedLengthEffect.TickRate - (int)fixedLengthEffect.TickRate) * 1000); float finalTickRate = fixedLengthEffect.TickRate; if (finalTickRate == 0) { finalTickRate = timer + 1; } //Debug.Log(abilityEffectName + ".StatusEffect.Tick() milliseconds: " + milliseconds); //TimeSpan tickRateTimeSpan = new TimeSpan(0, 0, 0, (int)finalTickRate, milliseconds); //Debug.Log(abilityEffectName + ".StatusEffect.Tick() tickRateTimeSpan: " + tickRateTimeSpan); //fixedLengthEffect.MyNextTickTime = System.DateTime.Now + tickRateTimeSpan; //Debug.Log(abilityEffectName + ".FixedLengthEffect.Tick() nextTickTime: " + nextTickTime); while (timeRemaining > 0f) { yield return(null); if (nullTarget == false && (targetStats == null || fixedLengthEffect == null)) { //Debug.Log(gameObject.name + ".CharacterAbilityManager.DestroyAbilityEffectObject: BREAKING!!!!!!!!!!!!!!!!!: fixedLengthEffect: " + (fixedLengthEffect == null ? "null" : fixedLengthEffect.MyName) + "; targetstats: " + (targetStats == null ? "null" : targetStats.name)); break; } if (fixedLengthEffect.MyPrefabSpawnLocation != PrefabSpawnLocation.GroundTarget && fixedLengthEffect.RequiresTarget == true && (target == null || (targetStats.IsAlive == true && fixedLengthEffect.RequireDeadTarget == true) || (targetStats.IsAlive == false && fixedLengthEffect.RequiresLiveTarget == true))) { //Debug.Log("BREAKING!!!!!!!!!!!!!!!!!"); break; } else { timeRemaining -= Time.deltaTime; if (elapsedTime > finalTickRate) { //Debug.Log(abilityEffectName + ".FixedLengthEffect.Tick() TickTime!"); fixedLengthEffect.CastTick(source, target, abilityEffectInput); elapsedTime -= finalTickRate; } } } //Debug.Log(fixedLengthEffect.MyName + ".FixedLengthEffect.Tick() Done ticking and about to perform ability affects."); fixedLengthEffect.CastComplete(source, target, abilityEffectInput); foreach (GameObject go in abilityEffectObjects.Values) { if (abilityEffectGameObjects.Contains(go)) { abilityEffectGameObjects.Remove(go); } Destroy(go, fixedLengthEffect.MyPrefabDestroyDelay); } abilityEffectObjects.Clear(); destroyAbilityEffectObjectCoroutine = null; }
public void BeginDestroyAbilityEffectObject(Dictionary <PrefabProfile, GameObject> abilityEffectObjects, IAbilityCaster source, GameObject target, float timer, AbilityEffectContext abilityEffectInput, FixedLengthEffect fixedLengthEffect) { foreach (GameObject go in abilityEffectObjects.Values) { abilityEffectGameObjects.Add(go); } destroyAbilityEffectObjectCoroutine = StartCoroutine(DestroyAbilityEffectObject(abilityEffectObjects, source, target, timer, abilityEffectInput, fixedLengthEffect)); }
public void HandleCollission(IAbilityCaster source, GameObject target, GameObject _abilityEffectObject, AbilityEffectContext abilityEffectInput) { //Debug.Log(MyName + ".ProjectileEffect.HandleCollission()"); PerformAbilityHit(source, target, abilityEffectInput); Destroy(_abilityEffectObject); }
public override void CastComplete(IAbilityCaster source, Interactable target, AbilityEffectContext abilityEffectContext) { //Debug.Log(abilityEffectName + ".DirectEffect.CastComplete()"); base.CastComplete(source, target, abilityEffectContext); PerformAbilityComplete(source, target, abilityEffectContext); }
public override Dictionary <PrefabProfile, GameObject> Cast(IAbilityCaster source, Interactable target, Interactable originalTarget, AbilityEffectContext abilityEffectInput) { //Debug.Log(MyName + ".DirectEffect.Cast()"); return(base.Cast(source, target, originalTarget, abilityEffectInput)); }
public override Dictionary <PrefabProfile, GameObject> Cast(IAbilityCaster source, GameObject target, GameObject originalTarget, AbilityEffectContext abilityEffectContext) { //Debug.Log(DisplayName + ".KnockBackEffect.Cast()"); if (target == null) { return(null); } Dictionary <PrefabProfile, GameObject> returnObjects = base.Cast(source, target, originalTarget, abilityEffectContext); Vector3 sourcePosition = source.UnitGameObject.transform.position; Vector3 targetPosition = target.transform.position; AnimatedUnit animatedUnit = target.GetComponent <AnimatedUnit>(); CharacterUnit targetCharacterUnit = target.GetComponent <CharacterUnit>(); if (targetCharacterUnit != null && targetCharacterUnit.MyCharacter != null && targetCharacterUnit.MyCharacter.CharacterAbilityManager) { //Debug.Log("KnockBackEffect.Cast(): stop casting"); targetCharacterUnit.MyCharacter.CharacterAbilityManager.StopCasting(); } if (knockbackType == KnockbackType.Knockback) { if (animatedUnit != null && animatedUnit.MyCharacterMotor != null) { //Debug.Log("KnockBackEffect.Cast(): casting on character"); animatedUnit.MyCharacterMotor.Move(GetKnockBackVelocity(sourcePosition, targetPosition), true); } else { Rigidbody rigidbody = target.GetComponent <Rigidbody>(); if (rigidbody != null) { rigidbody.constraints = RigidbodyConstraints.FreezeRotation; rigidbody.AddForce(GetKnockBackVelocity(sourcePosition, targetPosition), ForceMode.VelocityChange); } } } else { Collider[] colliders = new Collider[0]; //int playerMask = 1 << LayerMask.NameToLayer("Default"); //int characterMask = 1 << LayerMask.NameToLayer("CharacterUnit"); //int validMask = (playerMask | characterMask); //int validMask = playerMask; //colliders = Physics.OverlapSphere(targetPosition, explosionRadius, validMask); Vector3 explosionCenter = Vector3.zero; if (abilityEffectContext.groundTargetLocation != Vector3.zero) { explosionCenter = abilityEffectContext.groundTargetLocation; } else { explosionCenter = targetPosition; } colliders = Physics.OverlapSphere(explosionCenter, explosionRadius, explosionMask); foreach (Collider collider in colliders) { //Debug.Log(DisplayName + ".KnockBackEffect.Cast() hit: " + collider.gameObject.name + "; layer: " + collider.gameObject.layer); Rigidbody rigidbody = collider.gameObject.GetComponent <Rigidbody>(); if (rigidbody != null) { //Debug.Log(DisplayName + ".KnockBackEffect.Cast() rigidbody was not null on : " + collider.gameObject.name + "; layer: " + collider.gameObject.layer); //rigidbody.AddForce(GetKnockBackVelocity(targetPosition, collider.gameObject.transform.position), ForceMode.VelocityChange); // we have to handle player knockback specially, as they need to be in knockback state or the idle update will freeze them in place PlayerUnitMovementController playerUnitMovementController = collider.gameObject.GetComponent <PlayerUnitMovementController>(); if (playerUnitMovementController != null) { playerUnitMovementController.KnockBack(); } // if this is a character, we want to freeze their rotation. for inanimate objects, we want rotation targetCharacterUnit = collider.gameObject.GetComponent <CharacterUnit>(); if (targetCharacterUnit != null) { rigidbody.constraints = RigidbodyConstraints.FreezeRotation; } rigidbody.AddExplosionForce(explosionForce, explosionCenter, 0, upwardModifier, ForceMode.VelocityChange); } } } return(returnObjects); }
/// <summary> /// Does the actual work of hitting the target with an ability /// </summary> /// <param name="ability"></param> /// <param name="source"></param> /// <param name="target"></param> public override void PerformAbilityHit(IAbilityCaster source, Interactable target, AbilityEffectContext abilityEffectInput) { //Debug.Log(DisplayName + ".HealEffect.PerformAbilityEffect(" + source.AbilityManager.UnitGameObject.name + ", " + (target == null ? "null" : target.gameObject.name) + ")"); base.PerformAbilityHit(source, target, abilityEffectInput); }