コード例 #1
0
        public static float GetStartingHealthForType(DestructibleType destructibleType)
        {
            DestructibleProperties properties;

            if (_propertiesByType.TryGetValue(destructibleType, out properties))
            {
                return(properties.startingHealth);
            }
            DebugLog.LogWarningColor("No destructible properties defined for type: " + destructibleType.ToString(), LogColor.yellow);
            return(1);
        }
コード例 #2
0
        /**
         * in Start Patch we put some logic from original Start method and some more logic from original DoMeleeAttack
         */
        static bool Prefix(
            Humanoid character,
            CharacterAnimEvent animEvent,
            ItemDrop.ItemData weapon,
            ref Humanoid ___m_character,
            ref CharacterAnimEvent ___m_animEvent,
            ref ItemDrop.ItemData ___m_weapon,
            ref Attack __instance,
            ref EffectList ___m_hitEffect,
            ref Skills.SkillType ___m_specialHitSkill,
            ref DestructibleType ___m_specialHitType,
            bool ___m_lowerDamagePerHit,
            float ___m_forceMultiplier,
            float ___m_staggerMultiplier,
            float ___m_damageMultiplier,
            int ___m_attackChainLevels,
            int ___m_currentAttackCainLevel,
            ref DestructibleType ___m_resetChainIfHit,
            ref int ___m_nextAttackChainLevel,
            ref EffectList ___m_hitTerrainEffect,
            ref float ___m_attackHeight,
            ref float ___m_attackRange,
            ref float ___m_attackOffset,
            float ___m_attackHitNoise,
            GameObject ___m_spawnOnTrigger,
            ref int ___m_attackMask,
            ref int ___m_attackMaskTerrain,
            ref bool __result
            )
        {
            // if character is not local player, use original Start method
            if (character != Player.m_localPlayer ||
                __instance.m_attackType.ToString() == "Projectile" || !VHVRConfig.UseVrControls())
            {
                return(true);
            }

            ___m_character    = character;
            ___m_animEvent    = animEvent;
            ___m_weapon       = weapon;
            ___m_attackHeight = 0;
            ___m_attackRange  = 0;
            ___m_attackOffset = 0;
            __result          = true;

            if (___m_attackMask == 0)
            {
                ___m_attackMask        = LayerMask.GetMask("Default", "static_solid", "Default_small", "piece", "piece_nonsolid", nameof(character), "character_net", "character_ghost", "hitbox", "character_noenv", "vehicle");
                ___m_attackMaskTerrain = LayerMask.GetMask("Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "terrain", nameof(character), "character_net", "character_ghost", "hitbox", "character_noenv", "vehicle");
            }

            if (!MeshCooldown.staminaDrained)
            {
                float staminaUsage = (float)getStaminaUsageMethod.Invoke(__instance, null);
                if (staminaUsage > 0.0f && !character.HaveStamina(staminaUsage + 0.1f))
                {
                    if (character.IsPlayer())
                    {
                        Hud.instance.StaminaBarNoStaminaFlash();
                    }
                    __result = false;
                    return(false);
                }

                character.UseStamina(staminaUsage);
                MeshCooldown.staminaDrained = true;
            }

            Collider col = StaticObjects.lastHitCollider;
            Vector3  pos = StaticObjects.lastHitPoint;
            Vector3  dir = StaticObjects.lastHitDir;

            if (__instance.m_attackType == Attack.AttackType.Area)
            {
                __instance.OnAttackTrigger();
            }

            doMeleeAttack(___m_character, ___m_weapon, __instance, ___m_hitEffect, ___m_specialHitSkill, ___m_specialHitType, ___m_lowerDamagePerHit, ___m_forceMultiplier, ___m_staggerMultiplier, ___m_damageMultiplier, ___m_attackChainLevels, ___m_currentAttackCainLevel, ___m_resetChainIfHit, ref ___m_nextAttackChainLevel, ___m_hitTerrainEffect, ___m_attackHitNoise, pos, col, dir, ___m_spawnOnTrigger);
            return(false);
        }
コード例 #3
0
        private static void doMeleeAttack(Humanoid ___m_character, ItemDrop.ItemData ___m_weapon, Attack __instance,
                                          EffectList ___m_hitEffect, Skills.SkillType ___m_specialHitSkill, DestructibleType ___m_specialHitType,
                                          bool ___m_lowerDamagePerHit, float ___m_forceMultiplier, float ___m_staggerMultiplier, float ___m_damageMultiplier,
                                          int ___m_attackChainLevels, int ___m_currentAttackCainLevel, DestructibleType ___m_resetChainIfHit,
                                          ref int ___m_nextAttackChainLevel, EffectList ___m_hitTerrainEffect, float ___m_attackHitNoise, Vector3 pos,
                                          Collider col, Vector3 dir, GameObject ___m_spawnOnTrigger)
        {
            Vector3 zero  = Vector3.zero;
            bool    flag2 = false; //rename
            HashSet <Skills.SkillType> skillTypeSet = new HashSet <Skills.SkillType>();
            bool hitOccured = false;

            ___m_weapon.m_shared.m_hitEffect.Create(pos, Quaternion.identity);
            ___m_hitEffect.Create(pos, Quaternion.identity);

            GameObject hitObject = Projectile.FindHitObject(col);

            if (!(hitObject == ___m_character.gameObject))
            {
                Vagon component1 = hitObject.GetComponent <Vagon>();
                if (!component1 || !component1.IsAttached(___m_character))
                {
                    Character component2 = hitObject.GetComponent <Character>();
                    if (!(component2 != null) ||
                        (___m_character.IsPlayer() || BaseAI.IsEnemy(___m_character, component2)) &&
                        (!___m_weapon.m_shared.m_dodgeable || !component2.IsDodgeInvincible()))
                    {
                        hitOccured = true;
                    }
                }
            }

            if (!hitOccured)
            {
                return;
            }

            IDestructible component = hitObject.GetComponent <IDestructible>();

            if (component != null)
            {
                DestructibleType destructibleType = component.GetDestructibleType();
                Skills.SkillType skill            = ___m_weapon.m_shared.m_skillType;

                if (___m_specialHitSkill != Skills.SkillType.None &&
                    (destructibleType & ___m_specialHitType) != DestructibleType.None)
                {
                    skill = ___m_specialHitSkill;
                }

                float randomSkillFactor = ___m_character.GetRandomSkillFactor(skill);

                if (___m_lowerDamagePerHit)
                {
                    randomSkillFactor /= 0.75f;
                }

                HitData hitData = new HitData();
                hitData.m_toolTier     = ___m_weapon.m_shared.m_toolTier;
                hitData.m_statusEffect = ___m_weapon.m_shared.m_attackStatusEffect
                    ? ___m_weapon.m_shared.m_attackStatusEffect.name
                    : "";
                hitData.m_pushForce         = ___m_weapon.m_shared.m_attackForce * randomSkillFactor * ___m_forceMultiplier;
                hitData.m_backstabBonus     = ___m_weapon.m_shared.m_backstabBonus;
                hitData.m_staggerMultiplier = ___m_staggerMultiplier;
                hitData.m_dodgeable         = ___m_weapon.m_shared.m_dodgeable;
                hitData.m_blockable         = ___m_weapon.m_shared.m_blockable;
                hitData.m_skill             = skill;
                hitData.m_damage            = ___m_weapon.GetDamage();
                hitData.m_point             = pos;
                hitData.m_dir         = dir;
                hitData.m_hitCollider = col;
                hitData.SetAttacker(___m_character);
                hitData.m_damage.Modify(___m_damageMultiplier);
                hitData.m_damage.Modify(randomSkillFactor);
                hitData.m_damage.Modify((float)getLevelDamageFactorMethod.Invoke(__instance, null));
                if (___m_attackChainLevels > 1 && ___m_currentAttackCainLevel == ___m_attackChainLevels - 1)
                {
                    hitData.m_damage.Modify(2f);
                    hitData.m_pushForce *= 1.2f;
                }
                hitData.m_damage.Modify(MeshCooldown.calcDamageMultiplier());

                ___m_character.GetSEMan().ModifyAttack(skill, ref hitData);
                if (component is Character)
                {
                    flag2 = true;
                }
                component.Damage(hitData);
                if ((destructibleType & ___m_resetChainIfHit) != DestructibleType.None)
                {
                    ___m_nextAttackChainLevel = 0;
                }
                skillTypeSet.Add(skill);
            }

            ___m_weapon.m_shared.m_hitTerrainEffect.Create(pos,
                                                           Quaternion.identity); // Quaternion.identity might need to be replaced
            ___m_hitTerrainEffect.Create(pos, Quaternion.identity);

            if (___m_weapon.m_shared.m_spawnOnHitTerrain)
            {
                spawnOnHitTerrainMethod.Invoke(__instance,
                                               new object[] { pos, ___m_weapon.m_shared.m_spawnOnHitTerrain });
            }

            if (___m_weapon.m_shared.m_useDurability && ___m_character.IsPlayer())
            {
                ___m_weapon.m_durability -= ___m_weapon.m_shared.m_useDurabilityDrain;
            }
            ___m_character.AddNoise(___m_attackHitNoise);

            if (___m_weapon.m_shared.m_spawnOnHit)
            {
                Object.Instantiate(___m_weapon.m_shared.m_spawnOnHit, pos,
                                   Quaternion.identity).GetComponent <IProjectile>()
                ?.Setup(___m_character, zero, ___m_attackHitNoise, null, ___m_weapon);
            }
            foreach (Skills.SkillType skill in skillTypeSet)
            {
                ___m_character.RaiseSkill(skill, flag2 ? 1.5f : 1f);
            }

            if (!___m_spawnOnTrigger)
            {
                return;
            }
            Object.Instantiate(___m_spawnOnTrigger, zero,
                               Quaternion.identity).GetComponent <IProjectile>()?.Setup(___m_character,
                                                                                        ___m_character.transform.forward, -1f, null, ___m_weapon);

            return;
        }
コード例 #4
0
ファイル: Attack.cs プロジェクト: ingvard/valheim-jserver
    // Token: 0x060002F6 RID: 758 RVA: 0x00018CFC File Offset: 0x00016EFC
    private void DoMeleeAttack()
    {
        Transform transform;
        Vector3   vector;

        this.GetMeleeAttackDir(out transform, out vector);
        Vector3    point      = this.m_character.transform.InverseTransformDirection(vector);
        Quaternion quaternion = Quaternion.LookRotation(vector, Vector3.up);

        this.m_weapon.m_shared.m_triggerEffect.Create(transform.position, quaternion, transform, 1f);
        this.m_triggerEffect.Create(transform.position, quaternion, transform, 1f);
        Vector3 vector2                    = transform.position + Vector3.up * this.m_attackHeight + this.m_character.transform.right * this.m_attackOffset;
        float   num                        = this.m_attackAngle / 2f;
        float   num2                       = 4f;
        float   attackRange                = this.m_attackRange;
        List <Attack.HitPoint>     list    = new List <Attack.HitPoint>();
        HashSet <Skills.SkillType> hashSet = new HashSet <Skills.SkillType>();
        int layerMask                      = this.m_hitTerrain ? Attack.m_attackMaskTerrain : Attack.m_attackMask;

        for (float num3 = -num; num3 <= num; num3 += num2)
        {
            Quaternion rotation = Quaternion.identity;
            if (this.m_attackType == Attack.AttackType.Horizontal)
            {
                rotation = Quaternion.Euler(0f, -num3, 0f);
            }
            else if (this.m_attackType == Attack.AttackType.Vertical)
            {
                rotation = Quaternion.Euler(num3, 0f, 0f);
            }
            Vector3 vector3 = this.m_character.transform.TransformDirection(rotation * point);
            Debug.DrawLine(vector2, vector2 + vector3 * attackRange);
            RaycastHit[] array;
            if (this.m_attackRayWidth > 0f)
            {
                array = Physics.SphereCastAll(vector2, this.m_attackRayWidth, vector3, Mathf.Max(0f, attackRange - this.m_attackRayWidth), layerMask, QueryTriggerInteraction.Ignore);
            }
            else
            {
                array = Physics.RaycastAll(vector2, vector3, attackRange, layerMask, QueryTriggerInteraction.Ignore);
            }
            Array.Sort <RaycastHit>(array, (RaycastHit x, RaycastHit y) => x.distance.CompareTo(y.distance));
            foreach (RaycastHit raycastHit in array)
            {
                if (!(raycastHit.collider.gameObject == this.m_character.gameObject))
                {
                    Vector3 vector4 = raycastHit.point;
                    if (raycastHit.distance < 1E-45f)
                    {
                        if (raycastHit.collider is MeshCollider)
                        {
                            vector4 = vector2 + vector3 * attackRange;
                        }
                        else
                        {
                            vector4 = raycastHit.collider.ClosestPoint(vector2);
                        }
                    }
                    if (this.m_attackAngle >= 180f || Vector3.Dot(vector4 - vector2, vector) > 0f)
                    {
                        GameObject gameObject = Projectile.FindHitObject(raycastHit.collider);
                        if (!(gameObject == this.m_character.gameObject))
                        {
                            Vagon component = gameObject.GetComponent <Vagon>();
                            if (!component || !component.IsAttached(this.m_character))
                            {
                                Character component2 = gameObject.GetComponent <Character>();
                                if (!(component2 != null) || ((this.m_character.IsPlayer() || BaseAI.IsEnemy(this.m_character, component2)) && (!this.m_weapon.m_shared.m_dodgeable || !component2.IsDodgeInvincible())))
                                {
                                    this.AddHitPoint(list, gameObject, raycastHit.collider, vector4, raycastHit.distance);
                                    if (!this.m_hitThroughWalls)
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        int     num4    = 0;
        Vector3 vector5 = Vector3.zero;
        bool    flag    = false;
        bool    flag2   = false;

        foreach (Attack.HitPoint hitPoint in list)
        {
            GameObject go      = hitPoint.go;
            Vector3    vector6 = hitPoint.avgPoint / (float)hitPoint.count;
            Vector3    vector7 = vector6;
            switch (this.m_hitPointtype)
            {
            case Attack.HitPointType.Closest:
                vector7 = hitPoint.closestPoint;
                break;

            case Attack.HitPointType.Average:
                vector7 = vector6;
                break;

            case Attack.HitPointType.First:
                vector7 = hitPoint.firstPoint;
                break;
            }
            num4++;
            vector5 += vector6;
            this.m_weapon.m_shared.m_hitEffect.Create(vector7, Quaternion.identity, null, 1f);
            this.m_hitEffect.Create(vector7, Quaternion.identity, null, 1f);
            IDestructible component3 = go.GetComponent <IDestructible>();
            if (component3 != null)
            {
                DestructibleType destructibleType = component3.GetDestructibleType();
                Skills.SkillType skillType        = this.m_weapon.m_shared.m_skillType;
                if (this.m_specialHitSkill != Skills.SkillType.None && (destructibleType & this.m_specialHitType) != DestructibleType.None)
                {
                    skillType = this.m_specialHitSkill;
                }
                float num5 = this.m_character.GetRandomSkillFactor(skillType);
                if (this.m_lowerDamagePerHit && list.Count > 1)
                {
                    num5 /= (float)list.Count * 0.75f;
                }
                HitData hitData = new HitData();
                hitData.m_toolTier          = this.m_weapon.m_shared.m_toolTier;
                hitData.m_statusEffect      = (this.m_weapon.m_shared.m_attackStatusEffect ? this.m_weapon.m_shared.m_attackStatusEffect.name : "");
                hitData.m_pushForce         = this.m_weapon.m_shared.m_attackForce * num5 * this.m_forceMultiplier;
                hitData.m_backstabBonus     = this.m_weapon.m_shared.m_backstabBonus;
                hitData.m_staggerMultiplier = this.m_staggerMultiplier;
                hitData.m_dodgeable         = this.m_weapon.m_shared.m_dodgeable;
                hitData.m_blockable         = this.m_weapon.m_shared.m_blockable;
                hitData.m_skill             = skillType;
                hitData.m_damage            = this.m_weapon.GetDamage();
                hitData.m_point             = vector7;
                hitData.m_dir         = (vector7 - vector2).normalized;
                hitData.m_hitCollider = hitPoint.collider;
                hitData.SetAttacker(this.m_character);
                hitData.m_damage.Modify(this.m_damageMultiplier);
                hitData.m_damage.Modify(num5);
                hitData.m_damage.Modify(this.GetLevelDamageFactor());
                if (this.m_attackChainLevels > 1 && this.m_currentAttackCainLevel == this.m_attackChainLevels - 1)
                {
                    hitData.m_damage.Modify(2f);
                    hitData.m_pushForce *= 1.2f;
                }
                this.m_character.GetSEMan().ModifyAttack(skillType, ref hitData);
                if (component3 is Character)
                {
                    flag2 = true;
                }
                component3.Damage(hitData);
                if ((destructibleType & this.m_resetChainIfHit) != DestructibleType.None)
                {
                    this.m_nextAttackChainLevel = 0;
                }
                hashSet.Add(skillType);
                if (!this.m_multiHit)
                {
                    break;
                }
            }
            if (go.GetComponent <Heightmap>() != null && !flag)
            {
                flag = true;
                this.m_weapon.m_shared.m_hitTerrainEffect.Create(vector6, quaternion, null, 1f);
                this.m_hitTerrainEffect.Create(vector6, quaternion, null, 1f);
                if (this.m_weapon.m_shared.m_spawnOnHitTerrain)
                {
                    this.SpawnOnHitTerrain(vector6, this.m_weapon.m_shared.m_spawnOnHitTerrain);
                }
                if (!this.m_multiHit)
                {
                    break;
                }
            }
        }
        if (num4 > 0)
        {
            vector5 /= (float)num4;
            if (this.m_weapon.m_shared.m_useDurability && this.m_character.IsPlayer())
            {
                this.m_weapon.m_durability -= this.m_weapon.m_shared.m_useDurabilityDrain;
            }
            this.m_character.AddNoise(this.m_attackHitNoise);
            this.m_animEvent.FreezeFrame(0.15f);
            if (this.m_weapon.m_shared.m_spawnOnHit)
            {
                IProjectile component4 = UnityEngine.Object.Instantiate <GameObject>(this.m_weapon.m_shared.m_spawnOnHit, vector5, quaternion).GetComponent <IProjectile>();
                if (component4 != null)
                {
                    component4.Setup(this.m_character, Vector3.zero, this.m_attackHitNoise, null, this.m_weapon);
                }
            }
            foreach (Skills.SkillType skill in hashSet)
            {
                this.m_character.RaiseSkill(skill, flag2 ? 1.5f : 1f);
            }
        }
        if (this.m_spawnOnTrigger)
        {
            IProjectile component5 = UnityEngine.Object.Instantiate <GameObject>(this.m_spawnOnTrigger, vector2, Quaternion.identity).GetComponent <IProjectile>();
            if (component5 != null)
            {
                component5.Setup(this.m_character, this.m_character.transform.forward, -1f, null, this.m_weapon);
            }
        }
    }