Пример #1
0
        // Token: 0x06001CD8 RID: 7384 RVA: 0x0007B5C0 File Offset: 0x000797C0
        public static void OnCharacterDeath(DamageReport damageReport)
        {
            DotController dotController    = DotController.FindDotController(damageReport.victim.gameObject);
            bool          victimWasBurning = false;

            if (dotController)
            {
                victimWasBurning = (dotController.HasDotActive(DotController.DotIndex.Burn) | dotController.HasDotActive(DotController.DotIndex.PercentBurn) | dotController.HasDotActive(DotController.DotIndex.Helfire));
            }
            StatManager.deathEvents.Enqueue(new StatManager.DeathEvent
            {
                damageReport     = damageReport,
                victimWasBurning = victimWasBurning
            });
        }
        ////// Hooks //////

        private void HealthComponent_TakeDamage(On.RoR2.HealthComponent.orig_TakeDamage orig, HealthComponent self, DamageInfo damageInfo)
        {
            orig(self, damageInfo);

            if (damageInfo == null || !damageInfo.attacker || (damageInfo.damageType & DamageType.DoT) != 0)
            {
                return;
            }

            var dc = DotController.FindDotController(self.gameObject);

            if (!dc || dc.dotStackList.Count <= 0)
            {
                return;
            }

            var body  = damageInfo.attacker.GetComponent <CharacterBody>();
            var count = GetCount(body);

            if (count <= 0)
            {
                return;
            }

            var enemies = GatherEnemies(body.teamComponent.teamIndex, TeamIndex.Neutral)
                          .Select(x => MiscUtil.GetRootWithLocators(x.gameObject))
                          .Where(obj => {
                var hc = obj.GetComponent <HealthComponent>();
                if (!hc || !hc.alive || hc == self)
                {
                    return(false);
                }
                var dvec  = (obj.transform.position - self.transform.position);
                var ddist = dvec.magnitude;
                if (ddist > range)
                {
                    return(false);
                }
                return(true);
            })
                          .ToArray();

            if (enemies.Length <= 0)
            {
                return;
            }

            for (var i = 0; i < count; i++)
            {
                if (!Util.CheckRoll(procChance, body.master))
                {
                    continue;
                }
                var tgt = rng.NextElementUniform(enemies);
                var dot = rng.NextElementUniform(dc.dotStackList);
                var idi = new InflictDotInfo {
                    attackerObject   = damageInfo.attacker,
                    victimObject     = tgt,
                    duration         = dot.timer,
                    dotIndex         = dot.dotIndex,
                    totalDamage      = dot.damage,
                    damageMultiplier = 1f
                };
                DotController.InflictDot(ref idi);
            }
        }
Пример #3
0
        public static void AddHook()
        {
            On.RoR2.HealthComponent.TakeDamage += (orig, self, damageInfo) =>
            {
                bool  aliveBeforeHit       = self.alive;
                bool  resetCooldownsOnKill = false;
                bool  isDynamiteBundle     = false;
                bool  isBarrage            = false;
                float resetDuration        = 0f;

                GracePeriodComponent graceComponent = self.gameObject.GetComponent <GracePeriodComponent>();
                if (!graceComponent)
                {
                    graceComponent = self.gameObject.AddComponent <GracePeriodComponent>();
                }
                bool banditAttacker         = false;
                AssignDynamiteTeamFilter ad = self.gameObject.GetComponent <AssignDynamiteTeamFilter>();
                if (ad)
                {
                    isDynamiteBundle = true;
                }


                CharacterBody attackerCB = null;
                if (damageInfo.attacker)
                {
                    attackerCB = damageInfo.attacker.GetComponent <CharacterBody>();
                    if (attackerCB)
                    {
                        banditAttacker = attackerCB.baseNameToken == "BANDITRELOADED_BODY_NAME";
                    }
                }

                if (banditAttacker && graceComponent)
                {
                    if ((damageInfo.damageType & DamageType.ResetCooldownsOnKill) > 0)
                    {
                        resetCooldownsOnKill = true;
                        if ((damageInfo.damageType & DamageType.SlowOnHit) > 0)
                        {
                            damageInfo.damageType &= ~DamageType.SlowOnHit;
                            isBarrage              = true;
                        }

                        int           debuffCount = 0;
                        DotController d           = DotController.FindDotController(self.gameObject);

                        foreach (BuffIndex buffType in BuffCatalog.debuffBuffIndices)
                        {
                            if (self.body.HasBuff(buffType))
                            {
                                if (buffType != ModContentPack.skullBuff.buffIndex)
                                {
                                    debuffCount++;
                                }
                                else
                                {
                                    debuffCount += self.body.GetBuffCount(buffType);
                                }
                            }
                        }
                        DotController dotController = DotController.FindDotController(self.gameObject);
                        if (dotController)
                        {
                            for (DotController.DotIndex dotIndex = DotController.DotIndex.Bleed; dotIndex < DotController.DotIndex.Count; dotIndex++)
                            {
                                if (dotController.HasDotActive(dotIndex))
                                {
                                    debuffCount++;
                                }
                            }
                        }

                        if (isBarrage && self.body.HasBuff(ModContentPack.lightsOutBuff))
                        {
                            debuffCount--;
                        }

                        float buffDamage     = 0f;
                        float buffBaseDamage = damageInfo.damage * specialDebuffBonus;
                        buffDamage         = buffBaseDamage * debuffCount;
                        damageInfo.damage += buffDamage;

                        bool lightWeight = false;
                        if (self.body)
                        {
                            Rigidbody rb = self.body.rigidbody;
                            if (rb)
                            {
                                if (rb.mass < 50f)
                                {
                                    lightWeight = true;
                                }
                            }
                        }

                        resetDuration = 3.6f;
                        if (!lightWeight)
                        {
                            resetDuration = GracePeriodComponent.graceDuration;
                        }
                    }

                    if (self.alive && (damageInfo.damageType & DamageType.ResetCooldownsOnKill) == 0 && graceComponent.HasReset(attackerCB))
                    {
                        damageInfo.damageType |= DamageType.ResetCooldownsOnKill;
                    }
                }

                if (isDynamiteBundle)
                {
                    if (!ad.fired && banditAttacker && (damageInfo.damageType & DamageType.AOE) == 0 && damageInfo.procCoefficient > 0f)
                    {
                        ad.fired                   = true;
                        damageInfo.crit            = true;
                        damageInfo.procCoefficient = 0f;
                        ProjectileImpactExplosion pie = self.gameObject.GetComponent <ProjectileImpactExplosion>();
                        if (pie)
                        {
                            pie.blastRadius *= 2f;
                        }

                        ProjectileDamage pd = self.gameObject.GetComponent <ProjectileDamage>();
                        if (pd)
                        {
                            if (resetCooldownsOnKill)
                            {
                                pd.damage *= 2f;

                                BanditNetworkCommands bnc = damageInfo.attacker.GetComponent <BanditNetworkCommands>();
                                if (bnc)
                                {
                                    bnc.RpcResetSpecialCooldown();
                                }
                            }
                            else
                            {
                                pd.damage *= 1.5f;
                            }
                        }
                    }
                    else
                    {
                        damageInfo.rejected = true;
                    }
                }

                orig(self, damageInfo);

                if (!self.alive && graceComponent)
                {
                    if (aliveBeforeHit && self.globalDeathEventChanceCoefficient > 0f && self.body && self.body.master)
                    {
                        graceComponent.TriggerEffects(attackerCB);
                    }
                }
                else if (!damageInfo.rejected && self.alive)
                {
                    if (banditAttacker)
                    {
                        if (resetCooldownsOnKill)
                        {
                            if (isBarrage)
                            {
                                self.body.AddTimedBuff(ModContentPack.skullBuff, 3f);
                            }
                            self.body.AddTimedBuff(ModContentPack.lightsOutBuff, resetDuration);

                            if (graceComponent && resetDuration > 0f)
                            {
                                graceComponent.AddTimer(attackerCB, damageInfo.damageType, resetDuration);
                            }
                        }
                    }

                    if (self.body.HasBuff(ModContentPack.lightsOutBuff) && specialExecuteThreshold > 0f)
                    {
                        if (((self.body.bodyFlags & CharacterBody.BodyFlags.ImmuneToExecutes) == 0 && !self.body.isChampion) || specialExecuteBosses)
                        {
                            float executeThreshold = specialExecuteThreshold;
                            float executeToAdd     = 0f;
                            if (self.body.isElite)
                            {
                                executeToAdd = damageInfo.inflictor.GetComponent <CharacterBody>().executeEliteHealthFraction;
                            }
                            if (self.isInFrozenState && executeToAdd < 0.3f)
                            {
                                executeToAdd = 0.3f;
                            }
                            executeThreshold += executeToAdd;

                            if (self.alive && (self.combinedHealthFraction < executeThreshold))
                            {
                                damageInfo.damage           = self.combinedHealth / 2f + 1f;
                                damageInfo.damageType       = (DamageType.ResetCooldownsOnKill | DamageType.BypassArmor);
                                damageInfo.procCoefficient  = 0f;
                                damageInfo.crit             = true;
                                damageInfo.damageColorIndex = DamageColorIndex.WeakPoint;
                                orig(self, damageInfo);
                            }
                        }
                    }
                }
            };
        }