Esempio n. 1
0
        static bool PointInsideRect(Point2 point, Point2 rectCenter, HitBoxType rectSize)
        {
            double left   = rectCenter.x - rectSize.Width / 2,
                   right  = rectCenter.x + rectSize.Width / 2,
                   top    = rectCenter.y - rectSize.Height / 2,
                   bottom = rectCenter.y + rectSize.Height / 2;


            return(point.x >= left && point.x <= right && point.y >= top && point.y <= bottom);
        }
Esempio n. 2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ShotEventArgs"/> class.
        /// </summary>
        /// <param name="shooter"><inheritdoc cref="Shooter"/></param>
        /// <param name="target"><inheritdoc cref="Target"/></param>
        /// <param name="hitboxType"><inheritdoc cref="HitboxType"/></param>
        /// <param name="distance"><inheritdoc cref="Distance"/></param>
        /// <param name="damage"><inheritdoc cref="Damage"/></param>
        /// <param name="canHurt"><inheritdoc cref="CanHurt"/></param>
        public ShotEventArgs(Player shooter, GameObject target, HitBoxType hitboxType, float distance, float damage, bool canHurt = true)
        {
            Shooter = shooter;
            Target  = target;
#pragma warning disable CS0618 // Type or member is obsolete
            HitboxType = hitboxType.ToString().ToLowerInvariant();
#pragma warning restore CS0618 // Type or member is obsolete
            HitboxTypeEnum = hitboxType;
            Distance       = distance;
            Damage         = damage;
            CanHurt        = canHurt;
        }
Esempio n. 3
0
    /// <summary>
    /// Initializes a new instance of the <see cref="HitBox"/> class by copying the values from the
    /// given template.
    /// </summary>
    public HitBox(HitBox template)
    {
        // Copy the data fields from the given templates
        this.hitBoxType = template.hitBoxType;
        this.boneName   = template.boneName;
        this.offset     = template.offset;
        this.size       = template.size;

        // Duplicate the 'hitFrames' array
        this.hitFrames = ArrayUtils.Copy <int>(template.hitFrames);

        // Create a deep copy of the HitInfo instance>
        this.hitInfo = new HitInfo(template.hitInfo);
    }
Esempio n. 4
0
 public UnitForCollision(Unit unit)
 {
     this.unit = unit;
     this.hp   = unit.Hp;
     this.team = unit.Owner;
     //создаем чуть увеиченный хитбокс, чтобы считать снаряд точкой
     //решение не идеально точное, но сойдет
     hitBox = new HitBoxType
     {
         Height = unit.HitBox.Height + Const.ShellRadius * 2,
         Width  = unit.HitBox.Width + Const.ShellRadius * 2
     };
     this.maxRadius = Math.Sqrt(Geometry.Sqr(hitBox.Width / 2) + Geometry.Sqr(hitBox.Height / 2));
 }
        private static void Postfix(WeaponManager __instance, HitBoxType hitboxType, GameObject target)
        {
            // If limb damage is disabled; just don't do anything on the patch.
            if (!HardcoreSl.Instance.Config.EnableLimbDamage)
            {
                return;
            }

            if (target == null || __instance.gameObject == null)
            {
                return;
            }

            if (!ReferenceHub.TryGetHub(target, out var targetHub) || !ReferenceHub.TryGetHub(__instance.gameObject, out var ourHub))
            {
                return;
            }

            // Copied basically from HurtPlayer. Prevent limb damage on friendly fire targets.
            bool ff = targetHub.characterClassManager.Fraction == ourHub.characterClassManager.Fraction;

            if (ff && !GameCore.ConfigFile.ServerConfig.GetBool("friendly_fire"))
            {
                return;
            }

            if (!__instance.TryGetComponent(out PlayerHardcoreComponent instanceComponent) ||
                !target.TryGetComponent(out PlayerHardcoreComponent targetComponent))
            {
                return;
            }

            // No limb damage on SCPs - with the exception of 049-2.
            if (targetHub.characterClassManager.IsAnyScp() && targetHub.characterClassManager.CurClass != RoleType.Scp0492)
            {
                return;
            }

            float dis    = Vector3.Distance(__instance.camera.transform.position, target.transform.position);
            float damage = __instance.weapons[__instance.curWeapon].damageOverDistance.Evaluate(dis);

            targetComponent.RegisterHit(hitboxType, damage, instanceComponent);
        }
Esempio n. 6
0
 public PlayerShootEvent(Player player, Player target, Weapon weapon, WeaponSound?weaponSound, Vector sourcePosition, Vector targetPosition, HitBoxType targetHitbox, Vector direction, bool spawnHitmarker = true, bool spawnBloodDecal = true) : base(player)
 {
     this.Target = target;
     this.Weapon = weapon;
     this.ShouldSpawnHitmarker  = spawnHitmarker;
     this.ShouldSpawnBloodDecal = spawnBloodDecal;
     this.SourcePosition        = sourcePosition;
     this.TargetPosition        = targetPosition;
     this.TargetHitbox          = targetHitbox;
     this.Direction             = direction;
     this.WeaponSound           = weaponSound;
 }
Esempio n. 7
0
        private static bool Prefix(WeaponManager __instance, GameObject target, HitBoxType hitboxType, Vector3 dir, Vector3 sourcePos, Vector3 targetPos)
        {
            try
            {
                bool npc = Npc.Dictionary.ContainsKey(__instance.gameObject);

                if (!__instance._iawRateLimit.CanExecute(true))
                {
                    return(false);
                }

                int itemIndex = __instance._hub.inventory.GetItemIndex();

                if (!npc)
                {
                    if (itemIndex < 0 ||
                        itemIndex >= __instance._hub.inventory.items.Count ||
                        __instance.curWeapon < 0 ||
                        __instance._hub.inventory.curItem != __instance.weapons[__instance.curWeapon].inventoryID ||
                        __instance._hub.inventory.items[itemIndex].durability <= 0.0)
                    {
                        return(false);
                    }

                    if (Vector3.Distance(__instance._hub.playerMovementSync.RealModelPosition, sourcePos) > 5.5f)
                    {
                        __instance.GetComponent <CharacterClassManager>().TargetConsolePrint(__instance.connectionToClient, "Shot rejected - Code W.6 (difference between real source position and provided source position is too big)", "gray");
                        return(false);
                    }

                    if (sourcePos.y - __instance._hub.playerMovementSync.LastSafePosition.y > 1.78f)
                    {
                        __instance.GetComponent <CharacterClassManager>().TargetConsolePrint(__instance.connectionToClient, "Shot rejected - Code W.7 (Y axis difference between last safe position and provided source position is too big)", "gray");
                        return(false);
                    }

                    if (Math.Abs(sourcePos.y - __instance._hub.playerMovementSync.RealModelPosition.y) > 2.7f)
                    {
                        __instance.GetComponent <CharacterClassManager>().TargetConsolePrint(__instance.connectionToClient, "Shot rejected - Code W.8 (|Y| axis difference between real position and provided source position is too big)", "gray");
                        return(false);
                    }
                }

                if ((__instance._reloadCooldown > 0f || __instance._fireCooldown > 0f) && !__instance.isLocalPlayer)
                {
                    return(false);
                }

                Log.Debug("Invoking shooting event", Loader.ShouldDebugBeShown);

                var shootingEventArgs = new ShootingEventArgs(Player.Get(__instance.gameObject), target, targetPos);

                Exiled.Events.Handlers.Player.OnShooting(shootingEventArgs);

                if (!shootingEventArgs.IsAllowed)
                {
                    return(false);
                }

                targetPos = shootingEventArgs.Position;

                // <Exiled
                if (!npc)
                {
                    __instance._hub.inventory.items.ModifyDuration(itemIndex, __instance._hub.inventory.items[itemIndex].durability - 1f);
                }
                __instance.scp268.ServerDisable();
                __instance._fireCooldown = 1f / (__instance.weapons[__instance.curWeapon].shotsPerSecond * __instance.weapons[__instance.curWeapon].allEffects.firerateMultiplier) * 0.9f;

                float sourceRangeScale = __instance.weapons[__instance.curWeapon].allEffects.audioSourceRangeScale;
                sourceRangeScale = sourceRangeScale * sourceRangeScale * 70f;
                __instance.GetComponent <Scp939_VisionController>().MakeNoise(Mathf.Clamp(sourceRangeScale, 5f, 100f));

                bool flag = target != null;
                if (targetPos == Vector3.zero)
                {
                    if (Physics.Raycast(sourcePos, dir, out RaycastHit raycastHit, 500f, __instance.raycastMask))
                    {
                        HitboxIdentity component = raycastHit.collider.GetComponent <HitboxIdentity>();
                        if (component != null)
                        {
                            WeaponManager componentInParent = component.GetComponentInParent <WeaponManager>();
                            if (componentInParent != null)
                            {
                                flag       = false;
                                target     = componentInParent.gameObject;
                                hitboxType = component.id;
                                targetPos  = componentInParent.transform.position;
                            }
                        }
                    }
                }
                else if (Physics.Linecast(sourcePos, targetPos, out RaycastHit raycastHit, __instance.raycastMask))
                {
                    HitboxIdentity component = raycastHit.collider.GetComponent <HitboxIdentity>();
                    if (component != null)
                    {
                        WeaponManager componentInParent = component.GetComponentInParent <WeaponManager>();
                        if (componentInParent != null)
                        {
                            if (componentInParent.gameObject == target)
                            {
                                flag = false;
                            }
                            else if (componentInParent.scp268.Enabled)
                            {
                                flag       = false;
                                target     = componentInParent.gameObject;
                                hitboxType = component.id;
                                targetPos  = componentInParent.transform.position;
                            }
                        }
                    }
                }

                ReferenceHub referenceHub = null;
                if (target != null)
                {
                    referenceHub = ReferenceHub.GetHub(target);
                }

                if (referenceHub != null && __instance.GetShootPermission(referenceHub.characterClassManager, false))
                {
                    if (!npc)
                    {
                        if (Math.Abs(__instance._hub.playerMovementSync.RealModelPosition.y - referenceHub.playerMovementSync.RealModelPosition.y) > 35f)
                        {
                            __instance.GetComponent <CharacterClassManager>().TargetConsolePrint(__instance.connectionToClient, "Shot rejected - Code W.1 (too big Y-axis difference between source and target)", "gray");
                            return(false);
                        }

                        if (Vector3.Distance(referenceHub.playerMovementSync.RealModelPosition, targetPos) > 5f)
                        {
                            __instance.GetComponent <CharacterClassManager>().TargetConsolePrint(__instance.connectionToClient, "Shot rejected - Code W.2 (difference between real target position and provided target position is too big)", "gray");
                            return(false);
                        }

                        if (Physics.Linecast(__instance._hub.playerMovementSync.RealModelPosition, sourcePos, __instance.raycastServerMask))
                        {
                            __instance.GetComponent <CharacterClassManager>().TargetConsolePrint(__instance.connectionToClient, "Shot rejected - Code W.3 (collision between source positions detected)", "gray");
                            return(false);
                        }

                        if (flag && Physics.Linecast(sourcePos, targetPos, __instance.raycastServerMask))
                        {
                            __instance.GetComponent <CharacterClassManager>().TargetConsolePrint(__instance.connectionToClient, "Shot rejected - Code W.4 (collision on shot line detected)", "gray");
                            return(false);
                        }

                        if (referenceHub.gameObject == __instance.gameObject)
                        {
                            __instance.GetComponent <CharacterClassManager>().TargetConsolePrint(__instance.connectionToClient, "Shot rejected - Code W.5 (target is itself)", "gray");
                            return(false);
                        }

                        Vector3 positionOffset = referenceHub.playerMovementSync.RealModelPosition - __instance._hub.playerMovementSync.RealModelPosition;
                        float   sqrMagnitude   = positionOffset.sqrMagnitude;
                        if (Math.Abs(positionOffset.y) < 10f && sqrMagnitude > 7.84f && (referenceHub.characterClassManager.CurClass != global::RoleType.Scp0492 || sqrMagnitude > 9f) && ((referenceHub.characterClassManager.CurClass != global::RoleType.Scp93953 && referenceHub.characterClassManager.CurClass != global::RoleType.Scp93989) || sqrMagnitude > 18.49f))
                        {
                            float angl = Math.Abs(global::Misc.AngleIgnoreY(positionOffset, __instance.transform.forward));
                            if (angl > 45f)
                            {
                                __instance.GetComponent <global::CharacterClassManager>().TargetConsolePrint(__instance.connectionToClient, "Shot rejected - Code W.12 (too big angle)", "gray");
                                return(false);
                            }
                            if (__instance._lastAngleReset > 0f && angl > 25f && Math.Abs(global::Misc.AngleIgnoreY(positionOffset, __instance._lastAngle)) > 60f)
                            {
                                __instance._lastAngle      = positionOffset;
                                __instance._lastAngleReset = 0.4f;
                                __instance.GetComponent <global::CharacterClassManager>().TargetConsolePrint(__instance.connectionToClient, "Shot rejected - Code W.13 (too big angle v2)", "gray");
                                return(false);
                            }
                            __instance._lastAngle      = positionOffset;
                            __instance._lastAngleReset = 0.4f;
                        }
                        if (__instance._lastRotationReset > 0f && (__instance._hub.playerMovementSync.Rotations.x < 68f || __instance._hub.playerMovementSync.Rotations.x > 295f))
                        {
                            float num5 = __instance._hub.playerMovementSync.Rotations.x - __instance._lastRotation;
                            if (num5 >= 0f && num5 <= 0.0005f)
                            {
                                __instance._lastRotation      = __instance._hub.playerMovementSync.Rotations.x;
                                __instance._lastRotationReset = 0.35f;
                                __instance.GetComponent <global::CharacterClassManager>().TargetConsolePrint(__instance.connectionToClient, "Shot rejected - Code W.9 (no recoil)", "gray");
                                return(false);
                            }
                        }
                        __instance._lastRotation      = __instance._hub.playerMovementSync.Rotations.x;
                        __instance._lastRotationReset = 0.35f;
                    }

                    float num2 = Vector3.Distance(__instance.camera.transform.position, target.transform.position);
                    float num3 = __instance.weapons[(int)__instance.curWeapon].damageOverDistance.Evaluate(num2);
                    switch (referenceHub.characterClassManager.CurClass)
                    {
                    case RoleType.Scp106:
                        num3 /= 10f;
                        goto IL_6D1;

                    case RoleType.Scp049:
                    case RoleType.Scp079:
                    case RoleType.Scp096:
                    case RoleType.Scp173:
                    case RoleType.Scp93953:
                    case RoleType.Scp93989:
                        goto IL_6D1;

                    default:
                        switch (hitboxType)
                        {
                        case HitBoxType.HEAD:
                            num3 *= 4;
                            float num4 = 1 / (__instance.weapons[(int)__instance.curWeapon].shotsPerSecond * __instance.weapons[(int)__instance.curWeapon].allEffects.firerateMultiplier);
                            __instance._headshotsL++;
                            __instance._headshotsS++;
                            __instance._headshotsResetS = num4 * 1.86f;
                            __instance._headshotsResetL = num4 * 2.9f;

                            if (__instance._headshotsS >= 3)
                            {
                                __instance._hub.playerMovementSync.AntiCheatKillPlayer("Headshots limit exceeded in time window A\n(debug code: W.10)", "W.10");
                                return(false);
                            }

                            if (__instance._headshotsL >= 4)
                            {
                                __instance._hub.playerMovementSync.AntiCheatKillPlayer("Headshots limit exceeded in time window B\n(debug code: W.11)", "W.11");
                                return(false);
                            }

                            break;

                        case HitBoxType.ARM:
                        case HitBoxType.LEG:
                            num3 /= 2;
                            break;
                        }

                        break;
                    }

IL_6D1:
                    num3 *= __instance.weapons[(int)__instance.curWeapon].allEffects.damageMultiplier;
                    num3 *= __instance.overallDamagerFactor;

                    // >Exiled
                    Log.Debug("Invoking late shoot.", Loader.ShouldDebugBeShown);

                    var shotEventArgs = new ShotEventArgs(Player.Get(__instance.gameObject), target, hitboxType, num2, num3);

                    Exiled.Events.Handlers.Player.OnShot(shotEventArgs);

                    if (!shotEventArgs.CanHurt)
                    {
                        return(false);
                    }

                    // <Exiled
                    __instance._hub.playerStats.HurtPlayer(
                        new PlayerStats.HitInfo(
                            shotEventArgs.Damage,
                            __instance._hub.LoggedNameFromRefHub(),
                            DamageTypes.FromWeaponId(__instance.curWeapon),
                            __instance._hub.queryProcessor.PlayerId),
                        referenceHub.gameObject);

                    __instance.RpcConfirmShot(hitmarker: true, __instance.curWeapon);
                    __instance.PlaceDecal(isBlood: true, new Ray(__instance.camera.position, dir), (int)referenceHub.characterClassManager.CurClass, num2);
                }
                else if (target != null && hitboxType == HitBoxType.WINDOW && target.GetComponent <BreakableWindow>() != null)
                {
                    float time   = Vector3.Distance(__instance.camera.transform.position, target.transform.position);
                    float damage = __instance.weapons[__instance.curWeapon].damageOverDistance.Evaluate(time);
                    target.GetComponent <BreakableWindow>().ServerDamageWindow(damage);
                    __instance.RpcConfirmShot(hitmarker: true, __instance.curWeapon);
                }
                else
                {
                    __instance.PlaceDecal(isBlood: false, new Ray(__instance.camera.position, dir), __instance.curWeapon, 0f);
                    __instance.RpcConfirmShot(hitmarker: false, __instance.curWeapon);
                }

                return(false);
            }
            catch (Exception e)
            {
                Exiled.API.Features.Log.Error($"{typeof(ShootFixPatch).FullName}.{nameof(Prefix)}:\n{e}");

                return(true);
            }
        }
Esempio n. 8
0
 public void SetHitbox(Rectangle rect, HitBoxType type)
 {
     BoundingBox = rect;
     this.type   = type;
 }
Esempio n. 9
0
 public BasicHitBox(Rectangle rect, HitBoxType type)
 {
     BoundingBox = rect;
     this.type   = type;
 }
Esempio n. 10
0
 public BasicHitBox(Rectangle rect)
 {
     BoundingBox = rect;
     this.type   = HitBoxType.Basic;
 }
    void DrawHitBoxesList(MeleeAttackObject attackObject)
    {
        if (attackObject != null && attackObject.hitBoxes != null)
        {
            for (int i = 0; i < attackObject.hitBoxes.Count; i++)
            {
                try
                {
                    GUILayout.BeginHorizontal();
                    if (attackObject.hitBoxes[i] != null && attackObject.hitBoxes[i].transform == attackObject.transform ||
                        (attackObject.GetComponent <HitBox>() != null))
                    {
                        DestroyImmediate(attackObject.GetComponent <HitBox>());
                        attackObject.hitBoxes.RemoveAt(i);
                        GUILayout.EndHorizontal();
                        break;
                    }
                    Color color = GUI.color;
                    GUI.color = seletedHitboxIndex == i ? new Color(1, 1, 0, 0.6f) : color;

                    if (GUILayout.Button("Hit Box " + (i + 1), EditorStyles.miniButton))
                    {
                        if (seletedHitboxIndex == i)
                        {
                            seletedHitboxIndex = -1;
                        }
                        else
                        {
                            seletedHitboxIndex = i;
                        }
                    }
                    GUI.color = color;
                    if (attackObject.hitBoxes.Count > 1 && GUILayout.Button("X", EditorStyles.miniButton, GUILayout.Width(20)))
                    {
                        if (attackObject.hitBoxes[i] != null && attackObject.hitBoxes[i].transform != attackObject.transform)
                        {
                            DestroyImmediate(attackObject.hitBoxes[i].gameObject);
                        }
                        attackObject.hitBoxes.RemoveAt(i);
                        GUILayout.EndHorizontal();
                        break;
                    }
                    GUILayout.EndHorizontal();
                }
                catch { }
            }
        }

        if (seletedHitboxIndex > -1 && seletedHitboxIndex < attackObject.hitBoxes.Count)
        {
            GUILayout.BeginVertical("box");
            var hitBox = attackObject.hitBoxes[seletedHitboxIndex];
            if (hitBox)
            {
                EditorGUILayout.ObjectField("Selected Hit Box " + (seletedHitboxIndex + 1), hitBox, typeof(HitBox), true);
                //GUILayout.Box("Hit Settings", GUILayout.ExpandWidth(true));
                hitBox.damagePercentage = EditorGUILayout.IntSlider("Damage Percentage", hitBox.damagePercentage, 0, 100);
#if UNITY_2017_1_OR_NEWER
                hitBox.triggerType = (HitBoxType)EditorGUILayout.EnumFlagsField("Trigger Type", hitBox.triggerType);
#else
                hitBox.triggerType = (vHitBoxType)EditorGUILayout.EnumMaskField("Trigger Type", hitBox.triggerType);
#endif
                if (GUI.changed)
                {
                    EditorUtility.SetDirty(hitBox);
                }
            }
            GUILayout.EndVertical();
        }

        GUILayout.Space(10);

        if (!inCreateHitBox && GUILayout.Button("Create New Hit Box", EditorStyles.miniButton))
        {
            inCreateHitBox   = true;
            damagePercentage = 100;
            triggerType      = HitBoxType.Damage | HitBoxType.Recoil;
        }
        if (inCreateHitBox)
        {
            GUILayout.Box("New Hit Box", GUILayout.ExpandWidth(true));
            damagePercentage = EditorGUILayout.IntSlider("Damage Percentage", damagePercentage, 0, 100);

#if UNITY_2017_1_OR_NEWER
            triggerType = (HitBoxType)EditorGUILayout.EnumFlagsField("Trigger Type", triggerType);
#else
            triggerType = (vHitBoxType)EditorGUILayout.EnumMaskField("Trigger Type", triggerType);
#endif

            GUILayout.BeginHorizontal();

            if (GUILayout.Button("Create", EditorStyles.miniButton, GUILayout.ExpandWidth(true)))
            {
                var type      = typeof(BoxCollider);
                var hitObject = new GameObject("hitBox", typeof(HitBox), type);
                hitObject.transform.localScale       = Vector3.one * 0.2f;
                hitObject.transform.parent           = attackObject.transform;
                hitObject.transform.localPosition    = Vector3.zero;
                hitObject.transform.localEulerAngles = Vector3.zero;
                var hitBox = hitObject.GetComponent <HitBox>();
                hitBox.damagePercentage = damagePercentage;
                hitBox.triggerType      = triggerType;
                attackObject.hitBoxes.Add(hitBox);
                inCreateHitBox = false;
            }

            if (GUILayout.Button("Cancel", EditorStyles.miniButton, GUILayout.ExpandWidth(true)))
            {
                inCreateHitBox = false;
            }
            GUILayout.EndHorizontal();
        }

        GUILayout.Space(10);
    }
Esempio n. 12
0
        public override float Process(Npc npc)
        {
            if (!npc.NPCPlayer.ReferenceHub.characterClassManager.IsAnyScp())
            {
                if (npc.AvailableWeapons.Count > 0)
                {
                    if (!npc.ItemHeld.IsWeapon(false))
                    {
                        npc.ItemHeld = npc.AvailableWeapons.Keys.ElementAt(0);
                        return(0.5f);
                    }

                    npc.Stop();
                    Vector3    heading = (npc.CurrentAIPlayerTarget.Position - npc.NPCPlayer.Position);
                    Quaternion lookRot = Quaternion.LookRotation(heading.normalized);
                    npc.NPCPlayer.Rotations = new Vector2(lookRot.eulerAngles.x, lookRot.eulerAngles.y);
                    bool       miss         = Plugin.Random.Next(0, 100) >= accuracy;
                    int        hitbox_value = Plugin.Random.Next(0, 100);
                    HitBoxType hitbox       = HitBoxType.NULL;
                    int        min          = int.MaxValue;
                    foreach (HitBoxType box in hitboxes.Keys)
                    {
                        if (hitbox_value < hitboxes[box] && hitboxes[box] <= min)
                        {
                            min    = hitboxes[box];
                            hitbox = box;
                        }
                    }

                    npc.NPCPlayer.ReferenceHub.weaponManager.CallCmdShoot(miss ? npc.gameObject : npc.CurrentAIPlayerTarget.GameObject, hitbox, npc.NPCPlayer.CameraTransform.forward, npc.NPCPlayer.Position, npc.CurrentAIPlayerTarget.Position);

                    bool end = !npc.CurrentAIPlayerTarget.IsAlive;

                    if (use_ammo)
                    {
                        npc.AvailableWeapons[npc.ItemHeld]--;
                        if (npc.AvailableWeapons[npc.ItemHeld] <= 0)
                        {
                            npc.NPCPlayer.ReferenceHub.weaponManager.RpcReload(npc.NPCPlayer.ReferenceHub.weaponManager.curWeapon);
                            npc.AvailableWeapons[npc.ItemHeld] = (int)npc.NPCPlayer.ReferenceHub.weaponManager.weapons[npc.NPCPlayer.ReferenceHub.weaponManager.curWeapon].maxAmmo;
                            if (end)
                            {
                                npc.FireEvent(new Events.NPCTargetKilledEvent(npc, npc.CurrentAIPlayerTarget));
                                IsFinished = true;
                            }
                            return(npc.NPCPlayer.ReferenceHub.weaponManager.weapons[npc.NPCPlayer.ReferenceHub.weaponManager.curWeapon].reloadingTime);
                        }
                    }


                    if (end)
                    {
                        npc.FireEvent(new Events.NPCTargetKilledEvent(npc, npc.CurrentAIPlayerTarget));
                        IsFinished = true;
                        return(0f);
                    }
                }
                else
                {
                    IsFinished = true;
                    return(0f);
                }
                return(firerate * Plugin.Instance.Config.NpcFireCooldownMultiplier * npc.NPCPlayer.ReferenceHub.weaponManager._fireCooldown);
            }
            else
            {
                float cd = 0f;
                npc.OnTargetLostBehaviour = Npc.TargetLostBehaviour.STOP;
                npc.Follow(npc.CurrentAIPlayerTarget);
                if (Vector3.Distance(npc.CurrentAIPlayerTarget.Position, npc.NPCPlayer.Position) <= 1.5f)
                {
                    if (npc.NPCPlayer.Role.Is939())
                    {
                        npc.NPCPlayer.GameObject.GetComponent <Scp939PlayerScript>().CallCmdShoot(npc.CurrentAIPlayerTarget.GameObject);
                    }
                    else
                    {
                        switch (npc.NPCPlayer.Role)
                        {
                        case RoleType.Scp106:
                            npc.NPCPlayer.GameObject.GetComponent <Scp106PlayerScript>().CallCmdMovePlayer(npc.CurrentAIPlayerTarget.GameObject, ServerTime.time);
                            cd = 2f;
                            break;

                        case RoleType.Scp173:
                            npc.NPCPlayer.GameObject.GetComponent <Scp173PlayerScript>().CallCmdHurtPlayer(npc.CurrentAIPlayerTarget.GameObject);
                            break;

                        case RoleType.Scp049:
                            npc.CurrentAIPlayerTarget.Hurt(99999f, DamageTypes.Scp049, npc.NPCPlayer.Nickname);
                            cd = PlayableScps.Scp049.KillCooldown;
                            break;

                        case RoleType.Scp0492:
                            npc.NPCPlayer.GameObject.GetComponent <Scp049_2PlayerScript>().CallCmdShootAnim();
                            npc.NPCPlayer.GameObject.GetComponent <Scp049_2PlayerScript>().CallCmdHurtPlayer(npc.CurrentAIPlayerTarget.GameObject);
                            cd = 1f;
                            break;

                        case RoleType.Scp096:
                            npc.CurrentAIPlayerTarget.Hurt(99999f, DamageTypes.Scp096, npc.NPCPlayer.Nickname, npc.NPCPlayer.Id);
                            break;
                        }
                    }
                    if (!npc.CurrentAIPlayerTarget.IsAlive)
                    {
                        npc.AttachedCoroutines.Add(MEC.Timing.CallDelayed(0.1f, () =>
                        {
                            npc.FireEvent(new Events.NPCTargetKilledEvent(npc, npc.CurrentAIPlayerTarget));
                        }));

                        npc.Stop();

                        Player target = npc.CurrentAIPlayerTarget;

                        npc.CurrentAIPlayerTarget = null;

                        if (npc.ProcessSCPLogic && npc.NPCPlayer.Role == RoleType.Scp049)
                        {
                            npc.AttachedCoroutines.Add(Timing.RunCoroutine(ReviveCoroutine(npc, target)));
                            IsFinished = true;
                            return(PlayableScps.Scp049.TimeToRevive + 0.5f);
                        }
                    }
                }
                return(cd);
            }
        }
Esempio n. 13
0
        private IEnumerator <float> ShootCoroutine(Npc npc, Player p, HitBoxType hitbox, int amount)
        {
            for (int i = 0; i < amount; i++)
            {
                if (!npc.NPCPlayer.ReferenceHub.characterClassManager.IsAnyScp())
                {
                    if (npc.AvailableWeapons.Count > 0)
                    {
                        if (!npc.ItemHeld.IsWeapon(false))
                        {
                            npc.ItemHeld = npc.AvailableWeapons.Keys.ElementAt(0);
                        }
                        npc.Stop();
                        Vector3    heading = (p.Position - npc.NPCPlayer.Position);
                        Quaternion lookRot = Quaternion.LookRotation(heading.normalized);
                        npc.NPCPlayer.Rotations = new Vector2(lookRot.eulerAngles.x, lookRot.eulerAngles.y);
                        npc.NPCPlayer.ReferenceHub.weaponManager.CallCmdShoot(p.GameObject, hitbox, npc.NPCPlayer.CameraTransform.forward, npc.NPCPlayer.Position, p.Position);
                    }
                    yield return(Timing.WaitForSeconds(Plugin.Instance.Config.NpcFireCooldownMultiplier * npc.NPCPlayer.ReferenceHub.weaponManager._fireCooldown));
                }
                else
                {
                    float cd = 0f;
                    npc.Follow(p);
                    if (Vector3.Distance(p.Position, npc.NPCPlayer.Position) <= 1.5f)
                    {
                        if (npc.NPCPlayer.Role.Is939())
                        {
                            npc.NPCPlayer.GameObject.GetComponent <Scp939PlayerScript>().CallCmdShoot(p.GameObject);
                        }
                        else
                        {
                            switch (npc.NPCPlayer.Role)
                            {
                            case RoleType.Scp106:
                                npc.NPCPlayer.GameObject.GetComponent <Scp106PlayerScript>().CallCmdMovePlayer(p.GameObject, ServerTime.time);
                                cd = 2f;
                                break;

                            case RoleType.Scp173:
                                npc.NPCPlayer.GameObject.GetComponent <Scp173PlayerScript>().CallCmdHurtPlayer(p.GameObject);
                                break;

                            case RoleType.Scp049:
                                p.Hurt(99999f, DamageTypes.Scp049, npc.NPCPlayer.Nickname);
                                cd = PlayableScps.Scp049.KillCooldown;
                                break;

                            case RoleType.Scp0492:
                                npc.NPCPlayer.GameObject.GetComponent <Scp049_2PlayerScript>().CallCmdShootAnim();
                                npc.NPCPlayer.GameObject.GetComponent <Scp049_2PlayerScript>().CallCmdHurtPlayer(p.GameObject);
                                cd = 1f;
                                break;
                            }
                        }
                        npc.Stop();
                    }
                    yield return(Timing.WaitForSeconds(cd));
                }
            }
        }