///<summary> ///Used to recreate from temp into obstacle object. ///</summary> public CacheObject(CacheObject parent) : base(parent) { AcdGuid = parent.AcdGuid; BlacklistFlag = parent.BlacklistFlag; BlacklistLoops_ = parent.BlacklistLoops_; gprect_ = parent.gprect_; InteractionAttempts = parent.InteractionAttempts; lineofsight = new LOSInfo(this); LoopsUnseen_ = parent.LoopsUnseen_; losv3_ = parent.losv3_; LosSearchRetryMilliseconds_ = parent.LosSearchRetryMilliseconds_; NeedsRemoved = parent.NeedsRemoved; NeedsUpdate = parent.NeedsUpdate; PrioritizedDate = parent.PrioritizedDate; PriorityCounter = parent.PriorityCounter; position_ = parent.Position; radius_ = parent.Radius; RAGUID = parent.RAGUID; ref_DiaObject = parent.ref_DiaObject; removal_ = parent.removal_; RequiresLOSCheck = parent.RequiresLOSCheck; SummonerID = parent.SummonerID; weight_ = parent.Weight; HandleAsAvoidanceObject = parent.HandleAsAvoidanceObject; Properties = parent.Properties; }
public CacheObject(int sno, int raguid, int acdguid, Vector3 position, string Name = null) : base(sno) { RAGUID = raguid; NeedsUpdate = true; removal_ = false; BlacklistFlag = BlacklistType.None; AcdGuid = acdguid; radius_ = 0f; position_ = position; RequiresLOSCheck = !(base.IgnoresLOSCheck); //require a LOS check initally on a new object! lineofsight = new LOSInfo(this); LosSearchRetryMilliseconds_ = 1000; PrioritizedDate = DateTime.Today; PriorityCounter = 0; losv3_ = Vector3.Zero; HandleAsAvoidanceObject = false; Properties = TargetProperties.None; //Keep track of each unique RaGuid that is created and uses this SNO during each level. //if (!UsedByRaGuids.Contains(RAGUID)) UsedByRaGuids.Add(RAGUID); }
private static void CreateLineOfSightTargetCheck(ref Func <CacheUnit, bool> CombatCriteria, Skill ability) { if (ability.IsRanged) { CombatCriteria += (unit) => { if (!unit.IgnoresLOSCheck && unit.IsTargetableAndAttackable) { LOSInfo LOSINFO = unit.LineOfSight; if (LOSINFO.LastLOSCheckMS > 2000) { //!LOSINFO.LOSTest(FunkyGame.Hero.Position, true, ServerObjectIntersection: ability.IsProjectile, Flags: NavCellFlags.AllowProjectile) if (!LOSINFO.LOSTest(FunkyGame.Hero.Position, true, false, ability.IsProjectile, ability.IsProjectile ? NavCellFlags.AllowProjectile:NavCellFlags.None)) { //Raycast failed.. reset LOS Check -- for valid checking. if (!LOSINFO.RayCast.Value || (LOSINFO.ObjectIntersection.HasValue && !LOSINFO.ObjectIntersection.Value)) { unit.RequiresLOSCheck = true; return(false); } //if (LOSINFO.NavCellProjectile.HasValue && !LOSINFO.NavCellProjectile.Value) //NavCellFlag Walk Failed //{ // bool MovementException = ((FunkyGame.Targeting.Cache.CurrentUnitTarget.MonsterTeleport || FunkyGame.Targeting.Cache.CurrentTarget.IsTransformUnit) && FunkyGame.Targeting.Cache.CurrentUnitTarget.AnimState == AnimationState.Transform); // if (!MovementException) return false; //} } } //else if (LOSINFO.ObjectIntersection.HasValue && !LOSINFO.ObjectIntersection.Value) //{ // return false; //} } return(true); }; } else if (ability.Range > 0) { //Melee CombatCriteria += (unit) => { if (!unit.IgnoresLOSCheck && unit.IsTargetableAndAttackable) { float radiusDistance = unit.RadiusDistance; //Check if within interaction range.. if (radiusDistance > ability.Range) { //Verify LOS walk LOSInfo LOSINFO = unit.LineOfSight; if (LOSINFO.LastLOSCheckMS > 2000) //||!LOSINFO.NavCellWalk.HasValue) { if (!LOSINFO.LOSTest(FunkyGame.Hero.Position, true, ServerObjectIntersection: false)) { //bool MovementException=((FunkyGame.Targeting.Cache.CurrentUnitTarget.MonsterTeleport||FunkyGame.Targeting.Cache.CurrentTarget.IsTransformUnit)&&FunkyGame.Targeting.Cache.CurrentUnitTarget.AnimState==Zeta.Internals.Actors.AnimationState.Transform); //Raycast failed.. reset LOS Check -- for valid checking. if (!LOSINFO.RayCast.Value) { unit.RequiresLOSCheck = true; } //else if (!LOSINFO.NavCellWalk.Value) //NavCellFlag Walk Failed //{ // bool MovementException = ((FunkyGame.Targeting.Cache.CurrentUnitTarget.MonsterTeleport || FunkyGame.Targeting.Cache.CurrentTarget.IsTransformUnit) && FunkyGame.Targeting.Cache.CurrentUnitTarget.AnimState == Zeta.Internals.Actors.AnimationState.Transform); // if (!MovementException) // return false; //} } } //else if (LOSINFO.NavCellWalk.HasValue&&!LOSINFO.NavCellWalk.Value) //{ // return false; //} } } return(true); }; } }
protected LOSInfo CanSeePlayer(ref Blackboard bb) { LOSInfo results = new LOSInfo(); results.CanSeePlayer = false; RaycastHit2D hitInfo = Physics2D.Raycast(bb.Trans.position, bb.ToPlayer2D.normalized, bb.LOSDistance); if (hitInfo) { results.HitPoint = hitInfo.point; // dividing in half so I can add/subtract the half angle to find my field of view vectors float angleRads = (m_AngleOfLOS / 2.0f) * Mathf.PI / 180.0f; float unitCircleX = bb.Trans.up.x; float unitCircleY = bb.Trans.up.y; float leftUnitCircleX = unitCircleX * Mathf.Cos(-angleRads) - unitCircleY * Mathf.Sin(-angleRads); float leftUnitCircleY = unitCircleX * Mathf.Sin(-angleRads) + unitCircleY * Mathf.Cos(-angleRads); Vector3 leftVectorFOV = new Vector3(leftUnitCircleX, leftUnitCircleY, 0); leftVectorFOV = leftVectorFOV * bb.LOSDistance + bb.Trans.position; float rightUnitCircleX = unitCircleX * Mathf.Cos(angleRads) - unitCircleY * Mathf.Sin(angleRads); float rightUnitCircleY = unitCircleX * Mathf.Sin(angleRads) + unitCircleY * Mathf.Cos(angleRads); Vector3 rightVectorFOV = new Vector3(rightUnitCircleX, rightUnitCircleY, 0); rightVectorFOV = rightVectorFOV * bb.LOSDistance + bb.Trans.position; Debug.DrawLine(bb.Trans.position, rightVectorFOV, Color.white); Debug.DrawLine(bb.Trans.position, leftVectorFOV, Color.white); Debug.DrawLine (bb.Trans.position, bb.Trans.up*4 + bb.Trans.position, Color.red); if (hitInfo.transform.tag == "Player") { // we can see the player, are we within the field of view? //float dotResult = Vector3.Dot(bb.Trans.forward, hitInfo.point); results.CanSeePlayer = true; } } else { results.HitPoint = bb.Trans.position + (bb.ToPlayer.normalized * bb.LOSDistance); } return results; }
// Our exit conditions are // a) we reach the player // b) we reach the players last known position and we can't find the player after x seconds (second half may be a new behavior) public override Status Update(ref Blackboard bb) { LOSInfo losResults = new LOSInfo(); if ((bb.LastKnownPlayerPosition - bb.Player.position).sqrMagnitude >= m_RefindPlayerDist) { losResults = CanSeePlayer(ref bb); if (losResults.CanSeePlayer) { bb.LastKnownPlayerPosition = bb.Player.position; bb.SetDestinationAndPath(bb.Player.position); } } else if (bb.ShowLOSCheck) { losResults = CanSeePlayer(ref bb); } bb.LOSCheck(losResults.CanSeePlayer, losResults.HitPoint); if (bb.LastKnownPlayerPosition == Vector3.zero) { // We don't have a destination, return failure //Debug.Log("ChasePlayer failed"); return Status.BH_FAILURE; } Vector3 toDestination = bb.Destination - bb.Trans.position; if (toDestination.sqrMagnitude <= m_DistanceThreshold * m_DistanceThreshold || bb.PathCurrentIdx >= bb.MovementPath.Length) { // If we've reached our destination, we're done Debug.Log ("ChasePlayer finish"); return Status.BH_SUCCESS; } // Move normally //Debug.DrawLine(bb.Trans.position, bb.MovementPath[bb.PathCurrentIdx], Color.green); Vector3 toNextPoint = bb.MovementPath[bb.PathCurrentIdx] - bb.Trans.position; toNextPoint.z = 0; if (toNextPoint.sqrMagnitude < 3) { ++bb.PathCurrentIdx; } toNextPoint.z = 0; toNextPoint.Normalize(); bb.Trans.Translate(toNextPoint * bb.MoveSpeed * Time.deltaTime); m_Status = Status.BH_RUNNING; return Status.BH_RUNNING; }
///<summary> ///Returns Ability used for destructibles ///</summary> internal virtual Skill DestructibleAbility() { Skill returnAbility = Bot.Character.Class.DefaultAttack; List <Skill> nonDestructibleAbilities = new List <Skill>(); foreach (var item in Abilities.Values) { if (item.IsADestructiblePower) { //Check LOS -- Projectiles if (item.IsRanged && !Bot.Targeting.Cache.CurrentTarget.IgnoresLOSCheck) { LOSInfo LOSINFO = Bot.Targeting.Cache.CurrentTarget.LineOfSight; if (LOSINFO.LastLOSCheckMS > 3000 || (item.IsProjectile && !LOSINFO.ObjectIntersection.HasValue) || !LOSINFO.NavCellProjectile.HasValue) { if (!LOSINFO.LOSTest(Bot.Character.Data.Position, true, false, NavCellFlags.AllowProjectile)) { //Raycast failed.. reset LOS Check -- for valid checking. if (!LOSINFO.RayCast.Value) { Bot.Targeting.Cache.CurrentTarget.RequiresLOSCheck = true; } continue; } } else if (!LOSINFO.NavCellProjectile.Value) { continue; } } if (item.CheckPreCastConditionMethod()) { returnAbility = item; Skill.SetupAbilityForUse(ref returnAbility, true); return(returnAbility); } } else if (item.ExecutionType.HasFlag(AbilityExecuteFlags.Target) || item.ExecutionType.HasFlag(AbilityExecuteFlags.Location)) { //Check LOS -- Projectiles if (item.IsRanged && !Bot.Targeting.Cache.CurrentTarget.IgnoresLOSCheck) { LOSInfo LOSINFO = Bot.Targeting.Cache.CurrentTarget.LineOfSight; if (LOSINFO.LastLOSCheckMS > 3000 || (item.IsProjectile && !LOSINFO.ObjectIntersection.HasValue) || !LOSINFO.NavCellProjectile.HasValue) { if (!LOSINFO.LOSTest(Bot.Character.Data.Position, true, item.IsProjectile, NavCellFlags.AllowProjectile)) { //Raycast failed.. reset LOS Check -- for valid checking. if (!LOSINFO.RayCast.Value) { Bot.Targeting.Cache.CurrentTarget.RequiresLOSCheck = true; } continue; } } else if ((item.IsProjectile && LOSINFO.ObjectIntersection.Value) || !LOSINFO.NavCellProjectile.Value) { continue; } } //Add this Ability to our list.. incase we cant find an offical Ability to use. if (item.CheckPreCastConditionMethod()) { nonDestructibleAbilities.Add(item); } } } //Use non-destructible Ability.. if (nonDestructibleAbilities.Count > 0) { returnAbility = nonDestructibleAbilities[0]; } Skill.SetupAbilityForUse(ref returnAbility, true); return(returnAbility); }