Пример #1
0
            public void FireCone(Ray aim)
            {
                var hits = Physics.OverlapSphere(aim.origin, coneRange, LayerIndex.entityPrecise.mask)
                           .Where(x => Vector3.Angle(aim.direction, x.ClosestPoint(aim.origin) - aim.origin) < coneHalfAngleDegrees);
                HashSet <HealthComponent> hitHCs = new HashSet <HealthComponent>();

                foreach (var hit in hits)
                {
                    if (hit && hit.TryGetComponent <HurtBox>(out var hb) && hb.healthComponent && !hitHCs.Contains(hb.healthComponent))
                    {
                        hitHCs.Add(hb.healthComponent);
                        if (this.healthComponent == hb.healthComponent || !FriendlyFireManager.ShouldSplashHitProceed(hb.healthComponent, this.teamComponent.teamIndex))
                        {
                            continue;
                        }
                        var di = new DamageInfo {
                            attacker         = this.characterBody.gameObject,
                            canRejectForce   = true,
                            crit             = this.characterBody.RollCrit(),
                            damage           = this.characterBody.damage * damageCoeff,
                            damageColorIndex = DamageColorIndex.Default,
                            damageType       = DamageType.AOE,
                            force            = Vector3.zero,
                            inflictor        = null,
                            procChainMask    = default,
Пример #2
0
            private void ColliderExit(Collider col)
            {
                if (this.collidersInZone.Contains(col))
                {
                    this.collidersInZone.Remove(col);
                }
                var hb = col?.GetComponent <HurtBox>();

                if (hb == null)
                {
                    return;
                }
                if (!this.targetBoxes.ContainsValue(hb))
                {
                    return;
                }
                var hc = hb.healthComponent;

                if (hc == null)
                {
                    return;
                }
                if (!FriendlyFireManager.ShouldDirectHitProceed(hc, this.team))
                {
                    return;
                }
                if (hc == this.attackerBody.healthComponent)
                {
                    return;
                }

                this.targetBoxes.RemoveValue(hb);
            }
Пример #3
0
            private void ColliderEnter(Collider col)
            {
                this.collidersInZone.Add(col);
                var hb = col?.GetComponent <HurtBox>();

                if (hb == null)
                {
                    return;
                }
                var hc = hb.healthComponent;

                if (hc == null)
                {
                    return;
                }
                if (!FriendlyFireManager.ShouldDirectHitProceed(hc, this.team))
                {
                    return;
                }
                if (hc == this.attackerBody.healthComponent)
                {
                    return;
                }

                this.targetBoxes.Add(hc, hb);
            }
Пример #4
0
                private void Detonate(Single damage, Vector3 force, Single procCoef, DamageType damageType)
                {
                    HashSet <HealthComponent> mask = HashSetPool <HealthComponent> .item;
                    //mask.Clear();

                    var count = Physics.OverlapCapsuleNonAlloc(this.position - new Vector3(0f, 10f, 0f), this.position + new Vector3(0f, 1000f, 0f), this.radius * 2f, colliderBuffer, LayerIndex.entityPrecise.mask);

                    Log.Warning($"Detonate, count = {count}");

                    for (Int32 i = 0; i < count; ++i)
                    {
                        var col = colliderBuffer[i];
                        if (col is null)
                        {
                            //Main.LogW( "Null collider" );
                            continue;
                        }
                        var hb = col.GetComponent <HurtBox>();
                        if (hb is null)
                        {
                            //Main.LogW( "Null Hurtbox" );
                            continue;
                        }
                        var hc = hb.healthComponent;
                        if (hc is null)
                        {
                            //Main.LogW( "Null healthcomponent" );
                            continue;
                        }

                        if (!mask.Add(hc))
                        {
                            //Main.LogW( "Already hit" );
                            continue;
                        }
                        if (!FriendlyFireManager.ShouldDirectHitProceed(hc, this.team))
                        {
                            //Main.LogW( "Cannot hit team" );
                            continue;
                        }

                        var info = new DamageInfo
                        {
                            attacker         = this.owner,
                            crit             = this.crit,
                            damage           = damage,
                            damageColorIndex = DamageColorIndex.Default,
                            damageType       = damageType,
                            dotIndex         = DotController.DotIndex.None,
                            force            = force,
                            inflictor        = null,
                            position         = hc.transform.position,
                            procChainMask    = default,
        private void FireOverlapAttack()
        {
            if (FriendlyFireManager.ShouldDirectHitProceed(this.stuckObjectHealthComponent, this.teamIndex))
            {
                this.stuckObjectHealthComponent.TakeDamage(new DamageInfo
                {
                    attacker         = this.attacker,
                    inflictor        = this.gameObject,
                    damage           = this.damage,
                    damageColorIndex = DamageColorIndex.WeakPoint,
                    damageType       = this.damageType,
                    crit             = this.isCrit,
                    dotIndex         = DotController.DotIndex.None,
                    force            = Vector3.zero,
                    position         = this.transform.position,
                    procChainMask    = this.procChainMask,
                    procCoefficient  = this.procCoefficient
                });

                GlobalEventManager.instance.OnHitEnemy(new DamageInfo
                {
                    attacker         = this.attacker,
                    inflictor        = this.gameObject,
                    damage           = this.damage,
                    damageColorIndex = DamageColorIndex.WeakPoint,
                    damageType       = this.damageType,
                    crit             = this.isCrit,
                    dotIndex         = DotController.DotIndex.None,
                    force            = Vector3.zero,
                    position         = this.transform.position,
                    procChainMask    = this.procChainMask,
                    procCoefficient  = this.procCoefficient
                }, this.stuckObject);

                EffectManager.SpawnEffect(BootlegThermiteOverlapAttack.burnEffectPrefab, new EffectData
                {
                    origin = this.transform.position,
                    scale  = 2f
                }, true);
            }
        }
Пример #6
0
        public void TickDamage()
        {
            RaycastHit[] array = Physics.BoxCastAll(boxCollider.center, boxCollider.size / 2, Vector3.forward, Quaternion.identity, 5f, RoR2.LayerIndex.entityPrecise.mask, QueryTriggerInteraction.UseGlobal);

            foreach (var hit in array)
            {
                if (hit.collider)
                {
                    var hc = hit.collider.GetComponent <HealthComponent>();
                    if (hc)
                    {
                        if (FriendlyFireManager.ShouldSplashHitProceed(hc, owner.teamComponent.teamIndex))
                        {
                            var damageInfo = new DamageInfo()
                            {
                                attacker         = owner.gameObject,
                                inflictor        = gameObject,
                                crit             = owner.RollCrit(),
                                damage           = damage,
                                damageColorIndex = DamageColorIndex.Item,
                                damageType       = DamageType.SlowOnHit,
                                force            = Vector3.zero,
                                position         = hc.body ? hc.body.corePosition : hc.transform.position,
                                procChainMask    = default,
Пример #7
0
 private bool HurtBoxPassesFilter(HurtBox hurtBox)
 {
     return(!hurtBox.healthComponent || ((!(hurtBox.healthComponent.gameObject == this.attack.attacker) || this.attack.attackerFiltering != AttackerFiltering.NeverHit) && (!(this.attack.attacker == null) || !(hurtBox.healthComponent.gameObject.GetComponent <MaulingRock>() != null)) && FriendlyFireManager.ShouldDirectHitProceed(hurtBox.healthComponent, this.attack.teamIndex)));
 }
Пример #8
0
        public void OnProjectileImpact(ProjectileImpactInfo impactInfo)
        {
            if (!this.alive)
            {
                return;
            }

            Collider collider = impactInfo.collider;

            if (collider)
            {
                DamageInfo damageInfo = new DamageInfo();
                if (this.projectileDamage)
                {
                    damageInfo.damage           = this.projectileDamage.damage;
                    damageInfo.crit             = this.projectileDamage.crit;
                    damageInfo.attacker         = this.projectileController.owner;
                    damageInfo.inflictor        = base.gameObject;
                    damageInfo.position         = impactInfo.estimatedPointOfImpact;
                    damageInfo.force            = this.projectileDamage.force * base.transform.forward;
                    damageInfo.procChainMask    = this.projectileController.procChainMask;
                    damageInfo.procCoefficient  = this.projectileController.procCoefficient;
                    damageInfo.damageColorIndex = this.projectileDamage.damageColorIndex;
                    damageInfo.damageType       = this.projectileDamage.damageType;
                }
                else
                {
                    Debug.Log(ManipulatorPlugin.MODNAME + ": No projectile damage component on: " + this + "!");
                }
                HurtBox hurtBox = collider.GetComponent <HurtBox>();
                if (hurtBox)
                {
                    HealthComponent healthComponent = hurtBox.healthComponent;
                    if (healthComponent)
                    {
                        if (!this.attack.ignoredHealthComponentList.Contains(healthComponent))
                        {
                            this.attack.ignoredHealthComponentList.Add(healthComponent);
                            if (healthComponent.gameObject == this.projectileController.owner)
                            {
                                return;
                            }
                            if (FriendlyFireManager.ShouldDirectHitProceed(healthComponent, this.projectileController.teamFilter.teamIndex))
                            {
                                Util.PlaySound(this.enemyHitSoundString, base.gameObject);
                                if (NetworkServer.active)
                                {
                                    damageInfo.ModifyDamageInfo(hurtBox.damageModifier);
                                    healthComponent.TakeDamage(damageInfo);
                                    GlobalEventManager.instance.OnHitEnemy(damageInfo, hurtBox.healthComponent.gameObject);
                                }
                            }
                            this.HitEnemyEvent();
                        }
                    }
                }
                else if (this.destroyOnWorld)
                {
                    this.alive = false;
                }
                damageInfo.position = base.transform.position;
                if (NetworkServer.active)
                {
                    GlobalEventManager.instance.OnHitAll(damageInfo, collider.gameObject);
                }
            }
            if (!this.alive)
            {
                if (NetworkServer.active && this.impactEffect)
                {
                    EffectManager.SimpleImpactEffect(this.impactEffect, impactInfo.estimatedPointOfImpact, -base.transform.forward, !this.projectileController.isPrediction);
                }
                Util.PlaySound(this.hitSoundString, base.gameObject);
            }
        }
Пример #9
0
            private void BeamAttack(BeamAttackInfo beam)
            {
                RaycastHit beamRh;

                Vector3 end = beam.aim.origin;

                //if( Physics.Raycast( beam.aim, out beamRh, beam.range, LayerIndex.world.mask, QueryTriggerInteraction.UseGlobal ) )
                if (Util.CharacterRaycast(base.outer.gameObject, beam.aim, out beamRh, beam.range, LayerIndex.world.mask, QueryTriggerInteraction.UseGlobal))
                {
                    end = beamRh.point;
                    var dmg = new DamageInfo
                    {
                        attacker         = gameObject,
                        crit             = beam.crit,
                        damage           = beam.damage,
                        damageColorIndex = DamageColorIndex.Default,
                        damageType       = DamageType.Generic,
                        force            = beam.aim.direction * beam.force,
                        inflictor        = gameObject,
                        position         = end,
                        procChainMask    = default(ProcChainMask),
                        procCoefficient  = beam.procCoef
                    };
                    DoNetworkedDamage(dmg, null);
                }
                else
                {
                    end = beam.aim.GetPoint(beam.range);
                }
                System.Int32 count = Physics.OverlapCapsuleNonAlloc(beam.aim.origin, end, beam.radius, this.beamCols, LayerIndex.entityPrecise.mask, QueryTriggerInteraction.UseGlobal);

                this.beamMask.Clear();

                Collider        tempCol;
                HurtBox         tempBox;
                HealthComponent tempHc;
                DamageInfo      tempDmgInfo;

                //EffectData effect = new EffectData();
                for (System.Int32 i = 0; i < count; i++)
                {
                    if (!this.beamCols[i])
                    {
                        continue;
                    }
                    tempBox = this.dicCheck(this.beamCols[i]).Get(this.beamCols[i].gameObject);
                    if (!tempBox)
                    {
                        continue;
                    }
                    tempHc = tempBox.healthComponent;
                    if (!tempHc || this.beamMask.Contains(tempHc) || !FriendlyFireManager.ShouldDirectHitProceed(tempHc, this.team) || tempHc == base.healthComponent)
                    {
                        continue;
                    }
                    this.beamMask.Add(tempHc);

                    tempDmgInfo = new DamageInfo
                    {
                        attacker         = gameObject,
                        crit             = beam.crit,
                        damage           = beam.damage,
                        damageColorIndex = DamageColorIndex.Default,
                        damageType       = DamageType.Generic,
                        force            = beam.aim.direction * beam.force,
                        inflictor        = gameObject,
                        position         = tempBox.transform.position,
                        procChainMask    = default(ProcChainMask),
                        procCoefficient  = beam.procCoef
                    };

                    //effect.origin = tempBox.transform.position;
                    //EffectManager.SpawnEffect( Main.genericImpactEffects[this.skin][0], effect, true );

                    DoNetworkedDamage(tempDmgInfo, tempBox);
                }
            }
Пример #10
0
            public override void OnArrival()
            {
                //Explosion effect
                EffectData effect = new EffectData
                {
                    origin      = dest,
                    genericUInt = this.skin
                };

                EffectManager.SpawnEffect(Main.secondaryExplosion, effect, true);

                if (this.attacker)
                {
                    HashSet <HealthComponent> mask = new HashSet <HealthComponent>();
                    HurtBox box;

                    DamageInfo bdmg = new DamageInfo();
                    bdmg.damage           = this.damage;
                    bdmg.attacker         = this.attacker;
                    bdmg.crit             = this.crit;
                    bdmg.damageColorIndex = this.damageColor;
                    bdmg.damageType       = DamageType.Generic;
                    bdmg.force            = (this.direction + Vector3.up) * 50f;
                    bdmg.inflictor        = this.attacker;
                    bdmg.position         = this.dest;
                    bdmg.procChainMask    = this.procMask;
                    bdmg.procCoefficient  = this.procCoef;
                    GlobalEventManager.instance.OnHitAll(bdmg, null);


                    //Collider[] cols = Physics.OverlapCapsule(this.dest, this.dest + new Vector3(0f, 20f, 0f), this.radius * this.innerRadScale, LayerIndex.entityPrecise.mask, QueryTriggerInteraction.UseGlobal);

                    //foreach( Collider col in cols )
                    //{
                    //    if( !col ) continue;
                    //    box = col.GetComponent<HurtBox>();
                    //    if( !box ) continue;
                    //    HealthComponent hcomp = box.healthComponent;
                    //    if( !hcomp || mask.Contains( hcomp ) || TeamComponent.GetObjectTeam( hcomp.gameObject ) == this.team ) continue;

                    //    DamageInfo dmg = new DamageInfo();
                    //    dmg.damage = this.damage;
                    //    dmg.attacker = this.attacker;
                    //    dmg.crit = this.crit;
                    //    dmg.damageColorIndex = this.damageColor;
                    //    dmg.damageType = DamageType.Generic;
                    //    dmg.force = (this.direction + Vector3.up) * 50f;
                    //    dmg.inflictor = this.attacker;
                    //    dmg.position = col.transform.position;
                    //    dmg.procChainMask = this.procMask;
                    //    dmg.procCoefficient = this.procCoef;

                    //    hcomp.TakeDamage( dmg );
                    //    GlobalEventManager.instance.OnHitEnemy( dmg, hcomp.gameObject );
                    //    GlobalEventManager.instance.OnHitAll( dmg, hcomp.gameObject );
                    //    mask.Add( hcomp );
                    //}

                    var cols = Physics.OverlapCapsule(this.dest, this.dest + new Vector3(0f, 20f, 0f), this.radius, LayerIndex.entityPrecise.mask, QueryTriggerInteraction.UseGlobal);

                    foreach (Collider col in cols)
                    {
                        if (!col)
                        {
                            continue;
                        }
                        box = col.GetComponent <HurtBox>();
                        if (!box)
                        {
                            continue;
                        }
                        HealthComponent hcomp = box.healthComponent;
                        if (!hcomp || mask.Contains(hcomp) || !FriendlyFireManager.ShouldDirectHitProceed(hcomp, this.team) || hcomp.gameObject == this.attacker)
                        {
                            continue;
                        }

                        DamageInfo dmg = new DamageInfo();
                        dmg.damage           = this.damage;
                        dmg.attacker         = this.attacker;
                        dmg.crit             = this.crit;
                        dmg.damageColorIndex = this.damageColor;
                        dmg.damageType       = DamageType.Generic;
                        dmg.force            = (this.direction + Vector3.up) * 10f;
                        dmg.inflictor        = this.attacker;
                        dmg.position         = col.transform.position;
                        dmg.procChainMask    = this.procMask;
                        dmg.procCoefficient  = this.procCoef * this.edgePenaltyMult;

                        if (this.hitMask.Contains(hcomp))
                        {
                            dmg.damage          *= this.edgePenaltyMult;
                            dmg.procCoefficient *= this.edgePenaltyMult;
                        }

                        hcomp.TakeDamage(dmg);
                        GlobalEventManager.instance.OnHitEnemy(dmg, hcomp.gameObject);
                        GlobalEventManager.instance.OnHitAll(dmg, hcomp.gameObject);
                        mask.Add(hcomp);
                        this.hitMask.Add(hcomp);
                    }
                }

                if (this.stepsLeft > 0 && !this.last)
                {
                    SparkOrb nextOrb = new SparkOrb();
                    nextOrb.maxFall     = this.maxFall;
                    nextOrb.attacker    = this.attacker;
                    nextOrb.crit        = this.crit;
                    nextOrb.damage      = this.damage;
                    nextOrb.damageColor = this.damageColor;
                    nextOrb.direction   = this.direction;
                    nextOrb.origin      = this.dest;
                    nextOrb.procCoef    = this.procCoef;
                    nextOrb.procMask    = this.procMask;
                    nextOrb.isFirst     = false;
                    nextOrb.radius      = this.radius;
                    nextOrb.scale       = this.scale;
                    nextOrb.speed       = this.speed;
                    nextOrb.stepDist    = this.stepDist;
                    nextOrb.stepHeight  = this.stepHeight;
                    nextOrb.stepsLeft   = this.stepsLeft - 1;
                    nextOrb.target      = this.target;
                    nextOrb.team        = this.team;
                    nextOrb.skin        = this.skin;
                    nextOrb.hitMask     = this.hitMask;

                    OrbManager.instance.AddOrb(nextOrb);
                }
            }
Пример #11
0
        public void FixedUpdate()
        {
            this.fixedAge += Time.fixedDeltaTime;

            if (this.fixedAge >= 0.2f && !this.attached)
            {
                this.alive = false;
            }
            if (!this.attachedHealth.alive)
            {
                this.alive = false;
            }

            if (this.attached)
            {
                this.timer += Time.fixedDeltaTime;
                if (this.timer >= this.attachDuration)
                {
                    this.alive = false;
                }
                else
                {
                    if (this.attachHitCount > 0)
                    {
                        this.nextAttackTimer += Time.fixedDeltaTime;
                        if (this.nextAttackTimer >= this.attachDuration / (float)this.attachHitCount)
                        {
                            this.nextAttackTimer -= this.attachDuration / (float)this.attachHitCount;
                            if (mainHurtBox)
                            {
                                HealthComponent health     = mainHurtBox.healthComponent;
                                DamageInfo      damageInfo = new DamageInfo();
                                if (this.projectileDamage)
                                {
                                    damageInfo.damage           = this.projectileDamage.damage * this.attachDamageCoefficient;
                                    damageInfo.crit             = this.projectileDamage.crit;
                                    damageInfo.attacker         = this.projectileController.owner;
                                    damageInfo.inflictor        = base.gameObject;
                                    damageInfo.position         = mainHurtBox.transform.position;
                                    damageInfo.force            = new Vector3(0f, 0f, 0f);
                                    damageInfo.procChainMask    = this.projectileController.procChainMask;
                                    damageInfo.procCoefficient  = this.projectileController.procCoefficient;
                                    damageInfo.damageColorIndex = this.projectileDamage.damageColorIndex;
                                    damageInfo.damageType       = this.projectileDamage.damageType;
                                }
                                else
                                {
                                    Debug.Log("No projectile damage component!");
                                }

                                if (mainHurtBox.healthComponent.gameObject == this.projectileController.owner)
                                {
                                    return;
                                }
                                if (FriendlyFireManager.ShouldDirectHitProceed(health, this.projectileController.teamFilter.teamIndex))
                                {
                                    Util.PlaySound(this.attachTickSoundString, base.gameObject);
                                    if (NetworkServer.active)
                                    {
                                        damageInfo.ModifyDamageInfo(mainHurtBox.damageModifier);
                                        health.TakeDamage(damageInfo);
                                        GlobalEventManager.instance.OnHitEnemy(damageInfo, mainHurtBox.healthComponent.gameObject);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            if (!this.alive)
            {
                if (this.destroyWhenNotAlive)
                {
                    UnityEngine.Object.Destroy(base.gameObject);
                }
            }
        }
        public void OnProjectileImpact(ProjectileImpactInfo impactInfo)
        {
            Debug.LogWarning($"stopwatch: {this.stopwatch}");
            Debug.LogWarning($"stopwatch divided: {this.stopwatch / this.maxCoefficient}");
            Debug.LogWarning($"damage: {this.projectileDamage.damage * (this.stopwatch / this.maxCoefficient)}");
            if (!this.alive)
            {
                return;
            }
            Collider collider = impactInfo.collider;

            hitEnemyInfo     = impactInfo;
            hitEnemyCollider = collider;
            if (collider)
            {
                DamageInfo damageInfo = new DamageInfo();
                if (this.projectileDamage)
                {
                    damageInfo.damage           = this.projectileDamage.damage * (this.stopwatch / this.maxCoefficient);
                    damageInfo.crit             = this.projectileDamage.crit;
                    damageInfo.attacker         = this.projectileController.owner;
                    damageInfo.inflictor        = base.gameObject;
                    damageInfo.position         = impactInfo.estimatedPointOfImpact;
                    damageInfo.force            = this.projectileDamage.force * base.transform.forward;
                    damageInfo.procChainMask    = this.projectileController.procChainMask;
                    damageInfo.procCoefficient  = this.projectileController.procCoefficient;
                    damageInfo.damageColorIndex = this.projectileDamage.damageColorIndex;
                    damageInfo.damageType       = this.projectileDamage.damageType;
                }
                else
                {
                    Debug.Log("No projectile damage component!");
                }
                HurtBox component = collider.GetComponent <HurtBox>();
                if (component)
                {
                    HealthComponent healthComponent = component.healthComponent;
                    if (healthComponent)
                    {
                        if (healthComponent.gameObject == this.projectileController.owner)
                        {
                            return;
                        }
                        if (FriendlyFireManager.ShouldDirectHitProceed(healthComponent, this.projectileController.teamFilter.teamIndex))
                        {
                            Util.PlaySound(this.enemyHitSoundString, base.gameObject);
                            if (NetworkServer.active)
                            {
                                damageInfo.ModifyDamageInfo(component.damageModifier);
                                healthComponent.TakeDamage(damageInfo);
                                this.ApplyIceDebuff(healthComponent);
                                GlobalEventManager.instance.OnHitEnemy(damageInfo, component.healthComponent.gameObject);
                            }
                        }
                        this.alive = false;
                    }
                }
                else if (this.destroyOnWorld)
                {
                    this.alive = false;
                }
                damageInfo.position = base.transform.position;
                if (NetworkServer.active)
                {
                    GlobalEventManager.instance.OnHitAll(damageInfo, collider.gameObject);
                }
            }
            if (this.fireChildren)
            {
                for (int i = 0; i < this.childrenCount; i++)
                {
                    Vector3 vector = new Vector3(UnityEngine.Random.Range(this.minAngleOffset.x, this.maxAngleOffset.x), UnityEngine.Random.Range(this.minAngleOffset.z, this.maxAngleOffset.z), UnityEngine.Random.Range(this.minAngleOffset.z, this.maxAngleOffset.z));
                    switch (this.transformSpace)
                    {
                    case ProjectileImpactExplosion.TransformSpace.World:
                        this.FireChild(vector);
                        break;

                    case ProjectileImpactExplosion.TransformSpace.Local:
                        this.FireChild(base.transform.forward + base.transform.TransformDirection(vector));
                        break;

                    case ProjectileImpactExplosion.TransformSpace.Normal:
                        this.FireChild(this.impactNormal + vector);
                        break;
                    }
                }
            }
            if (!this.alive)
            {
                if (NetworkServer.active && this.impactEffect)
                {
                    EffectManager.SimpleImpactEffect(this.impactEffect, impactInfo.estimatedPointOfImpact, -base.transform.forward, !this.projectileController.isPrediction);
                }
                Util.PlaySound(this.hitSoundString, base.gameObject);
                if (this.destroyWhenNotAlive)
                {
                    UnityEngine.Object.Destroy(base.gameObject);
                }
            }
        }
Пример #13
0
        private void CharacterBody_FixedUpdate(On.RoR2.CharacterBody.orig_FixedUpdate orig, CharacterBody self)
        {
            orig(self);
            if (!NetworkServer.active || !self)
            {
                return;
            }
            var cpt = self.gameObject.GetComponent <HeadsetComponent>();

            if (!cpt)
            {
                cpt = self.gameObject.AddComponent <HeadsetComponent>();
            }
            var count = GetCount(self);

            if (count <= 0)
            {
                cpt.hitsRemaining = 0;
            }
            else if (cpt.hitsRemaining > 0)
            {
                var atkTeam = TeamComponent.GetObjectTeam(self.gameObject);
                var p1      = cpt.previousPos;
                var p2      = self.transform.position;

                Collider[] res;
                if (p1 == p2)
                {
                    res = Physics.OverlapSphere(p1, HITBOX_RADIUS, LayerIndex.entityPrecise.mask, QueryTriggerInteraction.Ignore);
                }
                else
                {
                    res = Physics.OverlapCapsule(p1, p2, HITBOX_RADIUS, LayerIndex.entityPrecise.mask, QueryTriggerInteraction.Ignore);
                }

                var damageInfo = new DamageInfo {
                    attacker         = self.gameObject,
                    inflictor        = self.gameObject,
                    crit             = false,
                    damage           = self.damage * (baseDamagePct + stackDamagePct * (count - 1)),
                    damageColorIndex = DamageColorIndex.Item,
                    damageType       = DamageType.Generic,
                    force            = Vector3.zero,
                    procCoefficient  = 1f
                };

                foreach (var hit in res)
                {
                    if (!hit)
                    {
                        continue;
                    }
                    var hurtbox = hit.GetComponent <HurtBox>();
                    if (!hurtbox ||
                        !hurtbox.healthComponent ||
                        hurtbox.healthComponent == self.healthComponent ||
                        !FriendlyFireManager.ShouldSplashHitProceed(hurtbox.healthComponent, atkTeam))
                    {
                        continue;
                    }
                    var icd = hurtbox.healthComponent.gameObject.GetComponent <HeadsetICDComponent>();
                    if (!icd)
                    {
                        icd = hurtbox.healthComponent.gameObject.AddComponent <HeadsetICDComponent>();
                    }
                    if (Time.fixedTime - icd.lastHit < HIT_INTERVAL)
                    {
                        continue;
                    }
                    icd.lastHit = Time.fixedTime;

                    damageInfo.position = hit.transform.position;
                    hurtbox.healthComponent.TakeDamage(damageInfo);
                    var ssoh = hurtbox.healthComponent.GetComponent <SetStateOnHurt>();
                    if (ssoh && ssoh.canBeStunned)
                    {
                        ssoh.SetStun(stunDuration);
                    }

                    cpt.hitsRemaining--;
                    if (cpt.hitsRemaining <= 0)
                    {
                        break;
                    }
                }

                cpt.previousPos = p2;
            }

            int currBuffStacks = self.GetBuffCount(headsetBuff);

            if (cpt.hitsRemaining != currBuffStacks)
            {
                self.SetBuffCount(headsetBuff.buffIndex, cpt.hitsRemaining);
            }
        }
Пример #14
0
        public void DamageVictim()
        {
            if (!this.active)
            {
                return;
            }
            if (this.stickOnImpact.victim == null)
            {
                return;
            }

            if (this.stickOnImpact.victim)
            {
                DamageInfo damageInfo = new DamageInfo();
                if (this.projectileDamage)
                {
                    damageInfo.damage           = this.projectileDamage.damage * this.damageCoefficient;
                    damageInfo.crit             = this.projectileDamage.crit;
                    damageInfo.attacker         = this.projectileController.owner;
                    damageInfo.inflictor        = base.gameObject;
                    damageInfo.position         = this.stickOnImpact.victim.transform.position;
                    damageInfo.force            = this.projectileDamage.force * base.transform.forward;
                    damageInfo.procChainMask    = this.projectileController.procChainMask;
                    damageInfo.procCoefficient  = this.projectileController.procCoefficient * this.procCoefficient;
                    damageInfo.damageColorIndex = this.projectileDamage.damageColorIndex;
                    damageInfo.damageType       = this.projectileDamage.damageType;
                }
                else
                {
                    Debug.Log("No projectile damage component!");
                }

                HealthComponent victimHealth = this.stickOnImpact.victim.GetComponent <HealthComponent>();
                if (!victimHealth)
                {
                    Debug.Log("No Health Component on Victim!");
                    return;
                }
                if (victimHealth)
                {
                    if (victimHealth.gameObject == this.projectileController.owner)
                    {
                        return;
                    }
                    if (FriendlyFireManager.ShouldDirectHitProceed(victimHealth, this.projectileController.teamFilter.teamIndex))
                    {
                        Util.PlaySound(this.enemyHitSoundString, base.gameObject);
                        if (NetworkServer.active)
                        {
                            CharacterBody victimBody = this.stickOnImpact.victim.GetComponent <CharacterBody>();
                            damageInfo.ModifyDamageInfo(victimBody.mainHurtBox.damageModifier);
                            victimHealth.TakeDamage(damageInfo);
                            GlobalEventManager.instance.OnHitEnemy(damageInfo, victimHealth.gameObject);
                        }
                    }
                }
                damageInfo.position = base.transform.position;
                if (NetworkServer.active)
                {
                    GlobalEventManager.instance.OnHitAll(damageInfo, victimHealth.gameObject);

                    UnityEvent unityEvent = this.onServerHit;
                    if (unityEvent == null)
                    {
                        return;
                    }
                    unityEvent.Invoke();
                }
            }
        }
Пример #15
0
        private void FixedUpdate_Il3(ILContext il)
        {
            BindingFlags allFlags                  = BindingFlags.Public | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
            FieldInfo    characterBody             = typeof(HuntressTracker).GetField("characterBody", allFlags);
            FieldInfo    trackingTarget            = typeof(HuntressTracker).GetField("trackingTarget", allFlags);
            FieldInfo    maxDistance               = typeof(HuntressTracker).GetField("maxTrackingDistance", allFlags);
            FieldInfo    trackerUpdateStopwatch    = typeof(HuntressTracker).GetField("trackerUpdateStopwatch", allFlags);
            FieldInfo    trackerUpdateFrequency    = typeof(HuntressTracker).GetField("trackerUpdateFrequency", allFlags);
            FieldInfo    indicator                 = typeof(HuntressTracker).GetField("indicator", allFlags);
            FieldInfo    indicator_targetTransform = typeof(RoR2.Indicator).GetField("targetTransform", allFlags);
            FieldInfo    hurtBox_group             = typeof(HurtBox).GetField(nameof(HurtBox.hurtBoxGroup), allFlags);
            FieldInfo    mainHurtBox               = typeof(HurtBoxGroup).GetField(nameof(HurtBoxGroup.mainHurtBox), allFlags);

            //MethodInfo fixedDeltaTime = typeof(Time).GetProperty( "fixedDeltaTime", allFlags ).GetGetMethod();
            MethodInfo object_implicit = typeof(UnityEngine.Object).GetMethod("op_Implicit", allFlags);


            HurtBox CastTarget(CharacterBody body, Single range)
            {
                var ray    = body.inputBank.GetAimRay();
                var myTeam = body.teamComponent.teamIndex;
                var hits   = Physics.SphereCastNonAlloc(ray, 0.75f, hitResultsBuffer, range, LayerIndex.entityPrecise.mask, QueryTriggerInteraction.UseGlobal);

                Single worldDist = Single.PositiveInfinity;

                if (hits > 0 && Physics.Raycast(ray, out RaycastHit hit, range, LayerIndex.world.mask, QueryTriggerInteraction.UseGlobal))
                {
                    worldDist = hit.distance + 1f;
                }

                HurtBox result       = null;
                Single  bestDistance = Single.PositiveInfinity;

                for (Int32 i = 0; i < hits; ++i)
                {
                    var res = hitResultsBuffer[i];

                    if (res.distance > bestDistance)
                    {
                        continue;
                    }
                    if (res.distance > worldDist)
                    {
                        continue;
                    }
                    var col = res.collider;
                    if (col is null)
                    {
                        continue;
                    }
                    var hb = col.GetComponent <HurtBox>();
                    if (hb is null)
                    {
                        continue;
                    }
                    var hc = hb.healthComponent;
                    if (hc is null)
                    {
                        continue;
                    }
                    if (hc == body.healthComponent)
                    {
                        continue;
                    }
                    if (!FriendlyFireManager.ShouldDirectHitProceed(hc, myTeam))
                    {
                        continue;
                    }

                    result       = hb;
                    bestDistance = res.distance;
                }
                return(result);
            }

            var cursor = new ILCursor(il);

            _ = cursor.Emit(OpCodes.Stfld, trackingTarget);
            _ = cursor.Emit(OpCodes.Ldarg_0);
            _ = cursor.Emit(OpCodes.Ldfld, indicator);
            _ = cursor.Emit(OpCodes.Ldarg_0);
            _ = cursor.Emit(OpCodes.Ldfld, trackingTarget);
            _ = cursor.Emit(OpCodes.Ldfld, hurtBox_group);
            _ = cursor.Emit(OpCodes.Ldfld, mainHurtBox);
            _ = cursor.Emit <Component>(OpCodes.Callvirt, "get_transform");
            _ = cursor.Emit(OpCodes.Stfld, indicator_targetTransform);
            _ = cursor.Emit(OpCodes.Ldarg_0);
            _ = cursor.Emit(OpCodes.Ldarg_0);
            _ = cursor.Emit(OpCodes.Ldfld, trackerUpdateStopwatch);
            _ = cursor.EmitDelegate <Func <Single> >(() => Time.fixedDeltaTime);
            _ = cursor.Emit(OpCodes.Add);
            _ = cursor.Emit(OpCodes.Stfld, trackerUpdateStopwatch);

            ILLabel normalPath = cursor.MarkLabel();

            _ = cursor.Emit(OpCodes.Pop);
            _ = cursor.Emit(OpCodes.Pop);
            ILLabel breakLabel = null;

            _            = cursor.GotoNext(MoveType.AfterLabel, x => x.MatchBltUn(out breakLabel));
            cursor.Index = 0;
            _            = cursor.Emit(OpCodes.Ldarg_0);
            _            = cursor.Emit(OpCodes.Ldarg_0);
            _            = cursor.Emit(OpCodes.Ldfld, characterBody);
            _            = cursor.Emit(OpCodes.Ldarg_0);
            _            = cursor.Emit(OpCodes.Ldfld, maxDistance);
            _            = cursor.EmitDelegate <Func <CharacterBody, Single, HurtBox> >(CastTarget);
            _            = cursor.Emit(OpCodes.Dup);
            _            = cursor.EmitDelegate <Func <HurtBox, Boolean> >((hb) => hb);
            _            = cursor.Emit(OpCodes.Brfalse, normalPath);
            _            = cursor.GotoLabel(normalPath, MoveType.Before);
            _            = cursor.Emit(OpCodes.Br, breakLabel);
        }