/// <summary>
        /// Loops through all the Options of the minion. The action has 4 useful parameters to use.
        /// The first parameter refers to the Option/Multiple itself. It is a GameObject.
        /// The second parameter refers to the OptionBehavior component in the Option/Multiple.
        /// The third parameter refers to the target of the Option/Multiple owner. It is also a GameObject.
        /// The last parameter refers to the direction from the option to the target. It is a normalized Vector3.
        /// </summary>
        /// <param name="optionOwner">The owner of the option.</param>
        /// <param name="actionToRun">An action to execute for each Option. The inputs are as follows:
        /// GameObject option, OptionBehavior behavior, GameObject target, Vector3 direction.</param>
        public void FireForAllOptions(CharacterBody optionOwner, Action <GameObject, OptionBehavior, GameObject, Vector3> actionToRun)
        {
            if (!optionOwner)
            {
                return;
            }
            OptionTracker optionTracker = optionOwner.GetComponent <OptionTracker>();

            if (!optionTracker)
            {
                return;
            }

            GameObject target       = null;
            GameObject masterObject = optionOwner.masterObject;

            if (masterObject)
            {
                BaseAI        ai         = masterObject.GetComponent <BaseAI>();
                BaseAI.Target mainTarget = ai.currentEnemy;
                if (mainTarget != null && mainTarget.gameObject)
                {
                    target = mainTarget.gameObject;
                }
            }

            foreach (GameObject option in optionTracker.existingOptions)
            {
                OptionBehavior behavior = option.GetComponent <OptionBehavior>();
                if (behavior)
                {
                    Vector3 direction;
                    if (target)
                    {
                        direction = (target.transform.position - option.transform.position).normalized;
                        if (includeModelInsideOrb)
                        {
                            behavior.target = target;
                            NetworkIdentity targetNetworkIdentity = target.GetComponent <NetworkIdentity>();
                            if (targetNetworkIdentity)
                            {
                                OptionSync(optionOwner, (networkIdentity, nullTracker) =>
                                {
                                    optionTracker.targetIds.Add(Tuple.Create(
                                                                    GameObjectType.Body, networkIdentity.netId,
                                                                    (short)behavior.numbering, targetNetworkIdentity.netId
                                                                    ));
                                }, false);
                            }
                        }
                    }
                    else
                    {
                        direction = optionOwner.inputBank.GetAimRay().direction.normalized;
                    }
                    actionToRun(option, behavior, target, direction);
                }
            }
        }
예제 #2
0
        private void Awake()
        {
            IL.RoR2.CharacterBody.HandleConstructTurret += (il) => {
                var c = new ILCursor(il);

                c.GotoNext(x => x.MatchStloc(4));
                c.Emit(OpCodes.Ldloc_2);
                c.EmitDelegate <Func <CharacterMaster, CharacterMaster, CharacterMaster> >((turret, master) => {
                    turret.gameObject.AddComponent <AIOwnership>().ownerMaster = master;

                    return(turret);
                });
            };


            IL.RoR2.CharacterAI.BaseAI.FixedUpdate += (il2) => {
                var c2 = new ILCursor(il2);
                c2.Emit(OpCodes.Ldarg_0);

                c2.EmitDelegate <Action <BaseAI> >((ai) => {
                    if (ai.leader.characterBody != null)
                    {
                        BaseAI.Target leader = ai.leader;


                        if (leader.characterBody.isPlayerControlled)
                        {
                            PingerController p = null; //leader.characterBody.master.GetComponent<PingerController>();
                            foreach (PlayerCharacterMasterController item in PlayerCharacterMasterController.instances)
                            {
                                if (item.master.alive)
                                {
                                    if (item.master.GetBody().GetUserName() == leader.characterBody.GetUserName())
                                    {
                                        p = (PingerController)pingerController.GetValue(item);
                                    }
                                }
                            }
                            if (p != null)
                            {
                                if (p.currentPing.targetGameObject != null)
                                {
                                    ((BaseAI.Target)currentEnemy.GetValue(ai)).gameObject = p.currentPing.targetGameObject;
                                }
                            }
                        }
                    }
                });
            };
        }
예제 #3
0
        // Token: 0x06000974 RID: 2420 RVA: 0x0002F30C File Offset: 0x0002D50C
        public override void FixedUpdate()
        {
            base.FixedUpdate();
            if (base.ai && base.body)
            {
                Vector3 footPosition = base.body.footPosition;
                base.ai.pathFollower.UpdatePosition(footPosition);
                this.updateTimer     -= Time.fixedDeltaTime;
                this.pathUpdateTimer -= Time.fixedDeltaTime;
                this.strafeTimer     -= Time.fixedDeltaTime;
                if (this.updateTimer <= 0f)
                {
                    this.updateTimer = UnityEngine.Random.Range(0.16666667f, 0.2f);
                    AISkillDriver.MovementType movementType = AISkillDriver.MovementType.Stop;
                    SkillSlot skillSlot = SkillSlot.None;
                    bool      flag      = false;
                    BaseAI.SkillDriverEvaluation skillDriverEvaluation = base.ai.skillDriverEvaluation;
                    this.dominantSkillDriver = skillDriverEvaluation.dominantSkillDriver;
                    BaseAI.Target target = skillDriverEvaluation.target;
                    if (this.dominantSkillDriver)
                    {
                        movementType = this.dominantSkillDriver.movementType;
                        skillSlot    = this.dominantSkillDriver.skillSlot;
                        flag         = this.dominantSkillDriver.activationRequiresTargetLoS;
                    }
                    Vector3 position = base.body.transform.position;
                    Vector3 b        = base.bodyInputBank ? base.bodyInputBank.aimOrigin : position;
                    Vector3 vector   = position;
                    Vector3 vector2  = vector;
                    this.moveTargetPositionFound = (target != null && target.GetBullseyePosition(out vector));
                    if (this.moveTargetPositionFound)
                    {
                        CharacterBody characterBody = target.characterBody;
                        if (characterBody)
                        {
                            vector2 = characterBody.footPosition;
                        }
                        else
                        {
                            vector2 = vector;
                        }
                        if (this.pathUpdateTimer <= 0f)
                        {
                            base.ai.RefreshPath(footPosition, vector2);
                            this.pathUpdateTimer = this.pathUpdateInterval;
                        }
                    }
                    Vector3 normalized = (vector - b).normalized;
                    bool    flag2      = true;
                    if (this.dominantSkillDriver && this.dominantSkillDriver.activationRequiresAimConfirmation)
                    {
                        flag2 = false;
                        if (base.bodyInputBank && Vector3.Dot(base.bodyInputBank.aimDirection.normalized, normalized) >= 0.95f)
                        {
                            flag2 = true;
                        }
                    }
                    Vector3 normalized2 = (((this.dominantSkillDriver && this.dominantSkillDriver.ignoreNodeGraph) ? ((base.ai.nodegraphType == MapNodeGroup.GraphType.Ground) ? vector2 : vector) : base.ai.pathFollower.GetNextPosition()) - footPosition).normalized;
                    Vector3 vector3     = Vector3.Cross(Vector3.up, normalized2);
                    Vector3 vector4     = position;
                    if (movementType == AISkillDriver.MovementType.ChaseMoveTarget)
                    {
                        vector4 += normalized2;
                    }
                    else if (movementType == AISkillDriver.MovementType.FleeMoveTarget)
                    {
                        vector4 -= normalized2;
                    }
                    else if (movementType == AISkillDriver.MovementType.StrafeMovetarget)
                    {
                        if (this.strafeTimer <= 0f)
                        {
                            this.strafeDirection = 0f;
                        }
                        if (this.strafeDirection == 0f)
                        {
                            LayerMask  mask    = LayerIndex.world.mask | LayerIndex.defaultLayer.mask;
                            float      num     = 0.25f * base.body.moveSpeed;
                            float      num2    = num;
                            float      num3    = num;
                            HullDef    hullDef = HullDef.Find(base.body.hullClassification);
                            float      radius  = hullDef.radius;
                            float      height  = hullDef.height;
                            Vector3    b2      = Vector3.up * (height * 0.5f - radius);
                            RaycastHit raycastHit;
                            if (Physics.CapsuleCast(position + b2, position - b2, radius, vector3, out raycastHit, num, mask))
                            {
                                num2 = raycastHit.distance;
                            }
                            if (Physics.CapsuleCast(position + b2, position - b2, radius, -vector3, out raycastHit, num, mask))
                            {
                                num3 = raycastHit.distance;
                            }
                            if (num3 == num2)
                            {
                                this.strafeDirection = ((UnityEngine.Random.Range(0, 1) == 0) ? -1f : 1f);
                            }
                            else
                            {
                                this.strafeDirection = ((num3 < num2) ? 1f : -1f);
                            }
                            if (this.strafeDirection != 0f)
                            {
                                this.strafeTimer = 0.25f;
                            }
                        }
                        vector4 += vector3 * this.strafeDirection;
                    }
                    base.ai.localNavigator.targetPosition = vector4;
                    base.ai.localNavigator.Update(Time.fixedDeltaTime);
                    bool newState  = false;
                    bool newState2 = false;
                    bool newState3 = false;
                    bool newState4 = false;
                    if (((target != null) ? target.gameObject : null) && flag2 && (!flag || base.ai.HasLOS(position, vector)))
                    {
                        switch (skillSlot)
                        {
                        case SkillSlot.Primary:
                            newState = true;
                            break;

                        case SkillSlot.Secondary:
                            newState2 = true;
                            break;

                        case SkillSlot.Utility:
                            newState3 = true;
                            break;

                        case SkillSlot.Special:
                            newState4 = true;
                            break;
                        }
                    }
                    Vector3 vector5 = base.ai.localNavigator.moveVector;
                    if (base.bodyCharacterMotor && movementType == AISkillDriver.MovementType.ChaseMoveTarget && Vector3.Dot(vector5, base.bodyCharacterMotor.velocity.normalized) <= 0.5f)
                    {
                        vector5 *= 0.5f;
                    }
                    if (this.dominantSkillDriver)
                    {
                        vector5 *= this.dominantSkillDriver.moveInputScale;
                    }
                    if (base.bodyInputBank)
                    {
                        base.bodyInputBank.skill1.PushState(newState);
                        base.bodyInputBank.skill2.PushState(newState2);
                        base.bodyInputBank.skill3.PushState(newState3);
                        base.bodyInputBank.skill4.PushState(newState4);
                        bool newState5 = false;
                        if (base.bodyCharacterMotor && base.bodyCharacterMotor.isGrounded && Mathf.Max(base.ai.pathFollower.CalculateJumpVelocityNeededToReachNextWaypoint(base.body.moveSpeed), base.ai.localNavigator.jumpSpeed) > 0f)
                        {
                            newState5 = true;
                        }
                        base.bodyInputBank.jump.PushState(newState5);
                        base.bodyInputBank.moveVector = vector5;
                    }
                    if (!this.dominantSkillDriver)
                    {
                        this.outer.SetNextState(new LookBusy());
                        return;
                    }
                }
                this.activeSoundTimer -= Time.fixedDeltaTime;
                if (this.activeSoundTimer <= 0f)
                {
                    this.activeSoundTimer = UnityEngine.Random.Range(3f, 8f);
                    base.body.CallRpcBark();
                }
            }
        }