Иконка ресурса

FREE SoccerWeapons : 11.4.0 11.4.0

Нет прав для скачивания
C#:
using System.Collections.Generic;
using UnityEngine;
using Rust;

namespace Oxide.Plugins
{
    [Info("SoccerWeapons", "Jess", "11.4.0")]
    [Description("MGL=Heal, Snowball=Magnet, Nailgun=YellowCard (Fixed), Bat=HomeRun, NVG=ESP")]
    public class SoccerWeapons : RustPlugin
    {
        // ==========================================================================
        // CONFIGURATION
        // ==========================================================================
        
        // WEAPONS
        private const string Medi_GunShortname = "multiplegrenadelauncher";
        private const string Medi_ItemToDrop = "largemedkit";
        private const float Medi_SpeedMultiplier = 0.5f;

        private const string Magnet_GunShortname = "snowballgun"; 
        private const string Magnet_ItemToDrop = "snowball"; 
        private const float Magnet_Speed = 60f; 

        private const string Tackle_GunShortname = "nailgun";
        private const float Tackle_Duration = 3.0f; 

        private const string Phase_GunShortname = "pistol.python";
        private const string Whistle_GunShortname = "crossbow";
        private const float Whistle_FreezeTime = 2.0f;

        private const string Bat_Shortname = "mace.baseballbat";
        private const float Bat_HitForce = 45f; 
        private const float Bat_ChargeTime = 2.0f; 

        // ESP
        private const string Esp_Shortname = "nightvisiongoggles";
        private const float Esp_Radius = 150f;
        private const float Esp_RefreshRate = 0.1f; 

        // ASSETS
        private const string FX_Explosion = "assets/prefabs/tools/c4/effects/c4_explosion.prefab";
        private const string FX_Magic = "assets/bundled/prefabs/fx/gestures/magic_glimmer_1.prefab";
        private const string FX_PhantomSmoke = "assets/bundled/prefabs/fx/smoke_rocket_explosion.prefab"; 

        // ==========================================================================
        // INITIALIZATION
        // ==========================================================================
        
        void OnServerInitialized()
        {
            timer.Every(Esp_RefreshRate, () => RunESPLoop());
        }

        // ==========================================================================
        // ADVANCED ESP LOGIC
        // ==========================================================================
        
        void RunESPLoop()
        {
            Color rainbow = Color.HSVToRGB((Time.time * 0.5f) % 1.0f, 1f, 1f);
            float duration = Esp_RefreshRate + 0.02f;

            foreach (var player in BasePlayer.activePlayerList)
            {
                if (player == null || !player.IsConnected || player.IsSleeping()) continue;
                if (player.inventory == null || player.inventory.containerWear == null) continue;

                bool hasGoggles = false;
                foreach (var item in player.inventory.containerWear.itemList)
                {
                    if (item.info.shortname == Esp_Shortname) { hasGoggles = true; break; }
                }

                if (hasGoggles) DrawUltimateESP(player, rainbow, duration);
            }
        }

        void DrawUltimateESP(BasePlayer observer, Color color, float duration)
        {
            List<BasePlayer> nearby = new List<BasePlayer>();
            Vis.Entities(observer.transform.position, Esp_Radius, nearby);

            foreach (var target in nearby)
            {
                if (target == observer || target.IsDead() || target.IsSleeping()) continue;

                Color c = target.IsNpc ? Color.yellow : color;

                // TALL BOX
                DrawPlayerBox(observer, target, c, duration);

                // SKELETON
                DrawBoneLine(observer, target, "head", "neck", c, duration);
                DrawBoneLine(observer, target, "neck", "spine3", c, duration);
                DrawBoneLine(observer, target, "spine3", "spine1", c, duration);
                DrawBoneLine(observer, target, "spine1", "pelvis", c, duration);
                // Arms
                DrawBoneLine(observer, target, "neck", "l_upperarm", c, duration);
                DrawBoneLine(observer, target, "l_upperarm", "l_forearm", c, duration);
                DrawBoneLine(observer, target, "l_forearm", "l_hand", c, duration);
                DrawBoneLine(observer, target, "neck", "r_upperarm", c, duration);
                DrawBoneLine(observer, target, "r_upperarm", "r_forearm", c, duration);
                DrawBoneLine(observer, target, "r_forearm", "r_hand", c, duration);
                // Legs
                DrawBoneLine(observer, target, "pelvis", "l_hip", c, duration);
                DrawBoneLine(observer, target, "l_hip", "l_knee", c, duration);
                DrawBoneLine(observer, target, "l_knee", "l_foot", c, duration);
                DrawBoneLine(observer, target, "pelvis", "r_hip", c, duration);
                DrawBoneLine(observer, target, "r_hip", "r_knee", c, duration);
                DrawBoneLine(observer, target, "r_knee", "r_foot", c, duration);

                // NAME TAG
                Vector3 headPos = target.eyes.position;
                string dist = $"{(int)Vector3.Distance(observer.transform.position, target.transform.position)}m";
                observer.SendConsoleCommand("ddraw.text", duration, Color.white, headPos + new Vector3(0, 0.4f, 0), $"{target.displayName} [{dist}]");
            }
        }

        void DrawBoneLine(BasePlayer observer, BasePlayer target, string b1, string b2, Color c, float d)
        {
            var bone1 = target.FindBone(b1);
            var bone2 = target.FindBone(b2);
            if (bone1 != null && bone2 != null)
                observer.SendConsoleCommand("ddraw.line", d, c, bone1.position, bone2.position);
        }

        void DrawPlayerBox(BasePlayer observer, BasePlayer target, Color c, float d)
        {
            Vector3 pos = target.transform.position;
            float w = 0.4f; float h = 1.9f;
            Vector3 b1 = pos + new Vector3(w, 0, w); Vector3 b2 = pos + new Vector3(-w, 0, w);
            Vector3 b3 = pos + new Vector3(-w, 0, -w); Vector3 b4 = pos + new Vector3(w, 0, -w);
            Vector3 t1 = b1 + new Vector3(0, h, 0); Vector3 t2 = b2 + new Vector3(0, h, 0);
            Vector3 t3 = b3 + new Vector3(0, h, 0); Vector3 t4 = b4 + new Vector3(0, h, 0);

            observer.SendConsoleCommand("ddraw.line", d, c, b1, b2); observer.SendConsoleCommand("ddraw.line", d, c, b2, b3);
            observer.SendConsoleCommand("ddraw.line", d, c, b3, b4); observer.SendConsoleCommand("ddraw.line", d, c, b4, b1);
            observer.SendConsoleCommand("ddraw.line", d, c, t1, t2); observer.SendConsoleCommand("ddraw.line", d, c, t2, t3);
            observer.SendConsoleCommand("ddraw.line", d, c, t3, t4); observer.SendConsoleCommand("ddraw.line", d, c, t4, t1);
            observer.SendConsoleCommand("ddraw.line", d, c, b1, t1); observer.SendConsoleCommand("ddraw.line", d, c, b2, t2);
            observer.SendConsoleCommand("ddraw.line", d, c, b3, t3); observer.SendConsoleCommand("ddraw.line", d, c, b4, t4);
        }

        // ==========================================================================
        // DEBUG COMMAND: "/hitme"
        // ==========================================================================
        [ChatCommand("hitme")]
        void CmdHitMe(BasePlayer player, string command, string[] args)
        {
            string targetPath = "assets/content/vehicles/ball/ball.item.prefab";
            ItemDefinition ballDef = null;
            foreach (var def in ItemManager.itemList) {
                if (def.worldModelPrefab != null && def.worldModelPrefab.isValid && def.worldModelPrefab.resourcePath == targetPath) {
                    ballDef = def; break;
                }
            }
            if (ballDef == null) { player.ChatMessage("Error: Ball item definition not found."); return; }

            Item item = ItemManager.CreateByItemID(ballDef.itemid, 1);
            if (item == null) return;

            Vector3 spawnPos = player.transform.position + (player.eyes.BodyForward() * 10f);
            spawnPos.y += 2.0f; 

            BaseEntity ball = item.Drop(spawnPos, Vector3.zero);
            if (ball == null) return;

            Rigidbody rb = ball.GetComponent<Rigidbody>();
            if (rb != null) {
                rb.isKinematic = false;
                rb.WakeUp();
                Vector3 direction = (player.eyes.position - spawnPos).normalized;
                rb.velocity = direction * 40f; 
            }

            ChargedBall script = ball.gameObject.AddComponent<ChargedBall>();
            script.Shooter = null; 
            script.LifeTime = 5.0f;
            script.Activate();
            player.ChatMessage("INCOMING!");
        }

        // ==========================================================================
        // HOOKS
        // ==========================================================================

        void OnWeaponFired(BaseProjectile projectile, BasePlayer player, ItemModProjectile mod, ProtoBuf.ProjectileShoot projectiles)
        {
            if (projectile == null || player == null) return;
            Item heldItem = player.GetActiveItem();
            if (heldItem == null) return;
            string weaponName = heldItem.info.shortname;

            if (weaponName == Magnet_GunShortname)
            {
                Vector3 spawnPos = player.eyes.position + (player.eyes.BodyForward() * 1.5f);
                Vector3 velocity = player.eyes.BodyForward() * Magnet_Speed;
                SpawnProjectile(spawnPos, velocity, player, Magnet_ItemToDrop, false);
            }
            else if (weaponName == Tackle_GunShortname) ShootYellowCard(player);
            else if (weaponName == Phase_GunShortname) ShootPhaseShift(player);
            else if (weaponName == Whistle_GunShortname) ShootWhistle(player);
        }

        void OnMeleeAttack(BasePlayer player, HitInfo info)
        {
            if (player == null || info == null || info.HitEntity == null) return;
            Item held = player.GetActiveItem();
            if (held == null || held.info.shortname != Bat_Shortname) return;

            if (info.HitEntity.ShortPrefabName.Contains("ball")) HandleBaseballHit_Ball(player, info.HitEntity);
            else if (info.HitEntity is BasePlayer) Effect.server.Run(FX_Explosion, info.HitEntity.transform.position);
        }

        void OnEntitySpawned(BaseNetworkable entity)
        {
            if (entity == null) return;
            BaseEntity baseEntity = entity as BaseEntity;
            if (baseEntity == null || baseEntity.ShortPrefabName == null) return;
            if (baseEntity is TimedExplosive && baseEntity.ShortPrefabName.Contains("40mm")) HandleMGL(baseEntity as TimedExplosive);
        }

        // ==========================================================================
        // LOGIC: GUNS & TOOLS
        // ==========================================================================
        
        void HandleBaseballHit_Ball(BasePlayer player, BaseEntity ball)
        {
            Rigidbody rb = ball.GetComponent<Rigidbody>();
            if (rb == null) return;
            if (rb.isKinematic) rb.isKinematic = false;
            rb.WakeUp();

            Vector3 direction = player.eyes.BodyForward(); 
            direction += Vector3.up * 0.25f; 
            rb.velocity = Vector3.zero; 
            rb.AddForce(direction.normalized * Bat_HitForce, ForceMode.VelocityChange); 

            ChargedBall script = ball.GetComponent<ChargedBall>();
            if (script == null) script = ball.gameObject.AddComponent<ChargedBall>();
            script.Shooter = player;
            script.LifeTime = Bat_ChargeTime;
            script.Activate();

            Effect.server.Run("assets/bundled/prefabs/fx/impacts/blunt/metal_hit_metal.prefab", ball.transform.position);
            player.ChatMessage("<color=#ff0000>HOME RUN!</color>");
        }

        void HandleMGL(TimedExplosive explosive)
        {
            BasePlayer shooter = explosive.creatorEntity as BasePlayer;
            if (shooter == null) return;
            Item activeItem = shooter.GetActiveItem();
            if (activeItem?.info?.shortname != Medi_GunShortname) return;
            Vector3 startPos = explosive.transform.position;
            Vector3 velocity = Vector3.zero;
            Rigidbody rb = explosive.GetComponent<Rigidbody>();
            if (rb != null) velocity = rb.velocity;
            else if (shooter.eyes != null) velocity = shooter.eyes.BodyForward() * 50f;
            velocity = velocity * Medi_SpeedMultiplier;
            explosive.Kill();
            SpawnProjectile(startPos, velocity, shooter, Medi_ItemToDrop, true);
        }

        // --- FIXED: Yellow Card now uses a Layer Mask to hit ONLY players ---
        void ShootYellowCard(BasePlayer player)
        {
            RaycastHit hit;
            // The mask "Player (Server)" ensures we ignore ground, walls, and invisible barriers
            int layerMask = LayerMask.GetMask("Player (Server)");

            // 0.5m thick beam, 100m range
            if (!Physics.SphereCast(player.eyes.position, 0.5f, player.eyes.BodyForward(), out hit, 100f, layerMask)) 
            {
                return;
            }

            BaseEntity hitEntity = hit.GetEntity();
            if (hitEntity == null) return;

            BasePlayer target = hitEntity as BasePlayer;
            if (target != null && !target.IsWounded() && !target.IsSleeping())
            {
                HitInfo info = new HitInfo();
                info.Initiator = player;
                info.WeaponPrefab = player.GetHeldEntity();
                info.damageTypes = new DamageTypeList();
                info.damageTypes.Add(DamageType.Generic, 0f); 
                
                target.BecomeWounded(info);
                
                player.ChatMessage($"<color=#ffff00>YELLOW CARD!</color> You tackled {target.displayName}.");
                target.ChatMessage($"<color=#ffff00>YELLOW CARD!</color> You have been tackled for {Tackle_Duration}s!");

                timer.Once(Tackle_Duration, () => {
                    if (target != null && target.IsWounded()) { target.StopWounded(); target.Heal(10f); target.ChatMessage("<color=#00ff00>PLAY ON!</color>"); }
                });
            }
        }

        void ShootPhaseShift(BasePlayer player)
        {
            RaycastHit hit;
            if (!Physics.Raycast(player.eyes.HeadRay(), out hit, 100f)) return;
            BaseEntity hitEntity = hit.GetEntity();
            if (hitEntity != null && hitEntity.ShortPrefabName.Contains("ball"))
            {
                Vector3 playerPos = player.transform.position;
                Vector3 ballPos = hitEntity.transform.position;
                Effect.server.Run(FX_Magic, playerPos);
                Effect.server.Run(FX_Magic, ballPos);
                player.Teleport(ballPos + new Vector3(0, 0.5f, 0));
                hitEntity.transform.position = playerPos + new Vector3(0, 1.0f, 0);
                Rigidbody ballRb = hitEntity.GetComponent<Rigidbody>();
                if (ballRb != null) { ballRb.velocity = Vector3.zero; ballRb.WakeUp(); }
                hitEntity.SendNetworkUpdateImmediate();
                player.ChatMessage("<color=#00ffff>PHASE SHIFT!</color>");
            }
        }

        void ShootWhistle(BasePlayer player)
        {
            RaycastHit hit;
            if (!Physics.Raycast(player.eyes.HeadRay(), out hit, 100f)) return;
            BaseEntity hitEntity = hit.GetEntity();
            if (hitEntity != null && hitEntity.ShortPrefabName.Contains("ball"))
            {
                Rigidbody ballRb = hitEntity.GetComponent<Rigidbody>();
                if (ballRb != null)
                {
                    ballRb.isKinematic = true;
                    Effect.server.Run(FX_Explosion, hitEntity.transform.position);
                    player.ChatMessage($"<color=#ff0000>WHISTLE!</color> Ball frozen for {Whistle_FreezeTime}s.");
                    timer.Once(Whistle_FreezeTime, () => {
                        if (ballRb != null) { ballRb.isKinematic = false; ballRb.WakeUp(); Effect.server.Run(FX_Explosion, hitEntity.transform.position); }
                    });
                }
            }
        }

        // ==========================================================================
        // CUSTOM SCRIPTS
        // ==========================================================================

        public class ChargedBall : MonoBehaviour
        {
            public BasePlayer Shooter;
            public float LifeTime;
            private float _stopTime;
            private float _nextEffectTime;
            private const string FX_Smoke = "assets/bundled/prefabs/fx/smoke/fog_1.prefab";
            private const string FX_Explosion = "assets/prefabs/tools/c4/effects/c4_explosion.prefab";
            public void Activate() { _stopTime = Time.time + LifeTime; }
            void FixedUpdate() {
                if (Time.time > _stopTime) { Destroy(this); return; }
                if (Time.time > _nextEffectTime) { Effect.server.Run(FX_Smoke, transform.position); _nextEffectTime = Time.time + 0.1f; }
            }
            void OnCollisionEnter(Collision col) {
                BasePlayer target = col.gameObject.GetComponentInParent<BasePlayer>();
                if (target != null) {
                    if (Shooter != null && target == Shooter) return;
                    Effect.server.Run(FX_Explosion, transform.position);
                    Destroy(this);
                }
            }
        }

        public class MediProjectile : MonoBehaviour
        {
            public BasePlayer Shooter;
            private BaseEntity _entity;
            private bool _hasHit = false;
            private float _spawnTime;
            private Vector3 _lastPosition;
            private const string HealEffect = "assets/bundled/prefabs/fx/build/promote_toptier.prefab"; 
            private const string HealSound = "assets/bundled/prefabs/fx/impacts/bloodreplacement/fleshbloodimpact_blunt_white.prefab";
            private int _playerMask;
            void Awake() { _entity = GetComponent<BaseEntity>(); _spawnTime = Time.time; _lastPosition = transform.position; _playerMask = LayerMask.GetMask("Player (Server)"); Invoke("DestroySelf", 10f); }
            void FixedUpdate() {
                if (_hasHit || _entity == null) return;
                Vector3 currentPos = transform.position;
                Vector3 direction = currentPos - _lastPosition;
                float distance = direction.magnitude;
                if (distance > 0) {
                    RaycastHit hit;
                    if (Physics.SphereCast(_lastPosition, 0.5f, direction.normalized, out hit, distance, _playerMask)) {
                         if (Time.time > _spawnTime + 0.2f) {
                             BaseEntity hitEntity = hit.GetEntity();
                             if (hitEntity == Shooter && Time.time < _spawnTime + 1.0f) {} 
                             else if (hitEntity is BasePlayer) { TriggerHit(hitEntity as BasePlayer); return; }
                         }
                    }
                }
                _lastPosition = currentPos;
            }
            void OnCollisionEnter(Collision collision) { if (Time.time < _spawnTime + 0.2f) return; if (_hasHit || _entity == null) return; TriggerHit(null); }
            void TriggerHit(BasePlayer target) {
                _hasHit = true;
                Effect.server.Run(HealEffect, transform.position, Vector3.up);
                Effect.server.Run(HealSound, transform.position, Vector3.up);
                if (target != null) { target.Heal(50f); target.metabolism.hydration.value += 20; if(Shooter != null && Shooter != target) Shooter.ChatMessage($"<color=#00ff00>Healed {target.displayName}!</color>"); }
                DestroySelf();
            }
            void DestroySelf() { if (_entity != null && !_entity.IsDestroyed) _entity.Kill(); else Destroy(gameObject); }
        }

        public class MagnetProjectile : MonoBehaviour
        {
            public BasePlayer Shooter;
            private BaseEntity _entity;
            private bool _hasHit = false;
            private const string ImpactEffect = "assets/prefabs/tools/c4/effects/c4_explosion.prefab";
            void Awake() { _entity = GetComponent<BaseEntity>(); Invoke("DestroySelf", 5f); }
            void OnCollisionEnter(Collision collision) {
                if (_hasHit || _entity == null) return;
                BaseEntity hitEntity = collision.gameObject.GetComponentInParent<BaseEntity>();
                if (hitEntity != null && Shooter != null && hitEntity == Shooter) return;
                _hasHit = true;
                PerformVacuum(transform.position);
                Effect.server.Run(ImpactEffect, transform.position);
                DestroySelf();
            }
            void PerformVacuum(Vector3 centerPoint) {
                List<BaseEntity> nearbyEntities = new List<BaseEntity>();
                Vis.Entities(centerPoint, 25f, nearbyEntities); 
                foreach (var entity in nearbyEntities) {
                    if (!entity.ShortPrefabName.Contains("ball")) continue;
                    if (entity is BasePlayer) continue;
                    Rigidbody rb = entity.GetComponent<Rigidbody>();
                    if (rb == null) continue;
                    if (rb.IsSleeping()) rb.WakeUp();
                    Vector3 directionToCenter = centerPoint - entity.transform.position;
                    Vector3 forceVector = directionToCenter.normalized * 50f; 
                    forceVector += Vector3.up * 8.0f; 
                    rb.velocity = Vector3.zero; 
                    rb.angularVelocity = Vector3.zero;
                    rb.AddForce(forceVector, ForceMode.VelocityChange);
                }
            }
            void DestroySelf() { if (_entity != null && !_entity.IsDestroyed) _entity.Kill(); else Destroy(gameObject); }
        }

        void SpawnProjectile(Vector3 pos, Vector3 vel, BasePlayer shooter, string itemName, bool isMedi)
        {
            Item item = ItemManager.CreateByName(itemName, 1);
            if (item == null) return;
            BaseEntity droppedEntity = item.Drop(pos, vel);
            if (droppedEntity == null) return;
            DroppedItem dropScript = droppedEntity.GetComponent<DroppedItem>();
            if (dropScript != null) dropScript.allowPickup = false;
            Rigidbody rb = droppedEntity.GetComponent<Rigidbody>();
            if (rb != null) {
                rb.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic;
                if (isMedi) { rb.drag = 0.5f; rb.useGravity = true; }
                else { rb.drag = 0.0f; rb.useGravity = false; }
            }
            if (isMedi) { MediProjectile script = droppedEntity.gameObject.AddComponent<MediProjectile>(); script.Shooter = shooter; } 
            else { MagnetProjectile script = droppedEntity.gameObject.AddComponent<MagnetProjectile>(); script.Shooter = shooter; }
        }
    }
}

Автор
15FPS
Скачиваний
0
Просмотры
1
Первый выпуск
Обновление
Оценка
0.00 звёзд 0 оценок
Сверху