예제 #1
0
파일: HitPatch.cs 프로젝트: jsza/Terraheim
        static void OnDamagedPrefix(Character __instance, ref HitData hit)
        {
            if (hit.HaveAttacker() && hit.GetAttacker().IsPlayer() && hit.GetAttacker().GetSEMan().HaveStatusEffect("Wyrdarrow"))
            {
                (hit.GetAttacker().GetSEMan().GetStatusEffect("Wyrdarrow") as SE_AoECounter).IncreaseCounter();
            }
            if (hit.HaveAttacker() && hit.GetAttacker().IsPlayer() && hit.GetAttacker().GetSEMan().HaveStatusEffect("Brassflesh Listener"))
            {
                if (hit.GetAttacker().GetSEMan().HaveStatusEffect("Brassflesh"))
                {
                    (hit.GetAttacker().GetSEMan().GetStatusEffect("Brassflesh") as SE_ArmorOnHit).OnHit();
                }
                else
                {
                    SEMan seman    = hit.GetAttacker().GetSEMan();
                    float maxArmor = (seman.GetStatusEffect("Brassflesh Listener") as SE_ArmorOnHitListener).GetMaxArmor();
                    seman.AddStatusEffect("Brassflesh");
                    (seman.GetStatusEffect("Brassflesh") as SE_ArmorOnHit).SetMaxArmor(maxArmor);
                }
            }

            if (__instance.IsPlayer() && __instance.GetSEMan().HaveStatusEffect("Challenge Move Speed"))
            {
                //Log.LogInfo($"starting damage: {hit.GetTotalDamage()}");
                float damageMod = 2f;
                hit.m_damage.m_blunt     *= damageMod;
                hit.m_damage.m_chop      *= damageMod;
                hit.m_damage.m_damage    *= damageMod;
                hit.m_damage.m_fire      *= damageMod;
                hit.m_damage.m_frost     *= damageMod;
                hit.m_damage.m_lightning *= damageMod;
                hit.m_damage.m_pickaxe   *= damageMod;
                hit.m_damage.m_pierce    *= damageMod;
                hit.m_damage.m_poison    *= damageMod;
                hit.m_damage.m_slash     *= damageMod;
                hit.m_damage.m_spirit    *= damageMod;
                //Log.LogInfo($"ending damage: {hit.GetTotalDamage()}");
            }

            if (__instance.IsPlayer() && __instance.GetSEMan().HaveStatusEffect("Brassflesh"))
            {
                //Log.LogInfo($"starting damage: {hit.GetTotalDamage()}");
                float damageMod = (__instance.GetSEMan().GetStatusEffect("Brassflesh") as SE_ArmorOnHit).GetCurrentDamageReduction();
                hit.m_damage.m_blunt     *= 1 - damageMod;
                hit.m_damage.m_chop      *= 1 - damageMod;
                hit.m_damage.m_damage    *= 1 - damageMod;
                hit.m_damage.m_fire      *= 1 - damageMod;
                hit.m_damage.m_frost     *= 1 - damageMod;
                hit.m_damage.m_lightning *= 1 - damageMod;
                hit.m_damage.m_pickaxe   *= 1 - damageMod;
                hit.m_damage.m_pierce    *= 1 - damageMod;
                hit.m_damage.m_poison    *= 1 - damageMod;
                hit.m_damage.m_slash     *= 1 - damageMod;
                hit.m_damage.m_spirit    *= 1 - damageMod;
                //Log.LogInfo($"ending damage: {hit.GetTotalDamage()}");
            }
        }
예제 #2
0
        public static void CheckAndDoLifeSteal(HitData hit)
        {
            try
            {
                if (!hit.HaveAttacker())
                {
                    return;
                }

                var attacker = hit.GetAttacker() as Humanoid;
                if (attacker == null)
                {
                    return;
                }

                // TODO track actual weapon which made a hit for better life-steal calculation
                var weapon = attacker.GetCurrentWeapon();

                // in case weapon's durability is destroyed after hit?
                // OR in case damage is delayed and player hides weapon - see to-do above
                if (weapon == null || !weapon.IsMagic() || !(attacker is Player player))
                {
                    return;
                }

                var lifeStealMultiplier = 0f;
                ModifyWithLowHealth.Apply(player, MagicEffectType.LifeSteal, effect => lifeStealMultiplier += player.GetTotalActiveMagicEffectValue(effect, 0.01f));

                if (lifeStealMultiplier == 0)
                {
                    return;
                }

                var healOn = hit.m_damage.GetTotalDamage() * lifeStealMultiplier;

                EpicLoot.Log("lifesteal " + healOn);
                var healFromQueue = false;
                if (attacker.IsPlayer())
                {
                    var healingQueue = attacker.GetComponent <HealingQueueMono>();
                    if (healingQueue)
                    {
                        healFromQueue = true;
                        healingQueue.HealRequests.Add(healOn);
                    }
                }

                if (!healFromQueue)
                {
                    // mostly for NPC with lifeSteal weapon
                    attacker.Heal(healOn);
                }
            }
            catch (Exception e)
            {
                EpicLoot.LogError(e.Message);
            }
        }
예제 #3
0
        public static void RPC_Damage_RP(this Character __instance, long sender, HitData hit)
        {
            if (__instance.IsDebugFlying() || !__instance.m_nview.IsOwner() || __instance.GetHealth() <= 0f || __instance.IsDead() || __instance.IsTeleporting() || __instance.InCutscene() || (hit.m_dodgeable && __instance.IsDodgeInvincible()))
            {
                return;
            }
            Character attacker = hit.GetAttacker();

            if ((hit.HaveAttacker() && attacker == null) || (__instance.IsPlayer() && !__instance.IsPVPEnabled() && attacker != null && attacker.IsPlayer()))
            {
                return;
            }
            if (attacker != null && !attacker.IsPlayer())
            {
                float difficultyDamageScale = Game.instance.GetDifficultyDamageScale(__instance.transform.position);
                hit.ApplyModifier(difficultyDamageScale);
            }
            __instance.m_seman.OnDamaged(hit, attacker);
            if (__instance.m_baseAI != null && !__instance.m_baseAI.IsAlerted() && hit.m_backstabBonus > 1f && Time.time - __instance.m_backstabTime > 300f)
            {
                __instance.m_backstabTime = Time.time;
                hit.ApplyModifier(hit.m_backstabBonus);
                __instance.m_backstabHitEffects.Create(hit.m_point, Quaternion.identity, __instance.transform);
            }
            if (__instance.IsStaggering() && !__instance.IsPlayer())
            {
                hit.ApplyModifier(2f);
                __instance.m_critHitEffects.Create(hit.m_point, Quaternion.identity, __instance.transform);
            }
            if (hit.m_blockable && __instance.IsBlocking())
            {
                __instance.BlockAttack(hit, attacker);
            }
            __instance.ApplyPushback(hit);
            if (!string.IsNullOrEmpty(hit.m_statusEffect))
            {
                StatusEffect statusEffect = __instance.m_seman.GetStatusEffect(hit.m_statusEffect);
                if (statusEffect == null)
                {
                    statusEffect = __instance.m_seman.AddStatusEffect(hit.m_statusEffect);
                }
                if (statusEffect != null && attacker != null)
                {
                    statusEffect.SetAttacker(attacker);
                }
            }
            HitData.DamageModifiers damageModifiers = __instance.GetDamageModifiers();
            hit.ApplyResistance(damageModifiers, out var significantModifier);
            if (__instance.IsPlayer())
            {
                float bodyArmor = __instance.GetBodyArmor();
                hit.ApplyArmor(bodyArmor);
                __instance.DamageArmorDurability(hit);
            }
            __instance.ApplyDamage(hit, showDamageText: true, triggerEffects: true, significantModifier);
        }
예제 #4
0
        static bool Prefix(long sender, HitData hit, Character __instance)
        {
            if (__instance.IsDebugFlying() || !__instance.m_nview.IsOwner() || __instance.GetHealth() <= 0f || __instance.IsDead() || __instance.IsTeleporting() || __instance.InCutscene() || (hit.m_dodgeable && __instance.IsDodgeInvincible()))
            {
                return(false);
            }

            Character attacker = hit.GetAttacker();

            if ((hit.HaveAttacker() && attacker == null) || (__instance.IsPlayer() && !__instance.IsPVPEnabled() && attacker != null && attacker.IsPlayer()))
            {
                return(false);
            }

            if (!string.IsNullOrEmpty(hit.m_statusEffect))
            {
                if (hit.m_statusEffect.StartsWith("Challenged"))
                {
                    if (__instance.IsPlayer() && attacker != null && attacker.IsPlayer() && attacker.IsPVPEnabled())
                    {
                        ((Player)__instance).m_intro = true;
                        var webSocketClient = Mod.WebSocketObject.GetComponent <WebSocketClient>();

                        StatusEffect statusEffect = __instance.m_seman.GetStatusEffect(hit.m_statusEffect);
                        if (statusEffect == null)
                        {
                            statusEffect = __instance.m_seman.AddStatusEffect(hit.m_statusEffect);
                        }
                        if (statusEffect != null)
                        {
                            // start game in here
                            statusEffect.SetAttacker(attacker);
                        }
                        Debug.Log("Challenge open for user id: " + hit.m_attacker.userID);
                        //dynamic message = new JObject();
                        var isAttacker = hit.m_attacker.userID == ZDOMan.instance.GetMyID();

                        var gameId = !isAttacker?Guid.NewGuid().ToString() : hit.m_statusEffect.Split(':').Last();

                        var message = new Message
                        {
                            type    = "connectValheim",
                            isWhite = isAttacker,
                            gameId  = gameId
                        };

                        //message.type = "connectValheim";
                        //message.gameId = ZDOMan.instance.GetMyID().ToString();
                        webSocketClient.Send(JsonMapper.ToJson(message));

                        if (!isAttacker)
                        {
                            //webSocketClient.Send("Challenged by id: " + hit.m_attacker.userID);
                            hit.m_statusEffect = $"Challenged:{gameId}";
                            attacker.Damage(hit);
                        }

                        Application.OpenURL($"{Mod.SiteUrl.Value}/game/{gameId}?isWhite={isAttacker}");
                    }
                    return(false);
                }
            }

            return(true);
        }
예제 #5
0
파일: HitPatch.cs 프로젝트: jsza/Terraheim
        public static void DamagePrefix(Character __instance, ref HitData hit)
        {
            if (!hit.HaveAttacker() || !hit.GetAttacker().IsPlayer())
            {
                return;
            }
            Character attacker = hit.GetAttacker();

            if (attacker.GetSEMan().HaveStatusEffect("Damage Vs Low HP"))
            {
                SE_DamageVSLowHP effect = hit.GetAttacker().GetSEMan().GetStatusEffect("Damage Vs Low HP") as SE_DamageVSLowHP;
                if (__instance.GetHealthPercentage() <= effect.GetHealthThreshold())
                {
                    //Log.LogWarning("Haha get f****d");
                    hit.m_damage.m_blunt     += hit.m_damage.m_blunt * effect.GetDamageBonus();
                    hit.m_damage.m_chop      += hit.m_damage.m_chop * effect.GetDamageBonus();
                    hit.m_damage.m_damage    += hit.m_damage.m_damage * effect.GetDamageBonus();
                    hit.m_damage.m_fire      += hit.m_damage.m_fire * effect.GetDamageBonus();
                    hit.m_damage.m_frost     += hit.m_damage.m_frost * effect.GetDamageBonus();
                    hit.m_damage.m_lightning += hit.m_damage.m_lightning * effect.GetDamageBonus();
                    hit.m_damage.m_pickaxe   += hit.m_damage.m_pickaxe * effect.GetDamageBonus();
                    hit.m_damage.m_pierce    += hit.m_damage.m_pierce * effect.GetDamageBonus();
                    hit.m_damage.m_poison    += hit.m_damage.m_poison * effect.GetDamageBonus();
                    hit.m_damage.m_slash     += hit.m_damage.m_slash * effect.GetDamageBonus();
                    hit.m_damage.m_spirit    += hit.m_damage.m_spirit * effect.GetDamageBonus();

                    var executionVFX          = Object.Instantiate(AssetHelper.FXExecution, __instance.GetCenterPoint(), Quaternion.identity);
                    ParticleSystem[] children = executionVFX.GetComponentsInChildren <ParticleSystem>();
                    foreach (ParticleSystem particle in children)
                    {
                        particle.Play();
                    }

                    var audioSource = hit.GetAttacker().GetComponent <AudioSource>();
                    if (audioSource == null)
                    {
                        audioSource             = hit.GetAttacker().gameObject.AddComponent <AudioSource>();
                        audioSource.playOnAwake = false;
                    }
                    audioSource.PlayOneShot(AssetHelper.SFXExecution);
                }
            }

            if (__instance.GetSEMan().HaveStatusEffect("Marked For Death FX"))
            {
                Log.LogMessage("Increasing damage");
                var effect = __instance.GetSEMan().GetStatusEffect("Marked For Death") as SE_MarkedForDeath;
                hit.m_damage.m_blunt     += hit.m_damage.m_blunt * effect.GetDamageBonus();
                hit.m_damage.m_chop      += hit.m_damage.m_chop * effect.GetDamageBonus();
                hit.m_damage.m_damage    += hit.m_damage.m_damage * effect.GetDamageBonus();
                hit.m_damage.m_fire      += hit.m_damage.m_fire * effect.GetDamageBonus();
                hit.m_damage.m_frost     += hit.m_damage.m_frost * effect.GetDamageBonus();
                hit.m_damage.m_lightning += hit.m_damage.m_lightning * effect.GetDamageBonus();
                hit.m_damage.m_pickaxe   += hit.m_damage.m_pickaxe * effect.GetDamageBonus();
                hit.m_damage.m_pierce    += hit.m_damage.m_pierce * effect.GetDamageBonus();
                hit.m_damage.m_poison    += hit.m_damage.m_poison * effect.GetDamageBonus();
                hit.m_damage.m_slash     += hit.m_damage.m_slash * effect.GetDamageBonus();
                hit.m_damage.m_spirit    += hit.m_damage.m_spirit * effect.GetDamageBonus();

                effect.DecreaseHitsRemaining();

                if ((bool)balance["enableMarkedForDeathFX"])
                {
                    var executionVFX          = Object.Instantiate(AssetHelper.FXMarkedForDeathHit, __instance.GetCenterPoint(), Quaternion.identity);
                    ParticleSystem[] children = executionVFX.GetComponentsInChildren <ParticleSystem>();
                    foreach (ParticleSystem particle in children)
                    {
                        particle.Play();
                    }
                }

                var audioSource = hit.GetAttacker().GetComponent <AudioSource>();
                if (audioSource == null)
                {
                    audioSource             = hit.GetAttacker().gameObject.AddComponent <AudioSource>();
                    audioSource.playOnAwake = false;
                }
                audioSource.PlayOneShot(AssetHelper.SFXExecution);
            }
            if (hit.m_statusEffect == "Marked For Death" && !__instance.GetSEMan().HaveStatusEffect("Marked For Death FX"))
            {
                __instance.GetSEMan().AddStatusEffect("Marked For Death FX");
            }
            if (attacker.GetSEMan().HaveStatusEffect("Death Mark"))
            {
                var effect = hit.GetAttacker().GetSEMan().GetStatusEffect("Death Mark") as SE_DeathMark;

                if (!__instance.GetSEMan().HaveStatusEffect("Marked For Death FX"))
                {
                    //Log.LogInfo(effect.GetLastHitThrowing());
                    if (__instance.GetSEMan().HaveStatusEffect("Marked For Death") && effect.GetLastHitThrowing())
                    {
                        //increase counter
                        (__instance.GetSEMan().GetStatusEffect("Marked For Death") as SE_MarkedForDeath).IncreaseCounter();
                        //Log.LogMessage($"Death Mark Counter : {(__instance.GetSEMan().GetStatusEffect("Marked For Death") as SE_MarkedForDeath).m_count}");
                    }
                    else if (effect.GetLastHitThrowing())
                    {
                        //Log.LogMessage("Adding Death Mark");
                        //add marked for death counter
                        __instance.GetSEMan().AddStatusEffect("Marked For Death");
                        //(__instance.GetSEMan().GetStatusEffect("Marked For Death") as SE_MarkedForDeath).IncreaseCounter();
                        (__instance.GetSEMan().GetStatusEffect("Marked For Death") as SE_MarkedForDeath).SetActivationCount(effect.GetThreshold());
                        (__instance.GetSEMan().GetStatusEffect("Marked For Death") as SE_MarkedForDeath).SetDamageBonus(effect.GetDamageBonus());
                        (__instance.GetSEMan().GetStatusEffect("Marked For Death") as SE_MarkedForDeath).SetHitDuration(effect.GetHitDuration());
                        //Log.LogInfo($"Death Mark Counter : {(__instance.GetSEMan().GetStatusEffect("Marked For Death") as SE_MarkedForDeath).m_count}, " +
                        //$"Activation: {(__instance.GetSEMan().GetStatusEffect("Marked For Death") as SE_MarkedForDeath).GetActivationCount()} " +
                        //$"Damage Bonus: {(__instance.GetSEMan().GetStatusEffect("Marked For Death") as SE_MarkedForDeath).GetDamageBonus()} " +
                        //$"Hit Amount: {(__instance.GetSEMan().GetStatusEffect("Marked For Death") as SE_MarkedForDeath).GetHitDuration()}");
                    }
                }
            }

            if (__instance.GetHealth() <= hit.GetTotalDamage() && attacker.GetSEMan().HaveStatusEffect("Bloodrush Listener"))
            {
                if (attacker.GetSEMan().HaveStatusEffect("Bloodrush"))
                {
                    (attacker.GetSEMan().GetStatusEffect("Bloodrush") as SE_MoveSpeedOnKill).OnKill();
                }
                else
                {
                    attacker.GetSEMan().AddStatusEffect("Bloodrush");
                    (attacker.GetSEMan().GetStatusEffect("Bloodrush") as SE_MoveSpeedOnKill).SetSpeedBonus((attacker.GetSEMan().GetStatusEffect("Bloodrush Listener") as SE_MoveSpeedOnKillListener).GetSpeedBonus());
                }
            }

            if (attacker.GetSEMan().HaveStatusEffect("Pinning") && !__instance.GetSEMan().HaveStatusEffect("Pinned") && !__instance.GetSEMan().HaveStatusEffect("Pinned Cooldown"))
            {
                if (UtilityFunctions.CheckIfVulnerable(__instance, hit) || (attacker as Player).GetCurrentWeapon().m_shared.m_name.Contains("mace_fire"))
                {
                    var effect = attacker.GetSEMan().GetStatusEffect("Pinning") as SE_Pinning;
                    __instance.GetSEMan().AddStatusEffect("Pinned");
                    (__instance.GetSEMan().GetStatusEffect("Pinned") as SE_Pinned).SetPinTTL(effect.GetPinTTL());
                    (__instance.GetSEMan().GetStatusEffect("Pinned") as SE_Pinned).SetPinCooldownTTL(effect.GetPinCooldownTTL());
                }
            }

            if (attacker.GetSEMan().HaveStatusEffect("Poison Vulnerable"))
            {
                if (UtilityFunctions.CheckIfVulnerable(__instance, hit))
                {
                    var effect = attacker.GetSEMan().GetStatusEffect("Poison Vulnerable") as SE_PoisonVulnerable;
                    __instance.AddPoisonDamage(hit.GetTotalDamage() * effect.GetDamageBonus());
                    //hit.m_damage.m_poison += hit.GetTotalDamage() * effect.GetDamageBonus();
                    Log.LogInfo($"Poison damage {hit.GetTotalDamage() * effect.GetDamageBonus()} damage {hit.GetTotalDamage()}");
                }
            }
        }