Respan Dataset Explorer

Select one behavior. Every returned turn has one binary label: Present or Absent. Source: final dense boolean release.

5,167,182physical rows
86shards
0.00%qualified row coverage
0.00%qualified cell coverage
Random row JSON API

turns-00083.parquet:31597

b3691b3a8e631e3d0abde04e
turn 3/19gpt-4.1-mini-2025-04-14EnglishCroatia463 words
degenerate_repetitionAbsentFinal dense release
USER
show the whole script
ASSISTANT
Certainly! Here's a complete example script that manages a weapon pickup in Unity, ensuring that **only one instance of the pickup prefab is spawned and reused**, toggling its active state instead of creating new clones every time. This example also includes simple respawn logic for demonstration.

---

### Example Script: `Kit_WeaponPickupRespawnManager.cs`

```csharp
using UnityEngine;
using System.Collections;

public class Kit_WeaponPickupRespawnManager : MonoBehaviour
{
    [Tooltip("Weapon pickup prefab assigned in inspector")]
    public GameObject weaponPickupPrefab;

    // The single instance of the pickup in the scene
    private GameObject weaponPickupInstance;

    // Respawn delay in seconds
    public float respawnDelay = 10f;

    private void Start()
    {
        SpawnPickup();
    }

    /// <summary>
    /// Instantiates pickup only once and enables it.
    /// </summary>
    public void SpawnPickup()
    {
        if (weaponPickupInstance == null)
        {
            weaponPickupInstance = Instantiate(weaponPickupPrefab);
            // Optional: Set parent, reset position, etc. here
            weaponPickupInstance.transform.SetParent(transform);
            weaponPickupInstance.transform.localPosition = Vector3.zero;
            weaponPickupInstance.SetActive(true);
        }
        else
        {
            // Pickup already exists, just enable it
            weaponPickupInstance.SetActive(true);
        }
    }

    /// <summary>
    /// Call this when weapon pickup is taken by player.
    /// Will deactivate the pickup and start respawn timer.
    /// </summary>
    public void PickupTaken()
    {
        if (weaponPickupInstance != null)
        {
            weaponPickupInstance.SetActive(false);
            StartCoroutine(RespawnCoroutine());
        }
    }

    private IEnumerator RespawnCoroutine()
    {
        yield return new WaitForSeconds(respawnDelay);
        SpawnPickup();
    }
}
```

---

### How to use this in your project:

1. **Assign your weapon pickup prefab** to the `weaponPickupPrefab` field in the inspector.
2. The script will instantiate the pickup once in `Start()`.
3. When the pickup is taken by a player, call `PickupTaken()`.
4. The manager will **deactivate the single instance**, wait for `respawnDelay` seconds, then enable it again.
5. No additional clones will be created beyond the initial instantiation.

---

### Optional: Connecting Pickup Interaction

If your pickup prefab has a collider that detects player entry and calls this, you can add a small script to the pickup prefab to notify the Manager:

```csharp
public class Kit_WeaponPickup : MonoBehaviour
{
    private Kit_WeaponPickupRespawnManager respawnManager;

    private void Start()
    {
        // Cache reference to manager in parent (or assign manually)
        respawnManager = GetComponentInParent<Kit_WeaponPickupRespawnManager>();
    }

    private void OnTriggerEnter(Collider other)
    {
        // Example: Check for player tag or component
        if (other.CompareTag("Player"))
        {
            // Give weapon to player here (your existing logic)

            // Notify respawn manager to hide pickup and start respawn
            respawnManager.PickupTaken();
        }
    }
}
```

---

### Important Notes:

- This example assumes a **single pickup instance** per manager.
- You can extend this pattern to pool multiple pickups if needed.
- If you use Mirror Networking, spawn the pickup once on the server with `NetworkServer.Spawn`, and use commands/RPCs instead of direct `SetActive` on clients.
- Ensure **only instances are activated/deactivated, never the prefab asset**.

---

If you want me to help modify your current `Kit_WeaponPickup.cs` and `Kit_WeaponPickupRespawnManager.cs` files, just provide their current content, and I can tailor the solution to your existing code!

turns-00083.parquet:31598

28002089f9de4a6703b0c783
turn 4/19gpt-4.1-mini-2025-04-14EnglishCroatia506 words
degenerate_repetitionAbsentFinal dense release
USER
show also the corrected WeaponPickup script
ASSISTANT
Certainly! Below is a complete example of a **corrected `Kit_WeaponPickup.cs`** script that works together with the respawn manager I showed previously.

This script **does not instantiate clones** directly; it assumes there is exactly one pickup instance managed by `Kit_WeaponPickupRespawnManager`. When a player collides with the pickup, it attempts to give the weapon to the player, then tells the manager to hide and respawn the pickup later.

---

### Example Script: `Kit_WeaponPickup.cs`

```csharp
using UnityEngine;

// This script is attached to the weapon pickup instance (the prefab instance in scene)
public class Kit_WeaponPickup : MonoBehaviour
{
    private Kit_WeaponPickupRespawnManager respawnManager;

    private void Start()
    {
        // Find the respawn manager in parent hierarchy for callback
        respawnManager = GetComponentInParent<Kit_WeaponPickupRespawnManager>();

        if (respawnManager == null)
        {
            Debug.LogError("Kit_WeaponPickupRespawnManager not found in parent hierarchy.");
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        // Example: Check if the collider belongs to a player
        if (other.CompareTag("Player"))
        {
            var player = other.GetComponent<MarsFPSKit.Kit_PlayerBehaviour>();
            if (player != null)
            {
                // Try to give/refill weapon to player
                bool success = TryGiveOrRefillWeapon(player);

                if (success)
                {
                    Debug.Log("[Kit_WeaponPickup] Player picked up weapon.");

                    // Notify respawn manager that pickup was taken
                    respawnManager.PickupTaken();
                }
                else
                {
                    Debug.LogWarning("[Kit_WeaponPickup] Player already has weapon or pickup failed.");
                }
            }
        }
    }

    /// <summary>
    /// Sample method that tries to give or refill the weapon to the player.
    /// Modify this function based on your weapon/weapon manager logic.
    /// Returns true if successful.
    /// </summary>
    private bool TryGiveOrRefillWeapon(MarsFPSKit.Kit_PlayerBehaviour player)
    {
        if (player == null)
        {
            return false;
        }

        // Example weapon ID - adjust to fit your setup
        int weaponID = 1;

        // Replace with your actual Kit_ModernWeaponManager usage
        var weaponManager = player.GetComponent<MarsFPSKit.Weapons.Kit_ModernWeaponManager>();
        if (weaponManager == null)
        {
            Debug.LogWarning("[Kit_WeaponPickup] No Kit_ModernWeaponManager on player.");
            return false;
        }

        // Check if the player already has the weapon, refill or give if not.
        if (weaponManager.HasWeapon(weaponID))
        {
            // For example, refill ammo if already have weapon
            weaponManager.RefillWeapon(weaponID);
            return true;
        }
        else
        {
            // Give weapon to player
            bool added = weaponManager.TryGiveWeapon(weaponID);
            return added;
        }
    }
}
```

---

### How this works together with `Kit_WeaponPickupRespawnManager`:

- The **single weapon pickup instance prefab** stays in scene (spawned once by the respawn manager).
- When a player collides with the pickup collider, the pickup tries to give/refill the weapon.
- If successful, it calls the respawn manager's `PickupTaken()` to:
  - Deactivate the pickup instance.
  - Start the respawn coroutine to enable it again after a delay.
- No new clones are created.
- Your weapon logic is called via the weapon manager on player objects.

---

### Notes / Adjustments:

- Replace `"Player"` tag with your actual player tag (if different).
- Modify `TryGiveOrRefillWeapon()` based on your game's weapon manager API.
- Ensure `Kit_WeaponPickupRespawnManager` is parent of your pickup instance or assign `respawnManager` reference directly if your hierarchy differs.
- Ensure colliders on pickup prefab have `IsTrigger` enabled.
- For Mirror Networking use, add proper server-side authority and spawn logic.

---

If you want, provide me your existing scripts, and I can assist in adapting these further for your setup!

turns-00083.parquet:31599

a3537ad587d9156ded71c981
turn 5/19gpt-4.1-mini-2025-04-14EnglishCroatia552 words
degenerate_repetitionAbsentFinal dense release
USER
show the full script, do not remove other parts everything should be compatible with mmfpse
ASSISTANT
Certainly! Below is a **full compatible version** of `Kit_WeaponPickup.cs` tailored specifically to be consistent with the MarsFPSKit (MMFPSE) framework based on the logs and typical structure you have, without removing existing functionality you may have, but updating it so it does **NOT instantiate clones repeatedly** and works well with the respawn manager pattern.

---

### Full Compatible `Kit_WeaponPickup.cs` Script

```csharp
using UnityEngine;
using MarsFPSKit;
using MarsFPSKit.Weapons;

public class Kit_WeaponPickup : MonoBehaviour
{
    // Presume you have some weapon ID configured for this pickup
    public int weaponID = 1;

    // Reference to respawn manager, assign in inspector or found in hierarchy
    private Kit_WeaponPickupRespawnManager respawnManager;

    private void Start()
    {
        // Try to find the respawn manager in parent hierarchy if not assigned
        if (respawnManager == null)
        {
            respawnManager = GetComponentInParent<Kit_WeaponPickupRespawnManager>();
        }

        if (respawnManager == null)
        {
            Debug.LogWarning("[Kit_WeaponPickup] No Kit_WeaponPickupRespawnManager found in parents.");
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        // Only trigger on players
        if (!other.CompareTag("Player")) return;

        Kit_PlayerBehaviour player = other.GetComponent<Kit_PlayerBehaviour>();

        if (player == null) return;

        // Attempt to give or refill the weapon
        if (TryGiveOrRefillWeapon(player))
        {
            Debug.Log($"[Kit_WeaponPickup] Player {player.nickname} picked up weapon ID {weaponID}");

            // Notify the respawn manager to deactivate and schedule respawn
            if (respawnManager != null)
            {
                respawnManager.PickupTaken();
            }
            else
            {
                Debug.LogWarning("[Kit_WeaponPickup] Cannot notify respawn manager - it's null");
            }
        }
        else
        {
            Debug.LogWarning($"[Kit_WeaponPickup] Player {player.nickname} already has weapon or failed to pick up weapon ID {weaponID}");
        }
    }

    /// <summary>
    /// Gives the weapon or refills ammo if already owned.
    /// </summary>
    private bool TryGiveOrRefillWeapon(Kit_PlayerBehaviour player)
    {
        if (player == null) return false;

        Kit_ModernWeaponManager wpnManager = player.weaponManager as Kit_ModernWeaponManager;

        if (wpnManager == null)
        {
            Debug.LogWarning("[Kit_WeaponPickup] Player does not have a Kit_ModernWeaponManager");
            return false;
        }

        // You may adjust your logic here:
        if (wpnManager.HasWeapon(weaponID))
        {
            // Refill ammo of the existing weapon if possible
            wpnManager.RefillWeapon(weaponID);
            return true;
        }
        else
        {
            // Try to give the weapon if player doesn't have it
            return wpnManager.TryGiveWeapon(weaponID);
        }
    }
}
```

---

### How This Script Fits Your Project:

- It uses/MMFPSE's **Kit_PlayerBehaviour** and **Kit_ModernWeaponManager** references exactly.
- Pickup collider triggers only for players (tag "Player" is assumed; change if your player tag differs).
- On pickup, it tries to add or refill the weapon via MMFPSE weapon manager.
- It calls **`respawnManager.PickupTaken()`** to deactivate this pickup and schedule respawn.
- It assumes the respawn manager manages the single instance, so no cloning done here.
- `weaponID` is exposed in inspector for easy configuration per pickup.

---

### Now, the previously shared `Kit_WeaponPickupRespawnManager.cs` (unchanged) manages:

- Instantiating the pickup prefab **once** on start.
- Activating / deactivating **that same instance** (not instantiating clones on respawn).
- Handling respawn delays and activation.

---

### Notes:

- Make sure **your pickup prefab** includes this `Kit_WeaponPickup` script and a trigger collider.
- Make sure the prefab is assigned in the respawn manager and that pickup instances are children or otherwise linked so `GetComponentInParent` works.
- This approach avoids clones, always activates/deactivates one instance.
- If your game uses networking (Mirror + Unity Relay), be sure to **spawn this pickup prefab once on the server** using `NetworkServer.Spawn()` and synchronize activation appropriately.

---

If you also want the **full respawn manager script** again, or help integrating networking spawning and syncing for MMFPSE Relay/Mirror, just ask!

turns-00083.parquet:31600

b7698fd2e2ae24da7a21aca9
turn 6/19gpt-4.1-mini-2025-04-14EnglishCroatia936 words
degenerate_repetitionAbsentFinal dense release
USER
Assets\My\Scripts\Kit_WeaponPickup.cs(39,59): error CS1061: 'Kit_PlayerBehaviour' does not contain a definition for 'nickname' and no accessible extension method 'nickname' accepting a first argument of type 'Kit_PlayerBehaviour' could be found (are you missing a using directive or an assembly reference?)

Assets\My\Scripts\Kit_WeaponPickup.cs(53,66): error CS1061: 'Kit_PlayerBehaviour' does not contain a definition for 'nickname' and no accessible extension method 'nickname' accepting a first argument of type 'Kit_PlayerBehaviour' could be found (are you missing a using directive or an assembly reference?)

Assets\My\Scripts\Kit_WeaponPickup.cs(73,24): error CS7036: There is no argument given that corresponds to the required formal parameter 'id' of 'Kit_ModernWeaponManager.HasWeapon(Kit_PlayerBehaviour, int)'

Assets\My\Scripts\Kit_WeaponPickup.cs(76,24): error CS1061: 'Kit_ModernWeaponManager' does not contain a definition for 'RefillWeapon' and no accessible extension method 'RefillWeapon' accepting a first argument of type 'Kit_ModernWeaponManager' could be found (are you missing a using directive or an assembly reference?)

Assets\My\Scripts\Kit_WeaponPickup.cs(82,31): error CS1061: 'Kit_ModernWeaponManager' does not contain a definition for 'TryGiveWeapon' and no accessible extension method 'TryGiveWeapon' accepting a first argument of type 'Kit_ModernWeaponManager' could be found (are you missing a using directive or an assembly reference?)

ASSISTANT
The errors indicate that the methods and properties I assumed on `Kit_PlayerBehaviour` and `Kit_ModernWeaponManager` do not exist or have different signatures in your version of MMFPSE.

Let's correct the script based on the error messages and typical MMFPSE usage:

---

### Issues & Fixes Recap:

1. **`Kit_PlayerBehaviour` has no `nickname` property or field:**

   - Use `player.playerName` or remove logging of name.
   - Or simply omit player name in logs if no such property exists.

2. **`Kit_ModernWeaponManager` methods expect different parameters or have different names:**

   Errors:

   - `HasWeapon(Kit_PlayerBehaviour, int)` expects **two parameters** instead of one.
   - `RefillWeapon` method does not exist.
   - `TryGiveWeapon` method does not exist.

We need to reference the methods with correct signatures or alternative ways.

---

### How to find correct method signatures?

Looking at MMFPSE typical weapon manager, `HasWeapon` usually is:

```csharp
public bool HasWeapon(Kit_PlayerBehaviour player, int id);
```

which explains the first error.

`RefillWeapon` and `TryGiveWeapon` may not be public/high-level functions or could be named differently.

---

### Adjusted `Kit_WeaponPickup.cs` to fix your errors:

```csharp
using UnityEngine;
using MarsFPSKit;
using MarsFPSKit.Weapons;

public class Kit_WeaponPickup : MonoBehaviour
{
    public int weaponID = 1;

    private Kit_WeaponPickupRespawnManager respawnManager;

    private void Start()
    {
        if (respawnManager == null)
        {
            respawnManager = GetComponentInParent<Kit_WeaponPickupRespawnManager>();
        }

        if (respawnManager == null)
        {
            Debug.LogWarning("[Kit_WeaponPickup] No Kit_WeaponPickupRespawnManager found in parents.");
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        if (!other.CompareTag("Player")) return;

        Kit_PlayerBehaviour player = other.GetComponent<Kit_PlayerBehaviour>();

        if (player == null) return;

        if (TryGiveOrRefillWeapon(player))
        {
            Debug.Log($"[Kit_WeaponPickup] Player picked up weapon ID {weaponID}");

            if (respawnManager != null)
            {
                respawnManager.PickupTaken();
            }
            else
            {
                Debug.LogWarning("[Kit_WeaponPickup] Cannot notify respawn manager - it's null");
            }
        }
        else
        {
            Debug.LogWarning("[Kit_WeaponPickup] Player already has weapon or failed to pick up weapon");
        }
    }

    private bool TryGiveOrRefillWeapon(Kit_PlayerBehaviour player)
    {
        if (player == null) return false;

        Kit_ModernWeaponManager wpnManager = player.weaponManager as Kit_ModernWeaponManager;

        if (wpnManager == null)
        {
            Debug.LogWarning("[Kit_WeaponPickup] Player does not have a Kit_ModernWeaponManager");
            return false;
        }

        // Use correct method signatures as per your MMFPSE version:

        // HasWeapon requires player and id:
        bool hasWeapon = wpnManager.HasWeapon(player, weaponID);

        if (hasWeapon)
        {
            // Try to refill ammo if you have a method for it — if no RefillWeapon method exists, you can skip or implement your own logic

            // Example fallback:
            TryRefillAmmo(wpnManager, player, weaponID);

            return true;
        }
        else
        {
            // TryGiveWeapon might be named differently or missing; manual add method may be required

            bool added = TryGiveWeapon(wpnManager, player, weaponID);
            return added;
        }
    }

    /// <summary>
    /// Example ammo refill fallback if no RefillWeapon method exists.
    /// Replace with your actual logic.
    /// </summary>
    private void TryRefillAmmo(Kit_ModernWeaponManager wpnManager, Kit_PlayerBehaviour player, int id)
    {
        // Implement your refill logic here if possible.
        // For example, access the player's current weapon inventory and refill ammo.

        Debug.Log("[Kit_WeaponPickup] Ammo refill logic not implemented (override this).");
    }

    /// <summary>
    /// Example giving the weapon fallback if TryGiveWeapon is not available.
    /// Replace with your actual logic.
    /// </summary>
    private bool TryGiveWeapon(Kit_ModernWeaponManager wpnManager, Kit_PlayerBehaviour player, int id)
    {
        // Implement your own logic here to add a weapon to player inventory.

        Debug.Log("[Kit_WeaponPickup] Weapon give logic not implemented (override this).");
        return false;
    }
}
```

---

### What to do next?

- **Check your MMFPSE `Kit_ModernWeaponManager` class** for exactly how to:  
  - Check if player has a weapon.  
  - Add/give weapon to player.  
  - Refill ammo or similar.

- **Fill in the `TryRefillAmmo` and `TryGiveWeapon` methods** with that exact logic.

---

### Possible methods based on typical MMFPSE versions:

- `HasWeapon(Kit_PlayerBehaviour player, int weaponID)` - check if player has weapon.
- `AddWeapon(Kit_PlayerBehaviour player, int weaponID)` or `SetWeapon(weaponID)` or similar - to give weapon.
- Ammo refills usually happen by directly manipulating weapon's ammo properties or calling some reload/refill methods.

---

### Example stub with guessed methods (only if you verify correct API):

```csharp
private void TryRefillAmmo(Kit_ModernWeaponManager wpnManager, Kit_PlayerBehaviour player, int id)
{
    // Hypothetical example: refill ammo by weapon slot or via weapon manager API
    var modWeapon = wpnManager.GetWeaponForPlayer(player, id);
    if (modWeapon != null)
    {
        modWeapon.currentAmmo = modWeapon.maxAmmo;
    }
}

private bool TryGiveWeapon(Kit_ModernWeaponManager wpnManager, Kit_PlayerBehaviour player, int id)
{
    // Hypothetical add weapon call, adjust if your version is different
    return wpnManager.AddWeapon(player, id);
}
```

---

### Without your exact MMFPSE source, this is the best generalized correction I can give.

If you want, provide me the method signatures from your `Kit_ModernWeaponManager` class regarding weapon checks and giving weapons and I can write exact code.

---

**Summary:**  
- Fix `HasWeapon(player, id)` call with two parameters.  
- Remove `nickname` logging or replace with your player name property.  
- Implement your own `RefillWeapon` and `TryGiveWeapon` equivalents according to your MMFPSE API.

---

If you need help with those `Kit_ModernWeaponManager` methods, please share their relevant code or method signatures!

turns-00083.parquet:31601

9d5e59178de5bb9b725b61b5
turn 7/19gpt-4.1-mini-2025-04-14EnglishCroatia429 words
degenerate_repetitionAbsentFinal dense release
USER
Assets\My\Scripts\Kit_WeaponPickup.cs(66,26): error CS0029: Cannot implicitly convert type 'int' to 'bool'
ASSISTANT
The error

```
Assets\My\Scripts\Kit_WeaponPickup.cs(66,26): error CS0029: Cannot implicitly convert type 'int' to 'bool'
```

means that you are assigning or returning an `int` when your code expects a `bool`. Most likely, this relates to a method like `HasWeapon()` which you expected to return a boolean, but actually returns an integer (probably the weapon slot index or -1 if not found).

---

### What this means in your case

In MarsFPSKit (MMFPSE), from what I know:

- `HasWeapon(Kit_PlayerBehaviour player, int weaponID)` returns an **int** representing the index of the weapon slot (or -1 if player doesn't have weapon).

So you cannot do:

```csharp
bool hasWeapon = wpnManager.HasWeapon(player, weaponID); // error: int → bool
```

Instead:

```csharp
int weaponSlot = wpnManager.HasWeapon(player, weaponID);
bool hasWeapon = weaponSlot != -1;
```

---

### Fix applied to your script snippet:

```csharp
// Check if the player has the weapon (slot index or -1)
int weaponSlot = wpnManager.HasWeapon(player, weaponID);

if (weaponSlot != -1)
{
    // Player has weapon, try to refill ammo
    TryRefillAmmo(wpnManager, player, weaponID, weaponSlot);
    return true;
}
else
{
    // Player does not have weapon, try to give it
    bool added = TryGiveWeapon(wpnManager, player, weaponID);
    return added;
}
```

---

### Also update `TryRefillAmmo` to get slot index if needed:

Modify the signature:

```csharp
private void TryRefillAmmo(Kit_ModernWeaponManager wpnManager, Kit_PlayerBehaviour player, int id, int weaponSlot)
{
    // Example: refill ammo based on weaponSlot
    var modWeapon = wpnManager.weapons[weaponSlot];
    if (modWeapon != null)
    {
        modWeapon.currentAmmo = modWeapon.maxAmmo;
        Debug.Log("[Kit_WeaponPickup] Ammo refilled");
    }
}
```

---

### Complete fixed portion in context:

```csharp
private bool TryGiveOrRefillWeapon(Kit_PlayerBehaviour player)
{
    if (player == null) return false;

    Kit_ModernWeaponManager wpnManager = player.weaponManager as Kit_ModernWeaponManager;

    if (wpnManager == null)
    {
        Debug.LogWarning("[Kit_WeaponPickup] Player does not have a Kit_ModernWeaponManager");
        return false;
    }

    // This returns weapon slot index or -1 if player does NOT have the weapon
    int weaponSlot = wpnManager.HasWeapon(player, weaponID);

    if (weaponSlot != -1)
    {
        TryRefillAmmo(wpnManager, player, weaponID, weaponSlot);
        return true;
    }
    else
    {
        bool added = TryGiveWeapon(wpnManager, player, weaponID);
        return added;
    }
}

private void TryRefillAmmo(Kit_ModernWeaponManager wpnManager, Kit_PlayerBehaviour player, int id, int weaponSlot)
{
    var modWeapon = wpnManager.weapons[weaponSlot];
    if (modWeapon != null)
    {
        modWeapon.currentAmmo = modWeapon.maxAmmo;
        Debug.Log("[Kit_WeaponPickup] Ammo refilled");
    }
}
```

---

### Summary:

- `HasWeapon` returns an int slot or -1.
- Compare to -1 to get bool "has weapon".
- Use weapon slot to refill ammo.
- Implement your own (or existing) `TryGiveWeapon` method to provide weapon.

---

If you want me to help implement `TryGiveWeapon` based on your code/api, please share how you add weapons in your `Kit_ModernWeaponManager`.

turns-00083.parquet:31602

b013b2576695f700b10ccde1
turn 8/19gpt-4.1-mini-2025-04-14EnglishCroatia530 words
degenerate_repetitionAbsentFinal dense release
USER
show the full fixed script
ASSISTANT
Certainly! Below is the **full fixed `Kit_WeaponPickup.cs` script** that:

- Uses the correct `HasWeapon` signature returning int.
- Checks `weaponSlot != -1` to detect if player has the weapon.
- Refills ammo using the weapon slot.
- Keeps placeholders for `TryGiveWeapon` logic (you should fill these according to your MMFPSE code).
- Removes `nickname` usage to avoid errors.
- Compatible with MarsFPSKit (MMFPSE) conventions.

---

```csharp
using UnityEngine;
using MarsFPSKit;
using MarsFPSKit.Weapons;

public class Kit_WeaponPickup : MonoBehaviour
{
    [Tooltip("Weapon ID this pickup grants")]
    public int weaponID = 1;

    private Kit_WeaponPickupRespawnManager respawnManager;

    private void Start()
    {
        if (respawnManager == null)
        {
            respawnManager = GetComponentInParent<Kit_WeaponPickupRespawnManager>();
        }

        if (respawnManager == null)
        {
            Debug.LogWarning("[Kit_WeaponPickup] No Kit_WeaponPickupRespawnManager found in parent hierarchy.");
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        // Only respond to players
        if (!other.CompareTag("Player")) return;

        Kit_PlayerBehaviour player = other.GetComponent<Kit_PlayerBehaviour>();
        if (player == null) return;

        if (TryGiveOrRefillWeapon(player))
        {
            Debug.Log($"[Kit_WeaponPickup] Player picked up weapon ID {weaponID}");

            if (respawnManager != null)
            {
                respawnManager.PickupTaken();
            }
            else
            {
                Debug.LogWarning("[Kit_WeaponPickup] Respawn manager reference missing.");
            }
        }
        else
        {
            Debug.LogWarning("[Kit_WeaponPickup] Player failed to pick up weapon (maybe already has it).");
        }
    }

    /// <summary>
    /// Attempts to give weapon to player if they don't have it, or refill ammo if they do.
    /// </summary>
    private bool TryGiveOrRefillWeapon(Kit_PlayerBehaviour player)
    {
        if (player == null) return false;

        Kit_ModernWeaponManager wpnManager = player.weaponManager as Kit_ModernWeaponManager;
        if (wpnManager == null)
        {
            Debug.LogWarning("[Kit_WeaponPickup] Player's weapon manager is not Kit_ModernWeaponManager.");
            return false;
        }

        // HasWeapon returns weapon slot index if owned, or -1 if not
        int weaponSlot = wpnManager.HasWeapon(player, weaponID);

        if (weaponSlot != -1)
        {
            // Player has weapon, refill ammo in that slot
            TryRefillAmmo(wpnManager, weaponSlot);
            return true;
        }
        else
        {
            // Player does not have weapon, try to give it
            bool added = TryGiveWeapon(wpnManager, player, weaponID);
            return added;
        }
    }

    /// <summary>
    /// Refill ammo on weapon in given slot.
    /// </summary>
    private void TryRefillAmmo(Kit_ModernWeaponManager wpnManager, int weaponSlot)
    {
        if (wpnManager.weapons == null)
        {
            Debug.LogWarning("[Kit_WeaponPickup] Weapon manager weapons array is null.");
            return;
        }

        if (weaponSlot < 0 || weaponSlot >= wpnManager.weapons.Length)
        {
            Debug.LogWarning("[Kit_WeaponPickup] Weapon slot out of bounds.");
            return;
        }

        var modWeapon = wpnManager.weapons[weaponSlot];
        if (modWeapon != null)
        {
            modWeapon.currentAmmo = modWeapon.maxAmmo;
            Debug.Log("[Kit_WeaponPickup] Ammo refilled on existing weapon.");
        }
    }

    /// <summary>
    /// Attempts to give weapon to player.
    /// Replace or extend with your actual MMFPSE weapon granting code.
    /// </summary>
    private bool TryGiveWeapon(Kit_ModernWeaponManager wpnManager, Kit_PlayerBehaviour player, int weaponID)
    {
        // TODO: Implement this with your actual MMFPSE weapon granting method

        // Example placeholder implementation:
        Debug.Log("[Kit_WeaponPickup] TryGiveWeapon called - not implemented. Override this method to add weapon.");

        // Return false indicating weapon not added (you need to implement this)
        return false;
    }
}
```

---

### How to proceed

- Implement your actual logic inside `TryGiveWeapon()` — usually there is a function in `Kit_ModernWeaponManager` like `AddWeapon(Kit_PlayerBehaviour player, int weaponID)` or similar you can call.
- Make sure your weapon prefab has this script attached and has a trigger collider.
- Ensure the pickup is managed by `Kit_WeaponPickupRespawnManager` that controls instantiation and respawn (activates/deactivates the single instance).

---

If you want, feel free to share your `Kit_ModernWeaponManager` methods related to giving weapons and I can write the exact `TryGiveWeapon` code for you!

turns-00083.parquet:31603

72aad4a03de15ab48f4d4749
turn 9/19gpt-4.1-mini-2025-04-14EnglishCroatia775 words
degenerate_repetitionAbsentFinal dense release
USER
Assets\My\Scripts\Kit_WeaponPickup.cs(88,24): error CS1061: 'Kit_ModernWeaponManager' does not contain a definition for 'weapons' and no accessible extension method 'weapons' accepting a first argument of type 'Kit_ModernWeaponManager' could be found (are you missing a using directive or an assembly reference?)

Assets\My\Scripts\Kit_WeaponPickup.cs(94,56): error CS1061: 'Kit_ModernWeaponManager' does not contain a definition for 'weapons' and no accessible extension method 'weapons' accepting a first argument of type 'Kit_ModernWeaponManager' could be found (are you missing a using directive or an assembly reference?)

Assets\My\Scripts\Kit_WeaponPickup.cs(100,36): error CS1061: 'Kit_ModernWeaponManager' does not contain a definition for 'weapons' and no accessible extension method 'weapons' accepting a first argument of type 'Kit_ModernWeaponManager' could be found (are you missing a using directive or an assembly reference?)

ASSISTANT
The error messages indicate that your version of **`Kit_ModernWeaponManager` does not expose a public `weapons` array or property** as used in the previous example. This is common if the weapon data is encapsulated or accessed via different methods rather than a direct public field.

---

### What to do:

You need to **interact with the weapon manager using public methods or properties it exposes**, not by accessing `weapons` directly.

Since I don't have your exact MMFPSE codebase, here are some common strategies based on typical FPS kit architectures:

---

### 1. Check if there are Getter methods for weapon data

Look for methods like:

- `GetWeapon(int slot)`
- `GetWeaponById(int id)`

---

### 2. Instead of accessing weapons array, you can:

- Query the player's current equipped weapon’s ammo (if accessible).
- Use functions in `Kit_ModernWeaponManager` to modify ammo or refresh weapon state.

---

### Adjusted `TryRefillAmmo` method (pseudo-code):

Let’s assume you can do something like:

```csharp
// Get weapon data or manager method to refill ammo by weapon ID or weapon slot
var weapon = wpnManager.GetWeaponById(weaponID); // If exists

if (weapon != null)
{
    // Assuming weapon has ammo properties you can set
    weapon.currentAmmo = weapon.maxAmmo;
    Debug.Log("[Kit_WeaponPickup] Ammo has been refilled.");
}
else
{
    Debug.LogWarning("[Kit_WeaponPickup] Weapon to refill ammo not found.");
}
```

If no such method exists, you might need to:

- Inspect the MMFPSE docs or source for how to:

  - Access the player's weapon loadout.
  - Modify ammo values.

---

### Without direct access to weapons, a fallback is to **skip refill and only try giving the weapon** (or implement refill via your specific API).

---

## Final recommended code version with safe assumptions:

```csharp
using UnityEngine;
using MarsFPSKit;
using MarsFPSKit.Weapons;

public class Kit_WeaponPickup : MonoBehaviour
{
    [Tooltip("Weapon ID this pickup grants")]
    public int weaponID = 1;

    private Kit_WeaponPickupRespawnManager respawnManager;

    private void Start()
    {
        if (respawnManager == null)
            respawnManager = GetComponentInParent<Kit_WeaponPickupRespawnManager>();

        if (respawnManager == null)
            Debug.LogWarning("[Kit_WeaponPickup] No Kit_WeaponPickupRespawnManager in parents.");
    }

    private void OnTriggerEnter(Collider other)
    {
        if (!other.CompareTag("Player")) return;

        Kit_PlayerBehaviour player = other.GetComponent<Kit_PlayerBehaviour>();
        if (player == null) return;

        if (TryGiveOrRefillWeapon(player))
        {
            Debug.Log($"[Kit_WeaponPickup] Player picked up weapon ID {weaponID}");

            if (respawnManager != null)
                respawnManager.PickupTaken();
            else
                Debug.LogWarning("[Kit_WeaponPickup] Respawn manager reference missing.");
        }
        else
        {
            Debug.LogWarning("[Kit_WeaponPickup] Player failed to pick up weapon.");
        }
    }

    private bool TryGiveOrRefillWeapon(Kit_PlayerBehaviour player)
    {
        if (player == null) return false;

        Kit_ModernWeaponManager wpnManager = player.weaponManager as Kit_ModernWeaponManager;
        if (wpnManager == null)
        {
            Debug.LogWarning("[Kit_WeaponPickup] Player's weapon manager not Kit_ModernWeaponManager.");
            return false;
        }

        // HasWeapon returns int slot or -1 if no weapon
        int weaponSlot = wpnManager.HasWeapon(player, weaponID);

        if (weaponSlot != -1)
        {
            // Attempt to refill ammo - if you have method, call it here, or skip this if not
            TryRefillAmmo(wpnManager, weaponID);

            return true;
        }
        else
        {
            // Try to give weapon
            return TryGiveWeapon(wpnManager, player, weaponID);
        }
    }

    private void TryRefillAmmo(Kit_ModernWeaponManager wpnManager, int weaponID)
    {
        // ** IMPORTANT **
        // Replace this with your own logic to refill ammo in MMFPSE weapon manager.
        // Since weapons array not public, you will need to use whatever API MMFPSE provides.

        Debug.Log("[Kit_WeaponPickup] TryRefillAmmo called - override with MMOFPSE ammo refill logic.");
    }

    private bool TryGiveWeapon(Kit_ModernWeaponManager wpnManager, Kit_PlayerBehaviour player, int weaponID)
    {
        // ** IMPORTANT **
        // Replace this stub with your actual MMFPSE weapon giving code.

        Debug.Log("[Kit_WeaponPickup] TryGiveWeapon called - override with MMFPSE weapon adding logic.");

        return false;
    }
}
```

---

### Summary:

- **Not accessing `weapons` array directly** (since it does not exist or is inaccessible).
- **You must implement `TryRefillAmmo` and `TryGiveWeapon` with your actual MMFPSE API calls.**
- Logging included to remind you where to do this.

---

### Next Steps:

Please check your `Kit_ModernWeaponManager` class for:

- How to add a weapon (method name and parameters).
- How to refill ammo / update ammo count.

You can share that snippet here and I can help write those methods exactly.

---

If you want me to help you adapt those methods, just copy-paste the relevant methods or signatures from `Kit_ModernWeaponManager` source and I will write the exact calls for you.

turns-00083.parquet:31604

3b506a145d30776fbeaa6a36
turn 10/19gpt-4.1-mini-2025-04-14EnglishCroatia1883 words
degenerate_repetitionAbsentFinal dense release
USER
<color=magenta>[MMFPSE UGS Manager]</color> Initializing UGS.
UnityEngine.Debug:Log (object,UnityEngine.Object)
MarsFPSKit.Services.Kit_UGS/<Awake>d__2:MoveNext () (at Assets/314 Arts/MarsFPSKit/Scripts/Services/Kit_UGS.cs:36)
System.Runtime.CompilerServices.AsyncVoidMethodBuilder:Start<MarsFPSKit.Services.Kit_UGS/<Awake>d__2> (MarsFPSKit.Services.Kit_UGS/<Awake>d__2&)
MarsFPSKit.Services.Kit_UGS:Awake ()

RelayManager initialized
UnityEngine.Debug:Log (object)
Utp.RelayManager:Awake () (at Assets/314 Arts/MarsFPSKit/Required/UTPTransport/Relay/RelayManager.cs:36)
UnityEngine.GameObject:AddComponent<Utp.RelayManager> ()
Utp.UtpTransport:Awake () (at Assets/314 Arts/MarsFPSKit/Required/UTPTransport/UtpTransport.cs:91)
UnityEngine.GameObject:AddComponent<Utp.UtpTransport> ()
MarsFPSKit.Services.Kit_TransportServiceUgsRelay:Initialize (MarsFPSKit.Kit_NetworkManager) (at Assets/314 Arts/MarsFPSKit/Scripts/Services/Kit_TransportServiceUgsRelay.cs:76)
MarsFPSKit.Kit_NetworkManager:Awake () (at Assets/314 Arts/MarsFPSKit/Scripts/Networking/Kit_NetworkManager.cs:76)

UTPTransport initialized!
UnityEngine.Debug:Log (object)
Utp.UtpTransport:Awake () (at Assets/314 Arts/MarsFPSKit/Required/UTPTransport/UtpTransport.cs:94)
UnityEngine.GameObject:AddComponent<Utp.UtpTransport> ()
MarsFPSKit.Services.Kit_TransportServiceUgsRelay:Initialize (MarsFPSKit.Kit_NetworkManager) (at Assets/314 Arts/MarsFPSKit/Scripts/Services/Kit_TransportServiceUgsRelay.cs:76)
MarsFPSKit.Kit_NetworkManager:Awake () (at Assets/314 Arts/MarsFPSKit/Scripts/Networking/Kit_NetworkManager.cs:76)

<color=magenta>[MMFPSE UGS Manager]</color> Signing in anonymously.
UnityEngine.Debug:Log (object,UnityEngine.Object)
MarsFPSKit.Services.Kit_UGS/<Awake>d__2:MoveNext () (at Assets/314 Arts/MarsFPSKit/Scripts/Services/Kit_UGS.cs:38)
System.Runtime.CompilerServices.AsyncTaskMethodBuilder:SetResult ()
Unity.Services.Core.UnityServices/<InitializeAsync>d__26:MoveNext () (at ./Library/PackageCache/com.unity.services.core@1.14.0/Runtime/Core/UnityServices.cs:136)
System.Runtime.CompilerServices.AsyncTaskMethodBuilder:SetResult ()
Unity.Services.Core.Internal.UnityServicesInternal/<InitializeAsync>d__27:MoveNext () (at ./Library/PackageCache/com.unity.services.core@1.14.0/Runtime/Core.Internal/UnityServicesInternal.cs:96)
System.Threading.Tasks.TaskCompletionSource`1<object>:TrySetResult (object)
Unity.Services.Core.Internal.UnityServicesInternal/<>c__DisplayClass33_0:<InitializeServicesAsync>g__SucceedServicesInitialization|3 () (at ./Library/PackageCache/com.unity.services.core@1.14.0/Runtime/Core.Internal/UnityServicesInternal.cs:191)
Unity.Services.Core.Internal.UnityServicesInternal/<InitializeServicesAsync>d__33:MoveNext () (at ./Library/PackageCache/com.unity.services.core@1.14.0/Runtime/Core.Internal/UnityServicesInternal.cs:164)
System.Runtime.CompilerServices.AsyncTaskMethodBuilder:Start<Unity.Services.Core.Internal.UnityServicesInternal/<InitializeServicesAsync>d__33> (Unity.Services.Core.Internal.UnityServicesInternal/<InitializeServicesAsync>d__33&)
Unity.Services.Core.Internal.UnityServicesInternal:InitializeServicesAsync ()
Unity.Services.Core.Internal.UnityServicesInternal/<EnableInitializationAsync>d__36:MoveNext () (at ./Library/PackageCache/com.unity.services.core@1.14.0/Runtime/Core.Internal/UnityServicesInternal.cs:217)
System.Runtime.CompilerServices.AsyncTaskMethodBuilder:Start<Unity.Services.Core.Internal.UnityServicesInternal/<EnableInitializationAsync>d__36> (Unity.Services.Core.Internal.UnityServicesInternal/<EnableInitializationAsync>d__36&)
Unity.Services.Core.Internal.UnityServicesInternal:EnableInitializationAsync ()
Unity.Services.Core.Internal.UnityServicesInitializer/<EnableServicesInitializationAsync>d__1:MoveNext () (at ./Library/PackageCache/com.unity.services.core@1.14.0/Runtime/Core.Internal/UnityServicesInitializer.cs:32)
System.Runtime.CompilerServices.AsyncVoidMethodBuilder:Start<Unity.Services.Core.Internal.UnityServicesInitializer/<EnableServicesInitializationAsync>d__1> (Unity.Services.Core.Internal.UnityServicesInitializer/<EnableServicesInitializationAsync>d__1&)
Unity.Services.Core.Internal.UnityServicesInitializer:EnableServicesInitializationAsync ()

<color=magenta>[MMFPSE UGS Manager]</color> Logged into UGS, player ID: SYt0H3zGWXCwLfJrQH8WedUYe83P
UnityEngine.Debug:Log (object,UnityEngine.Object)
MarsFPSKit.Services.Kit_UGS/<Awake>d__2:MoveNext () (at Assets/314 Arts/MarsFPSKit/Scripts/Services/Kit_UGS.cs:40)
System.Runtime.CompilerServices.AsyncTaskMethodBuilder:SetResult ()
Unity.Services.Authentication.AuthenticationServiceInternal/<HandleSignInRequestAsync>d__140:MoveNext () (at ./Library/PackageCache/com.unity.services.authentication@2.7.4/Runtime/AuthenticationServiceInternal.cs:806)
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<Unity.Services.Authentication.SignInResponse>:SetResult (Unity.Services.Authentication.SignInResponse)
Unity.Services.Authentication.WebRequest/<SendAsync>d__15`1<Unity.Services.Authentication.SignInResponse>:MoveNext () (at ./Library/PackageCache/com.unity.services.authentication@2.7.4/Runtime/Network/WebRequest.cs:66)
System.Threading.Tasks.TaskCompletionSource`1<string>:SetResult (string)
Unity.Services.Authentication.WebRequest:RequestCompleted (System.Threading.Tasks.TaskCompletionSource`1<string>,long,bool,bool,string,string,System.Collections.Generic.IDictionary`2<string, string>) (at ./Library/PackageCache/com.unity.services.authentication@2.7.4/Runtime/Network/WebRequest.cs:198)
Unity.Services.Authentication.WebRequest/<>c__DisplayClass16_0:<SendAttemptAsync>b__0 (UnityEngine.AsyncOperation) (at ./Library/PackageCache/com.unity.services.authentication@2.7.4/Runtime/Network/WebRequest.cs:76)
UnityEngine.AsyncOperation:InvokeCompletionEvent ()

Starting online server
UnityEngine.Debug:Log (object)
MarsFPSKit.UI.Kit_MenuHostScreen/<StartSessionRoutine>d__35:MoveNext () (at Assets/314 Arts/MarsFPSKit/Scripts/UI/New Main Menu/Kit_MenuHostScreen.cs:340)
UnityEngine.MonoBehaviour:StartCoroutine (System.Collections.IEnumerator)
MarsFPSKit.UI.Kit_MenuHostScreen:StartSession () (at Assets/314 Arts/MarsFPSKit/Scripts/UI/New Main Menu/Kit_MenuHostScreen.cs:290)
UnityEngine.EventSystems.EventSystem:Update () (at ./Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:530)

QosJob: executing job with 10000ms timeout
UnityEngine.Debug:Log (object)
Unity.Networking.QoS.QosJob:Execute () (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:127)
Unity.Jobs.IJobExtensions/JobStruct`1<Unity.Networking.QoS.QosJob>:Execute (Unity.Networking.QoS.QosJob&,intptr,intptr,Unity.Jobs.LowLevel.Unsafe.JobRanges&,int)

QosJob: send to 35.185.184.193:7778 took 2ms
UnityEngine.Debug:Log (object)
Unity.Networking.QoS.QosJob:ProcessServer (Unity.Networking.QoS.QosJob/InternalQosServer,Unity.Baselib.LowLevel.Binding/Baselib_Socket_Handle) (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:225)
Unity.Networking.QoS.QosJob:ProcessServers (Unity.Baselib.LowLevel.Binding/Baselib_Socket_Handle) (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:165)
Unity.Networking.QoS.QosJob:Execute () (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:142)
Unity.Jobs.IJobExtensions/JobStruct`1<Unity.Networking.QoS.QosJob>:Execute (Unity.Networking.QoS.QosJob&,intptr,intptr,Unity.Jobs.LowLevel.Unsafe.JobRanges&,int)

QosJob: send to 34.121.11.132:7778 took 2ms
UnityEngine.Debug:Log (object)
Unity.Networking.QoS.QosJob:ProcessServer (Unity.Networking.QoS.QosJob/InternalQosServer,Unity.Baselib.LowLevel.Binding/Baselib_Socket_Handle) (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:225)
Unity.Networking.QoS.QosJob:ProcessServers (Unity.Baselib.LowLevel.Binding/Baselib_Socket_Handle) (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:165)
Unity.Networking.QoS.QosJob:Execute () (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:142)
Unity.Jobs.IJobExtensions/JobStruct`1<Unity.Networking.QoS.QosJob>:Execute (Unity.Networking.QoS.QosJob&,intptr,intptr,Unity.Jobs.LowLevel.Unsafe.JobRanges&,int)

QosJob: send to 35.228.80.26:7778 took 0ms
UnityEngine.Debug:Log (object)
Unity.Networking.QoS.QosJob:ProcessServer (Unity.Networking.QoS.QosJob/InternalQosServer,Unity.Baselib.LowLevel.Binding/Baselib_Socket_Handle) (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:225)
Unity.Networking.QoS.QosJob:ProcessServers (Unity.Baselib.LowLevel.Binding/Baselib_Socket_Handle) (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:165)
Unity.Networking.QoS.QosJob:Execute () (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:142)
Unity.Jobs.IJobExtensions/JobStruct`1<Unity.Networking.QoS.QosJob>:Execute (Unity.Networking.QoS.QosJob&,intptr,intptr,Unity.Jobs.LowLevel.Unsafe.JobRanges&,int)

QosJob: send to 34.87.195.172:7778 took 2ms
UnityEngine.Debug:Log (object)
Unity.Networking.QoS.QosJob:ProcessServer (Unity.Networking.QoS.QosJob/InternalQosServer,Unity.Baselib.LowLevel.Binding/Baselib_Socket_Handle) (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:225)
Unity.Networking.QoS.QosJob:ProcessServers (Unity.Baselib.LowLevel.Binding/Baselib_Socket_Handle) (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:165)
Unity.Networking.QoS.QosJob:Execute () (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:142)
Unity.Jobs.IJobExtensions/JobStruct`1<Unity.Networking.QoS.QosJob>:Execute (Unity.Networking.QoS.QosJob&,intptr,intptr,Unity.Jobs.LowLevel.Unsafe.JobRanges&,int)

QosJob: send to 34.90.156.155:7778 took 0ms
UnityEngine.Debug:Log (object)
Unity.Networking.QoS.QosJob:ProcessServer (Unity.Networking.QoS.QosJob/InternalQosServer,Unity.Baselib.LowLevel.Binding/Baselib_Socket_Handle) (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:225)
Unity.Networking.QoS.QosJob:ProcessServers (Unity.Baselib.LowLevel.Binding/Baselib_Socket_Handle) (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:165)
Unity.Networking.QoS.QosJob:Execute () (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:142)
Unity.Jobs.IJobExtensions/JobStruct`1<Unity.Networking.QoS.QosJob>:Execute (Unity.Networking.QoS.QosJob&,intptr,intptr,Unity.Jobs.LowLevel.Unsafe.JobRanges&,int)

QosJob: send to 35.244.34.146:7778 took 2ms
UnityEngine.Debug:Log (object)
Unity.Networking.QoS.QosJob:ProcessServer (Unity.Networking.QoS.QosJob/InternalQosServer,Unity.Baselib.LowLevel.Binding/Baselib_Socket_Handle) (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:225)
Unity.Networking.QoS.QosJob:ProcessServers (Unity.Baselib.LowLevel.Binding/Baselib_Socket_Handle) (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:165)
Unity.Networking.QoS.QosJob:Execute () (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:142)
Unity.Jobs.IJobExtensions/JobStruct`1<Unity.Networking.QoS.QosJob>:Execute (Unity.Networking.QoS.QosJob&,intptr,intptr,Unity.Jobs.LowLevel.Unsafe.JobRanges&,int)

QosJob: send to 34.116.138.213:7778 took 0ms
UnityEngine.Debug:Log (object)
Unity.Networking.QoS.QosJob:ProcessServer (Unity.Networking.QoS.QosJob/InternalQosServer,Unity.Baselib.LowLevel.Binding/Baselib_Socket_Handle) (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:225)
Unity.Networking.QoS.QosJob:ProcessServers (Unity.Baselib.LowLevel.Binding/Baselib_Socket_Handle) (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:165)
Unity.Networking.QoS.QosJob:Execute () (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:142)
Unity.Jobs.IJobExtensions/JobStruct`1<Unity.Networking.QoS.QosJob>:Execute (Unity.Networking.QoS.QosJob&,intptr,intptr,Unity.Jobs.LowLevel.Unsafe.JobRanges&,int)

QosJob: send to 34.84.175.100:7778 took 2ms
UnityEngine.Debug:Log (object)
Unity.Networking.QoS.QosJob:ProcessServer (Unity.Networking.QoS.QosJob/InternalQosServer,Unity.Baselib.LowLevel.Binding/Baselib_Socket_Handle) (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:225)
Unity.Networking.QoS.QosJob:ProcessServers (Unity.Baselib.LowLevel.Binding/Baselib_Socket_Handle) (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:165)
Unity.Networking.QoS.QosJob:Execute () (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:142)
Unity.Jobs.IJobExtensions/JobStruct`1<Unity.Networking.QoS.QosJob>:Execute (Unity.Networking.QoS.QosJob&,intptr,intptr,Unity.Jobs.LowLevel.Unsafe.JobRanges&,int)

QosJob: send to 35.247.237.17:7778 took 0ms
UnityEngine.Debug:Log (object)
Unity.Networking.QoS.QosJob:ProcessServer (Unity.Networking.QoS.QosJob/InternalQosServer,Unity.Baselib.LowLevel.Binding/Baselib_Socket_Handle) (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:225)
Unity.Networking.QoS.QosJob:ProcessServers (Unity.Baselib.LowLevel.Binding/Baselib_Socket_Handle) (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:165)
Unity.Networking.QoS.QosJob:Execute () (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:142)
Unity.Jobs.IJobExtensions/JobStruct`1<Unity.Networking.QoS.QosJob>:Execute (Unity.Networking.QoS.QosJob&,intptr,intptr,Unity.Jobs.LowLevel.Unsafe.JobRanges&,int)

QosJob: send to 35.227.42.36:7778 took 1ms
UnityEngine.Debug:Log (object)
Unity.Networking.QoS.QosJob:ProcessServer (Unity.Networking.QoS.QosJob/InternalQosServer,Unity.Baselib.LowLevel.Binding/Baselib_Socket_Handle) (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:225)
Unity.Networking.QoS.QosJob:ProcessServers (Unity.Baselib.LowLevel.Binding/Baselib_Socket_Handle) (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:165)
Unity.Networking.QoS.QosJob:Execute () (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:142)
Unity.Jobs.IJobExtensions/JobStruct`1<Unity.Networking.QoS.QosJob>:Execute (Unity.Networking.QoS.QosJob&,intptr,intptr,Unity.Jobs.LowLevel.Unsafe.JobRanges&,int)

QosJob: send to 34.19.21.101:7778 took 0ms
UnityEngine.Debug:Log (object)
Unity.Networking.QoS.QosJob:ProcessServer (Unity.Networking.QoS.QosJob/InternalQosServer,Unity.Baselib.LowLevel.Binding/Baselib_Socket_Handle) (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:225)
Unity.Networking.QoS.QosJob:ProcessServers (Unity.Baselib.LowLevel.Binding/Baselib_Socket_Handle) (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:165)
Unity.Networking.QoS.QosJob:Execute () (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:142)
Unity.Jobs.IJobExtensions/JobStruct`1<Unity.Networking.QoS.QosJob>:Execute (Unity.Networking.QoS.QosJob&,intptr,intptr,Unity.Jobs.LowLevel.Unsafe.JobRanges&,int)

QosJob: received 55 responses of 55/55 in 260ms waiting avg 5ms per response
UnityEngine.Debug:Log (object)
Unity.Networking.QoS.QosJob:RecvQosResponsesTimed (Unity.Networking.QoS.NetworkEndPoint,System.DateTime,Unity.Baselib.LowLevel.Binding/Baselib_Socket_Handle,bool) (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:331)
Unity.Networking.QoS.QosJob:ProcessServers (Unity.Baselib.LowLevel.Binding/Baselib_Socket_Handle) (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:184)
Unity.Networking.QoS.QosJob:Execute () (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:142)
Unity.Jobs.IJobExtensions/JobStruct`1<Unity.Networking.QoS.QosJob>:Execute (Unity.Networking.QoS.QosJob&,intptr,intptr,Unity.Jobs.LowLevel.Unsafe.JobRanges&,int)

QosJob: took 274ms to process 11 servers
UnityEngine.Debug:Log (object)
Unity.Networking.QoS.QosJob:Execute () (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/QosJob.cs:146)
Unity.Jobs.IJobExtensions/JobStruct`1<Unity.Networking.QoS.QosJob>:Execute (Unity.Networking.QoS.QosJob&,intptr,intptr,Unity.Jobs.LowLevel.Unsafe.JobRanges&,int)

best region is europe-central2
UnityEngine.Debug:Log (object)
Unity.Services.Relay.WrappedRelayService/<CreateAllocationAsync>d__6:MoveNext () (at ./Library/PackageCache/com.unity.services.relay@1.1.1/Runtime/SDK/WrappedRelayService.cs:54)
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<System.Collections.Generic.IList`1<Unity.Services.Qos.Internal.QosResult>>:SetResult (System.Collections.Generic.IList`1<Unity.Services.Qos.Internal.QosResult>)
Unity.Services.Qos.WrappedQosService/<GetSortedInternalQosResultsAsync>d__19:MoveNext () (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/WrappedQosService.cs:115)
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<System.Collections.Generic.List`1<Unity.Services.Qos.Internal.QosResult>>:SetResult (System.Collections.Generic.List`1<Unity.Services.Qos.Internal.QosResult>)
Unity.Services.Qos.Runner.BaselibQosRunner/<MeasureQosAsync>d__3:MoveNext () (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/BaselibQosRunner.cs:53)
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<Unity.Services.Qos.Runner.IQosJob>:SetResult (Unity.Services.Qos.Runner.IQosJob)
Unity.Services.Qos.Runner.BaselibQosRunner/<RunQosJob>d__7:MoveNext () (at ./Library/PackageCache/com.unity.services.qos@1.3.2/Runtime/Runner/BaselibQosRunner.cs:113)
UnityEngine.UnitySynchronizationContext:ExecuteTasks ()

Relay server started
UnityEngine.Debug:Log (object)
Utp.UtpServer:Start (uint16,bool,Unity.Services.Relay.Models.Allocation) (at Assets/314 Arts/MarsFPSKit/Required/UTPTransport/Utp/UtpServer.cs:345)
Utp.UtpTransport:ServerStart () (at Assets/314 Arts/MarsFPSKit/Required/UTPTransport/UtpTransport.cs:240)
Mirror.NetworkServer:Listen (int) (at Assets/Mirror/Core/NetworkServer.cs:149)
Mirror.NetworkManager:SetupServer () (at Assets/Mirror/Core/NetworkManager.cs:305)
Mirror.NetworkManager:StartHost () (at Assets/Mirror/Core/NetworkManager.cs:471)
MarsFPSKit.Services.Kit_TransportServiceUgsRelay/<>c__DisplayClass7_0:<StartHost>b__0 (string) (at Assets/314 Arts/MarsFPSKit/Scripts/Services/Kit_TransportServiceUgsRelay.cs:146)
Utp.RelayManager/<GetJoinCodeTask>d__23:MoveNext () (at Assets/314 Arts/MarsFPSKit/Required/UTPTransport/Relay/RelayManager.cs:176)
UnityEngine.SetupCoroutine:InvokeMoveNext (System.Collections.IEnumerator,intptr)

Server started listening
UnityEngine.Debug:Log (object)
Mirror.NetworkServer:Listen (int) (at Assets/Mirror/Core/NetworkServer.cs:165)
Mirror.NetworkManager:SetupServer () (at Assets/Mirror/Core/NetworkManager.cs:305)
Mirror.NetworkManager:StartHost () (at Assets/Mirror/Core/NetworkManager.cs:471)
MarsFPSKit.Services.Kit_TransportServiceUgsRelay/<>c__DisplayClass7_0:<StartHost>b__0 (string) (at Assets/314 Arts/MarsFPSKit/Scripts/Services/Kit_TransportServiceUgsRelay.cs:146)
Utp.RelayManager/<GetJoinCodeTask>d__23:MoveNext () (at Assets/314 Arts/MarsFPSKit/Required/UTPTransport/Relay/RelayManager.cs:176)
UnityEngine.SetupCoroutine:InvokeMoveNext (System.Collections.IEnumerator,intptr)

Server started. Loading map.
UnityEngine.Debug:Log (object)
MarsFPSKit.UI.Kit_MenuHostScreen:<StartSessionRoutine>b__35_0 () (at Assets/314 Arts/MarsFPSKit/Scripts/UI/New Main Menu/Kit_MenuHostScreen.cs:331)
UnityEngine.Events.UnityEvent:Invoke ()
MarsFPSKit.Kit_PlayerPlaceholder:OnStartLocalPlayer () (at Assets/314 Arts/MarsFPSKit/Scripts/Player/Kit_PlayerPlaceholder.cs:28)
Mirror.NetworkIdentity:OnStartLocalPlayer () (at Assets/Mirror/Core/NetworkIdentity.cs:826)
Mirror.NetworkClient:InvokeIdentityCallbacks (Mirror.NetworkIdentity) (at Assets/Mirror/Core/NetworkClient.cs:1414)
Mirror.NetworkClient:BootstrapIdentity (Mirror.NetworkIdentity) (at Assets/Mirror/Core/NetworkClient.cs:1380)
Mirror.NetworkClient:OnHostClientSpawn (Mirror.SpawnMessage) (at Assets/Mirror/Core/NetworkClient.cs:1372)
Mirror.NetworkClient/<>c__DisplayClass61_0`1<Mirror.SpawnMessage>:<RegisterHandler>g__HandlerWrapped|0 (Mirror.NetworkConnection,Mirror.SpawnMessage) (at Assets/Mirror/Core/NetworkClient.cs:544)
Mirror.NetworkMessages/<>c__DisplayClass9_0`2<Mirror.SpawnMessage, Mirror.NetworkConnection>:<WrapHandler>g__Wrapped|0 (Mirror.NetworkConnection,Mirror.SpawnMessage,int) (at Assets/Mirror/Core/NetworkMessages.cs:206)
Mirror.NetworkMessages/<>c__DisplayClass8_0`2<Mirror.SpawnMessage, Mirror.NetworkConnection>:<WrapHandler>b__0 (Mirror.NetworkConnection,Mirror.NetworkReader,int) (at Assets/Mirror/Core/NetworkMessages.cs:179)
Mirror.NetworkClient:UnpackAndInvoke (Mirror.NetworkReader,int) (at Assets/Mirror/Core/NetworkClient.cs:282)
Mirror.NetworkClient:OnTransportData (System.ArraySegment`1<byte>,int) (at Assets/Mirror/Core/NetworkClient.cs:358)
Mirror.LocalConnectionToServer:Update () (at Assets/Mirror/Core/LocalConnectionToServer.cs:70)
Mirror.NetworkClient:NetworkLateUpdate () (at Assets/Mirror/Core/NetworkClient.cs:1619)
Mirror.NetworkLoop:NetworkLateUpdate () (at Assets/Mirror/Core/NetworkLoop.cs:208)

Trying to load scene now: Test_Map_4
UnityEngine.Debug:Log (object)
MarsFPSKit.Kit_SceneSyncer:LoadScene (string,bool) (at Assets/314 Arts/MarsFPSKit/Scripts/GameLogic/Kit_SceneSyncer.cs:146)
MarsFPSKit.UI.Kit_MenuHostScreen:<StartSessionRoutine>b__35_0 () (at Assets/314 Arts/MarsFPSKit/Scripts/UI/New Main Menu/Kit_MenuHostScreen.cs:334)
UnityEngine.Events.UnityEvent:Invoke ()
MarsFPSKit.Kit_PlayerPlaceholder:OnStartLocalPlayer () (at Assets/314 Arts/MarsFPSKit/Scripts/Player/Kit_PlayerPlaceholder.cs:28)
Mirror.NetworkIdentity:OnStartLocalPlayer () (at Assets/Mirror/Core/NetworkIdentity.cs:826)
Mirror.NetworkClient:InvokeIdentityCallbacks (Mirror.NetworkIdentity) (at Assets/Mirror/Core/NetworkClient.cs:1414)
Mirror.NetworkClient:BootstrapIdentity (Mirror.NetworkIdentity) (at Assets/Mirror/Core/NetworkClient.cs:1380)
Mirror.NetworkClient:OnHostClientSpawn (Mirror.SpawnMessage) (at Assets/Mirror/Core/NetworkClient.cs:1372)
Mirror.NetworkClient/<>c__DisplayClass61_0`1<Mirror.SpawnMessage>:<RegisterHandler>g__HandlerWrapped|0 (Mirror.NetworkConnection,Mirror.SpawnMessage) (at Assets/Mirror/Core/NetworkClient.cs:544)
Mirror.NetworkMessages/<>c__DisplayClass9_0`2<Mirror.SpawnMessage, Mirror.NetworkConnection>:<WrapHandler>g__Wrapped|0 (Mirror.NetworkConnection,Mirror.SpawnMessage,int) (at Assets/Mirror/Core/NetworkMessages.cs:206)
Mirror.NetworkMessages/<>c__DisplayClass8_0`2<Mirror.SpawnMessage, Mirror.NetworkConnection>:<WrapHandler>b__0 (Mirror.NetworkConnection,Mirror.NetworkReader,int) (at Assets/Mirror/Core/NetworkMessages.cs:179)
Mirror.NetworkClient:UnpackAndInvoke (Mirror.NetworkReader,int) (at Assets/Mirror/Core/NetworkClient.cs:282)
Mirror.NetworkClient:OnTransportData (System.ArraySegment`1<byte>,int) (at Assets/Mirror/Core/NetworkClient.cs:358)
Mirror.LocalConnectionToServer:Update () (at Assets/Mirror/Core/LocalConnectionToServer.cs:70)
Mirror.NetworkClient:NetworkLateUpdate () (at Assets/Mirror/Core/NetworkClient.cs:1619)
Mirror.NetworkLoop:NetworkLateUpdate () (at Assets/Mirror/Core/NetworkLoop.cs:208)

[Camera] Changing camera parent to Spawn Camera Position
UnityEngine.Debug:Log (object,UnityEngine.Object)
MarsFPSKit.Kit_IngameMain:set_activeCameraTransform (UnityEngine.Transform) (at Assets/314 Arts/MarsFPSKit/Scripts/GameLogic/Kit_IngameMain.cs:210)
MarsFPSKit.Kit_IngameMain:OnStartServer () (at Assets/314 Arts/MarsFPSKit/Scripts/GameLogic/Kit_IngameMain.cs:835)
Mirror.NetworkIdentity:OnStartServer () (at Assets/Mirror/Core/NetworkIdentity.cs:711)
Mirror.NetworkServer:SpawnObject (UnityEngine.GameObject,Mirror.NetworkConnectionToClient) (at Assets/Mirror/Core/NetworkServer.cs:1641)
Mirror.NetworkServer:Spawn (UnityEngine.GameObject,Mirror.NetworkConnectionToClient) (at Assets/Mirror/Core/NetworkServer.cs:1563)
Mirror.NetworkServer:SpawnObjects () (at Assets/Mirror/Core/NetworkServer.cs:1518)
Mirror.NetworkManager:FinishLoadSceneHost () (at Assets/Mirror/Core/NetworkManager.cs:1039)
Mirror.NetworkManager:FinishLoadScene () (at Assets/Mirror/Core/NetworkManager.cs:985)
Mirror.NetworkManager:UpdateScene () (at Assets/Mirror/Core/NetworkManager.cs:963)
Mirror.NetworkManager:LateUpdate () (at Assets/Mirror/Core/NetworkManager.cs:257)

Requested switch from -1 to 0
UnityEngine.Debug:Log (object)
MarsFPSKit.Kit_IngameMain:SwitchMenu (int) (at Assets/314 Arts/MarsFPSKit/Scripts/GameLogic/Kit_IngameMain.cs:2622)
MarsFPSKit.UI.Kit_IngameMenuTeamSelection:Open () (at Assets/314 Arts/MarsFPSKit/Scripts/UI/New Main Menu/Kit_IngameMenuTeamSelection.cs:64)
MarsFPSKit.Kit_IngameMain:OnClientDataReadyToSetup () (at Assets/314 Arts/MarsFPSKit/Scripts/GameLogic/Kit_IngameMain.cs:1430)
MarsFPSKit.Kit_GameModeNetworkDataBase:OnStartClient () (at Assets/314 Arts/MarsFPSKit/Scripts/GameLogic/GameModes/Kit_GameModeNetworkDataBase.cs:43)
Mirror.NetworkIdentity:OnStartClient () (at Assets/Mirror/Core/NetworkIdentity.cs:757)
Mirror.NetworkClient:InvokeIdentityCallbacks (Mirror.NetworkIdentity) (at Assets/Mirror/Core/NetworkClient.cs:1407)
Mirror.NetworkClient:BootstrapIdentity (Mirror.NetworkIdentity) (at Assets/Mirror/Core/NetworkClient.cs:1380)
Mirror.NetworkClient:OnHostClientSpawn (Mirror.SpawnMessage) (at Assets/Mirror/Core/NetworkClient.cs:1372)
Mirror.NetworkClient/<>c__DisplayClass61_0`1<Mirror.SpawnMessage>:<RegisterHandler>g__HandlerWrapped|0 (Mirror.NetworkConnection,Mirror.SpawnMessage) (at Assets/Mirror/Core/NetworkClient.cs:544)
Mirror.NetworkMessages/<>c__DisplayClass9_0`2<Mirror.SpawnMessage, Mirror.NetworkConnection>:<WrapHandler>g__Wrapped|0 (Mirror.NetworkConnection,Mirror.SpawnMessage,int) (at Assets/Mirror/Core/NetworkMessages.cs:206)
Mirror.NetworkMessages/<>c__DisplayClass8_0`2<Mirror.SpawnMessage, Mirror.NetworkConnection>:<WrapHandler>b__0 (Mirror.NetworkConnection,Mirror.NetworkReader,int) (at Assets/Mirror/Core/NetworkMessages.cs:179)
Mirror.NetworkClient:UnpackAndInvoke (Mirror.NetworkReader,int) (at Assets/Mirror/Core/NetworkClient.cs:282)
Mirror.NetworkClient:OnTransportData (System.ArraySegment`1<byte>,int) (at Assets/Mirror/Core/NetworkClient.cs:358)
Mirror.LocalConnectionToServer:Update () (at Assets/Mirror/Core/LocalConnectionToServer.cs:70)
Mirror.NetworkClient:NetworkLateUpdate () (at Assets/Mirror/Core/NetworkClient.cs:1619)
Mirror.NetworkLoop:NetworkLateUpdate () (at Assets/Mirror/Core/NetworkLoop.cs:208)

[Kit_WeaponPickup] No Kit_WeaponPickupRespawnManager in parents.
UnityEngine.Debug:LogWarning (object)
Kit_WeaponPickup:Start () (at Assets/My/Scripts/Kit_WeaponPickup.cs:18)

Requested switch from 0 to 1. Force? True
UnityEngine.Debug:Log (object)
MarsFPSKit.Kit_IngameMain:SwitchMenu (int,bool) (at Assets/314 Arts/MarsFPSKit/Scripts/GameLogic/Kit_IngameMain.cs:2672)
MarsFPSKit.Kit_IngameMain:UserCode_TeamJoinGranted__NetworkConnection__SByte (Mirror.NetworkConnection,sbyte) (at Assets/314 Arts/MarsFPSKit/Scripts/GameLogic/Kit_IngameMain.cs:2059)
MarsFPSKit.Kit_IngameMain:InvokeUserCode_TeamJoinGranted__NetworkConnection__SByte (Mirror.NetworkBehaviour,Mirror.NetworkReader,Mirror.NetworkConnectionToClient)
Mirror.RemoteCalls.RemoteProcedureCalls:Invoke (uint16,Mirror.RemoteCalls.RemoteCallType,Mirror.NetworkReader,Mirror.NetworkBehaviour,Mirror.NetworkConnectionToClient) (at Assets/Mirror/Core/RemoteCalls.cs:133)
Mirror.NetworkIdentity:HandleRemoteCall (byte,uint16,Mirror.RemoteCalls.RemoteCallType,Mirror.NetworkReader,Mirror.NetworkConnectionToClient) (at Assets/Mirror/Core/NetworkIdentity.cs:245)
Mirror.NetworkClient:OnRPCMessage (Mirror.RpcMessage) (at Assets/Mirror/Core/NetworkClient.cs:1435)
Mirror.NetworkClient/<>c__DisplayClass61_0`1<Mirror.RpcMessage>:<RegisterHandler>g__HandlerWrapped|0 (Mirror.NetworkConnection,Mirror.RpcMessage) (at Assets/Mirror/Core/NetworkClient.cs:544)
Mirror.NetworkMessages/<>c__DisplayClass9_0`2<Mirror.RpcMessage, Mirror.NetworkConnection>:<WrapHandler>g__Wrapped|0 (Mirror.NetworkConnection,Mirror.RpcMessage,int) (at Assets/Mirror/Core/NetworkMessages.cs:206)
Mirror.NetworkMessages/<>c__DisplayClass8_0`2<Mirror.RpcMessage, Mirror.NetworkConnection>:<WrapHandler>b__0 (Mirror.NetworkConnection,Mirror.NetworkReader,int) (at Assets/Mirror/Core/NetworkMessages.cs:179)
Mirror.NetworkClient:UnpackAndInvoke (Mirror.NetworkReader,int) (at Assets/Mirror/Core/NetworkClient.cs:282)
Mirror.NetworkClient:OnTransportData (System.ArraySegment`1<byte>,int) (at Assets/Mirror/Core/NetworkClient.cs:358)
Mirror.LocalConnectionToServer:Update () (at Assets/Mirror/Core/LocalConnectionToServer.cs:70)
Mirror.NetworkClient:NetworkLateUpdate () (at Assets/Mirror/Core/NetworkClient.cs:1619)
Mirror.NetworkLoop:NetworkLateUpdate () (at Assets/Mirror/Core/NetworkLoop.cs:208)

Guest (325) ID: 0 Bot: False Team: 0 Kills: 0 Assists: 0 Deaths: 0 Ping: 0
UnityEngine.Debug:Log (object)
MarsFPSKit.Kit_IngameMain:UserCode_CmdRequestSpawn__Loadout__NetworkConnectionToClient (MarsFPSKit.Loadout,Mirror.NetworkConnectionToClient) (at Assets/314 Arts/MarsFPSKit/Scripts/GameLogic/Kit_IngameMain.cs:1808)
MarsFPSKit.Kit_IngameMain:InvokeUserCode_CmdRequestSpawn__Loadout__NetworkConnectionToClient (Mirror.NetworkBehaviour,Mirror.NetworkReader,Mirror.NetworkConnectionToClient)
Mirror.RemoteCalls.RemoteProcedureCalls:Invoke (uint16,Mirror.RemoteCalls.RemoteCallType,Mirror.NetworkReader,Mirror.NetworkBehaviour,Mirror.NetworkConnectionToClient) (at Assets/Mirror/Core/RemoteCalls.cs:133)
Mirror.NetworkIdentity:HandleRemoteCall (byte,uint16,Mirror.RemoteCalls.RemoteCallType,Mirror.NetworkReader,Mirror.NetworkConnectionToClient) (at Assets/Mirror/Core/NetworkIdentity.cs:245)
Mirror.NetworkServer:OnCommandMessage (Mirror.NetworkConnectionToClient,Mirror.CommandMessage,int) (at Assets/Mirror/Core/NetworkServer.cs:396)
Mirror.NetworkMessages/<>c__DisplayClass8_0`2<Mirror.CommandMessage, Mirror.NetworkConnectionToClient>:<WrapHandler>b__0 (Mirror.NetworkConnection,Mirror.NetworkReader,int) (at Assets/Mirror/Core/NetworkMessages.cs:179)
Mirror.NetworkServer:UnpackAndInvoke (Mirror.NetworkConnectionToClient,Mirror.NetworkReader,int) (at Assets/Mirror/Core/NetworkServer.cs:742)
Mirror.NetworkServer:OnTransportData (int,System.ArraySegment`1<byte>,int) (at Assets/Mirror/Core/NetworkServer.cs:813)
Mirror.LocalConnectionToClient:Update () (at Assets/Mirror/Core/LocalConnectionToClient.cs:57)
Mirror.NetworkServer:Broadcast () (at Assets/Mirror/Core/NetworkServer.cs:2029)
Mirror.NetworkServer:NetworkLateUpdate () (at Assets/Mirror/Core/NetworkServer.cs:2080)
Mirror.NetworkLoop:NetworkLateUpdate () (at Assets/Mirror/Core/NetworkLoop.cs:207)

Requested switch from 1 to 2. Force? True
UnityEngine.Debug:Log (object)
MarsFPSKit.Kit_IngameMain:SwitchMenu (int,bool) (at Assets/314 Arts/MarsFPSKit/Scripts/GameLogic/Kit_IngameMain.cs:2672)
MarsFPSKit.Kit_PlayerBehaviour/<LocalPlayerRoutine>d__54:MoveNext () (at Assets/314 Arts/MarsFPSKit/Scripts/Player/Kit_PlayerBehaviour.cs:350)
UnityEngine.MonoBehaviour:StartCoroutine (System.Collections.IEnumerator)
MarsFPSKit.Kit_PlayerBehaviour:OnStartLocalPlayer () (at Assets/314 Arts/MarsFPSKit/Scripts/Player/Kit_PlayerBehaviour.cs:645)
Mirror.NetworkIdentity:OnStartLocalPlayer () (at Assets/Mirror/Core/NetworkIdentity.cs:826)
Mirror.NetworkClient:InvokeIdentityCallbacks (Mirror.NetworkIdentity) (at Assets/Mirror/Core/NetworkClient.cs:1414)
Mirror.NetworkClient:BootstrapIdentity (Mirror.NetworkIdentity) (at Assets/Mirror/Core/NetworkClient.cs:1380)
Mirror.NetworkClient:OnHostClientSpawn (Mirror.SpawnMessage) (at Assets/Mirror/Core/NetworkClient.cs:1372)
Mirror.NetworkClient/<>c__DisplayClass61_0`1<Mirror.SpawnMessage>:<RegisterHandler>g__HandlerWrapped|0 (Mirror.NetworkConnection,Mirror.SpawnMessage) (at Assets/Mirror/Core/NetworkClient.cs:544)
Mirror.NetworkMessages/<>c__DisplayClass9_0`2<Mirror.SpawnMessage, Mirror.NetworkConnection>:<WrapHandler>g__Wrapped|0 (Mirror.NetworkConnection,Mirror.SpawnMessage,int) (at Assets/Mirror/Core/NetworkMessages.cs:206)
Mirror.NetworkMessages/<>c__DisplayClass8_0`2<Mirror.SpawnMessage, Mirror.NetworkConnection>:<WrapHandler>b__0 (Mirror.NetworkConnection,Mirror.NetworkReader,int) (at Assets/Mirror/Core/NetworkMessages.cs:179)
Mirror.NetworkClient:UnpackAndInvoke (Mirror.NetworkReader,int) (at Assets/Mirror/Core/NetworkClient.cs:282)
Mirror.NetworkClient:OnTransportData (System.ArraySegment`1<byte>,int) (at Assets/Mirror/Core/NetworkClient.cs:358)
Mirror.LocalConnectionToServer:Update () (at Assets/Mirror/Core/LocalConnectionToServer.cs:70)
Mirror.NetworkClient:NetworkLateUpdate () (at Assets/Mirror/Core/NetworkClient.cs:1619)
Mirror.NetworkLoop:NetworkLateUpdate () (at Assets/Mirror/Core/NetworkLoop.cs:208)

[Camera] Changing camera parent to CameraGO
UnityEngine.Debug:Log (object,UnityEngine.Object)
MarsFPSKit.Kit_IngameMain:set_activeCameraTransform (UnityEngine.Transform) (at Assets/314 Arts/MarsFPSKit/Scripts/GameLogic/Kit_IngameMain.cs:210)
MarsFPSKit.Kit_PlayerBehaviour/<LocalPlayerRoutine>d__54:MoveNext () (at Assets/314 Arts/MarsFPSKit/Scripts/Player/Kit_PlayerBehaviour.cs:353)
UnityEngine.SetupCoroutine:InvokeMoveNext (System.Collections.IEnumerator,intptr)

Requested switch from 2 to 1. Force? True
UnityEngine.Debug:Log (object)
MarsFPSKit.Kit_IngameMain:SwitchMenu (int,bool) (at Assets/314 Arts/MarsFPSKit/Scripts/GameLogic/Kit_IngameMain.cs:2672)
MarsFPSKit.Kit_IngameMain:Update () (at Assets/314 Arts/MarsFPSKit/Scripts/GameLogic/Kit_IngameMain.cs:587)

Requested switch from 1 to 2. Force? True
UnityEngine.Debug:Log (object)
MarsFPSKit.Kit_IngameMain:SwitchMenu (int,bool) (at Assets/314 Arts/MarsFPSKit/Scripts/GameLogic/Kit_IngameMain.cs:2672)
MarsFPSKit.Kit_IngameMain:Update () (at Assets/314 Arts/MarsFPSKit/Scripts/GameLogic/Kit_IngameMain.cs:600)

cant pickup the weapon
ASSISTANT
From your logs and errors, the main issue is:

- **`Kit_WeaponPickupRespawnManager` is not found in your `Kit_WeaponPickup` parents** (see the warning: `[Kit_WeaponPickup] No Kit_WeaponPickupRespawnManager in parents.`), so the pickup can't notify the respawner.
- Your pickup logic calls `TryGiveOrRefillWeapon` but likely returns false, meaning the weapon is not given.
- You also indicated "can't pickup the weapon," so the core weapon granting logic is not working.

---

# How to fix and fully enable weapon pickups in MMFPSE

---

## 1. **Setup Respawn Manager Parenting**

Make sure your weapon pickup prefab instance is a **child (or descendant) of an active GameObject with the `Kit_WeaponPickupRespawnManager`** component**. This is essential because your pickup script tries to `GetComponentInParent<Kit_WeaponPickupRespawnManager>()`.

- If your pickup prefab is spawned dynamically, ensure it is parented under the respawn manager GameObject.
- Alternatively, in `Kit_WeaponPickup`, add a serialized field and manually assign the respawn manager reference instead of auto-search.

Example modification:

```csharp
public class Kit_WeaponPickup : MonoBehaviour
{
    [SerializeField] private Kit_WeaponPickupRespawnManager respawnManager;

    // In editor, assign respawn manager manually if auto-search fails
    private void Start()
    {
        if (respawnManager == null)
        {
            respawnManager = GetComponentInParent<Kit_WeaponPickupRespawnManager>();
            if (respawnManager == null)
                Debug.LogWarning("[Kit_WeaponPickup] No Kit_WeaponPickupRespawnManager in parents or assigned reference.");
        }
    }

    // ...
}
```

---

## 2. **Implement Actual Weapon Granting Logic**

The `TryGiveWeapon` method is a stub. Since your pickup never grants the weapon, pickup always fails.

You MUST implement that logic exactly according to your MMFPSE weapon manager API.

---

### Sample implementation hints (based on MMFPSE typical usage):

From the logs and code, these are typical methods you might find:

- `Kit_ModernWeaponManager.HasWeapon(Kit_PlayerBehaviour player, int weaponID)` returns slot index or -1.
- To add a weapon, something like `Kit_ModernWeaponManager.TryGiveWeapon(Kit_PlayerBehaviour player, int id, bool selectImmediately)` might exist.
- Ammo refill could be managed internally by the weapon manager or via methods on weapon instances.

---

### Here's an improved `TryGiveWeapon` example assuming such API:

```csharp
private bool TryGiveWeapon(Kit_ModernWeaponManager wpnManager, Kit_PlayerBehaviour player, int weaponID)
{
    // Check if method exists, otherwise replace with your actual MMFPSE method
    try
    {
        // Assuming a method like this exists.
        bool result = wpnManager.TryGiveWeapon(player, weaponID, true /*selectImmediately*/);

        if(result)
        {
            Debug.Log("[Kit_WeaponPickup] Weapon granted successfully.");
        }
        else
        {
            Debug.LogWarning("[Kit_WeaponPickup] Weapon granting failed.");
        }

        return result;
    }
    catch (System.Exception e)
    {
        Debug.LogError("[Kit_WeaponPickup] Error while trying to give weapon: " + e);
        return false;
    }
}
```

If that exact method name does not exist, **search your MMFPSE scripts** for a public method in `Kit_ModernWeaponManager` that gives a weapon to a player and matches this purpose.

---

## 3. **Testing With Debug Logs**

Add debug prints to ensure:

- The player collider triggers pickup.
- `HasWeapon` returns expected values.
- `TryGiveWeapon` executes and returns true.
- `PickupTaken()` in `respawnManager` gets called.

---

## 4. **Example Full Working Pickup Script (simplified)**

```csharp
using UnityEngine;
using MarsFPSKit;
using MarsFPSKit.Weapons;

public class Kit_WeaponPickup : MonoBehaviour
{
    [SerializeField] private Kit_WeaponPickupRespawnManager respawnManager;
    public int weaponID = 1;

    private void Start()
    {
        if (respawnManager == null)
        {
            respawnManager = GetComponentInParent<Kit_WeaponPickupRespawnManager>();
            if (respawnManager == null)
                Debug.LogWarning("[Kit_WeaponPickup] No Kit_WeaponPickupRespawnManager found.");
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        if (!other.CompareTag("Player")) return;

        var player = other.GetComponent<Kit_PlayerBehaviour>();
        if (player == null) return;

        var wpnManager = player.weaponManager as Kit_ModernWeaponManager;
        if (wpnManager == null) 
        {
            Debug.LogWarning("[Kit_WeaponPickup] Player's weaponManager not of expected type.");
            return;
        }

        int slot = wpnManager.HasWeapon(player, weaponID);

        if (slot != -1)
        {
            Debug.Log("[Kit_WeaponPickup] Player already has weapon, consider ammo refill (implement if needed).");
            // Optional: implement ammo refill here if your MMFPSE API supports
        }
        else
        {
            bool given = false;
            try
            {
                // Replace TryGiveWeapon call with your exact MMFPSE method
                given = wpnManager.TryGiveWeapon(player, weaponID, true);
                Debug.Log(given ? "[Kit_WeaponPickup] Weapon granted." : "[Kit_WeaponPickup] Weapon grant failed.");
            }
            catch (System.Exception e)
            {
                Debug.LogError("[Kit_WeaponPickup] Exception when giving weapon: " + e);
            }

            if (!given) return; // Early out if failed to give weapon
        }

        if (respawnManager != null)
        {
            respawnManager.PickupTaken();
        }
        else
        {
            Debug.LogWarning("[Kit_WeaponPickup] Respawn manager missing, cannot schedule respawn.");
        }
    }
}
```

---

# Summary

- **Make sure your pickup prefab is parented under or assigned a reference to the respawn manager.**
- **Implement or call the actual MMFPSE weapon giving method—your stub won't work.**
- **Test with logs to confirm each step triggers.**
- **Modify the ammo refill logic with your specific MMFPSE API.**

---

If you want, **share your `Kit_ModernWeaponManager` class or related method names/signatures**, and I can help write the exact method call for `TryGiveWeapon` or ammo refill you need!

turns-00083.parquet:31605

1c3914ec27d951f74fb4707c
turn 11/19gpt-4.1-mini-2025-04-14EnglishCroatia415 words
degenerate_repetitionAbsentFinal dense release
USER
Assets\My\Scripts\Kit_WeaponPickup.cs(47,36): error CS1061: 'Kit_ModernWeaponManager' does not contain a definition for 'TryGiveWeapon' and no accessible extension method 'TryGiveWeapon' accepting a first argument of type 'Kit_ModernWeaponManager' could be found (are you missing a using directive or an assembly reference?)
ASSISTANT
The error:
```
'Kit_ModernWeaponManager' does not contain a definition for 'TryGiveWeapon'
```
means that the `Kit_ModernWeaponManager` class you're using **does not have a method named `TryGiveWeapon`**.

---

### How to proceed:

Since this function is missing, **you need to find the correct method in your MMFPSE's `Kit_ModernWeaponManager` that adds or equips a weapon to a player**.

---

### Steps:

1. **Search your code for weapon-giving methods.**

   Open your `Kit_ModernWeaponManager` script and look for **public methods** that:

   - Take a player and weapon ID.
   - Add or equip a weapon.

   Common method names might include:

   - `AddWeapon(...)`
   - `GiveWeapon(...)`
   - `EquipWeapon(...)`
   - `SetWeapon(...)`
   - `LoadWeapon(...)`

2. **Check usage in example scenes or other scripts.**

   MMFPSE may already have example code that calls these methods.

3. **If none exist, the weapon manager might expect you to modify network values directly, or spawn weapon GameObjects manually.**

---

### Example: Implementing `TryGiveWeapon` correctly

Assuming you find a method in `Kit_ModernWeaponManager` named, for example, `AddWeapon(Kit_PlayerBehaviour player, int weaponID)` returning `bool` or `void`, you would do:

```csharp
private bool TryGiveWeapon(Kit_ModernWeaponManager wpnManager, Kit_PlayerBehaviour player, int weaponID)
{
    // Adjust this line to your exact method signature
    // Example:
    wpnManager.AddWeapon(player, weaponID);

    // If AddWeapon returns void, just return true as granted
    return true;
}
```

---

### If you don't know the method, **ask or search for these keywords**

Open `Kit_ModernWeaponManager.cs` file and search for:

- `public bool`
- `public void`
- `Give`
- `AddWeapon`
- `Equip`
- `Load`

---

### If you can share that part of the `Kit_ModernWeaponManager` class or a public API for weapon management, I can help you write the exact call.

---

### Meanwhile, use this stub to avoid errors but show a warning:

```csharp
private bool TryGiveWeapon(Kit_ModernWeaponManager wpnManager, Kit_PlayerBehaviour player, int weaponID)
{
    Debug.LogWarning("[Kit_WeaponPickup] TryGiveWeapon not implemented. Please replace this with your MMFPSE weapon add method.");
    return false; // Return false to prevent pickup success until implemented
}
```

---

### Summary:

- `TryGiveWeapon` is not part of your current API.
- Find your actual weapon granting method.
- Replace the stub with the real method call.
- Share that function or API if you want me to help write it.

---

If you send me your `Kit_ModernWeaponManager` class or related code snippets, I can help you implement it properly.

turns-00083.parquet:31606

b1a686255157f0cfccbb30a0
turn 12/19gpt-4.1-mini-2025-04-14EnglishCroatia5231 words
degenerate_repetitionAbsentFinal dense release
USER
search by yourself and fix all to be compatible:

using Mirror;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using UnityEngine;

namespace MarsFPSKit
{
    namespace Weapons
    {
        /// <summary>
        /// Input that is allowed for the given weapon slot
        /// </summary>
        [System.Serializable]
        public class WeaponManagerSlot
        {
            /// <summary>
            /// Can weapons in this slot be equipped?
            /// </summary>
            public bool enableEquipping = true;
            /// <summary>
            /// ID of <see cref="Kit_PlayerInput.weaponSlotUses"/>
            /// </summary>
            public int equippingInputID;
            /// <summary>
            /// Can weapons in this slot be quick used (e.g. quick grenades, quick knife)
            /// </summary>
            public bool enableQuickUse;
            /// <summary>
            /// ID of <see cref="Kit_PlayerInput.weaponSlotUses"/>
            /// </summary>
            public int quickUseInputID;
        }

        public enum DeadDrop { None, Selected, All }

        /// <summary>
        /// This is a modern, generic weapon manager. Weapons are put away and then taken out, like in COD or Battlefield. Supports an "infinite" amount of weapons
        /// </summary>
        [CreateAssetMenu(menuName = ("MarsFPSKit/Weapons/Modern Weapon Manager"))]
        public class Kit_ModernWeaponManager : Kit_WeaponManagerBase
        {
            public WeaponManagerSlot[] slotConfiguration;
            /// <summary>
            /// Main drop prefab!
            /// </summary>
            public GameObject dropPrefab;
            /// <summary>
            /// Layers that will be hit by the pickup raycast
            /// </summary>
            public LayerMask pickupLayers;
            /// <summary>
            /// Distance for the pickup raycast
            /// </summary>
            public float pickupDistance = 3f;
            /// <summary>
            /// Which weapons should be dropped upon death?
            /// </summary>
            public DeadDrop uponDeathDrop;
            /// <summary>
            /// How fast does the weapon position change?
            /// </summary>
            public float weaponPositionChangeSpeed = 5f;
            /// <summary>
            /// Can we switch while we are running?
            /// </summary>
            public bool allowSwitchingWhileRunning;
            /// <summary>
            /// Can we do quick use while running?
            /// </summary>
            public bool allowQuickUseWhileRunning;

            public override void OnWeaponsInUseSyncCallback(Kit_PlayerBehaviour pb, SyncList<uint>.Operation op, int itemIndex, uint item)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;

                switch (op)
                {
                    case SyncList<uint>.Operation.OP_SET:
                        //Cleanup old data first
                        for (int i = 0; i < runtimeData.weaponsInUseDataObjects[itemIndex].instantiatedObjects.Count; i++)
                        {
                            if (runtimeData.weaponsInUseDataObjects[itemIndex].instantiatedObjects[i])
                            {
                                NetworkIdentity nid = runtimeData.weaponsInUseDataObjects[itemIndex].instantiatedObjects[i].GetComponentInChildren<NetworkIdentity>();

                                if (nid)
                                {
                                    if (NetworkServer.active)
                                    {
                                        NetworkServer.Destroy(nid.gameObject);
                                    }
                                }
                                else
                                {
                                    Destroy(runtimeData.weaponsInUseDataObjects[itemIndex].instantiatedObjects[i]);
                                }
                            }
                        }

                        runtimeData.weaponsInUseDataObjects[itemIndex].instantiatedObjects.Clear();

                        //We may need to wait a bit for the network
                        Kit_ScriptableObjectCoroutineHelper.instance.StartCoroutine(Kit_ScriptableObjectCoroutineHelper.instance.NetworkReplaceWeapon(pb, runtimeData, itemIndex, runtimeData.weaponsInUseSync[itemIndex]));
                        break;
                }
            }

            public override void SetupSpawnData(Kit_PlayerBehaviour pb, Loadout loadout, NetworkConnectionToClient sender)
            {
                GameObject data = Instantiate(networkData, Vector3.zero, Quaternion.identity);
                Kit_ModernWeaponManagerNetworkData runtimeData = data.GetComponent<Kit_ModernWeaponManagerNetworkData>();
                pb.weaponManagerNetworkData = runtimeData;

                for (int i = 0; i < loadout.loadoutWeapons.Length; i++)
                {
                    GameObject spawnObject = Kit_IngameMain.instance.gameInformation.allWeapons[loadout.loadoutWeapons[i].weaponID].SetupSpawnData(pb, i, loadout.loadoutWeapons[i]);
                    NetworkServer.Spawn(spawnObject, sender);
                    NetworkIdentity id = spawnObject.GetComponent<NetworkIdentity>();

                    //Add to our weapon list
                    runtimeData.weaponsInUseSync.Add(id.netId);
                }
            }

            public override void SetupSpawnData(Kit_PlayerBehaviour pb, Loadout loadout)
            {
                GameObject data = Instantiate(networkData, Vector3.zero, Quaternion.identity);
                Kit_ModernWeaponManagerNetworkData runtimeData = data.GetComponent<Kit_ModernWeaponManagerNetworkData>();
                pb.weaponManagerNetworkData = runtimeData;

                for (int i = 0; i < loadout.loadoutWeapons.Length; i++)
                {
                    GameObject spawnObject = Kit_IngameMain.instance.gameInformation.allWeapons[loadout.loadoutWeapons[i].weaponID].SetupSpawnData(pb, i, loadout.loadoutWeapons[i]);
                    NetworkServer.Spawn(spawnObject);
                    NetworkIdentity id = spawnObject.GetComponent<NetworkIdentity>();

                    //Add to our weapon list
                    runtimeData.weaponsInUseSync.Add(id.netId);
                }
            }

            public override void InitializeServer(Kit_PlayerBehaviour pb)
            {
                //Is created in SetupSpawnData
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                runtimeData.ownerPlayerNetworkId = pb.netId;
                //Spawn it here
                if (pb.isBot)
                    NetworkServer.Spawn(runtimeData.gameObject);
                else
                    NetworkServer.Spawn(runtimeData.gameObject, pb.gameObject);

                //Setup input IDs
                runtimeData.lastInputIDs = new bool[pb.input.weaponSlotUses.Length];

                //Initially build list
                runtimeData.weaponsInUseDataObjects = new Kit_WeaponRuntimeDataBase[runtimeData.weaponsInUseSync.Count];

                for (int i = 0; i < runtimeData.weaponsInUseSync.Count; i++)
                {
                    NetworkIdentity id = null;

                    if (NetworkServer.active)
                    {
                        id = NetworkServer.spawned[runtimeData.weaponsInUseSync[i]];
                    }
                    else
                    {
                        id = NetworkClient.spawned[runtimeData.weaponsInUseSync[i]];
                    }

                    if (id)
                    {
                        runtimeData.weaponsInUseDataObjects[i] = id.GetComponent<Kit_WeaponRuntimeDataBase>();
                    }
                    else
                    {
                        //Didn't find it. This shouldn't happen!
                        runtimeData.weaponsInUseDataObjects[i] = null;
                    }
                }

                for (int i = 0; i < runtimeData.weaponsInUseDataObjects.Length; i++)
                {
                    int slot = i;
                    int id = runtimeData.weaponsInUseDataObjects[slot].id;
                    //Get their behaviour modules
                    Kit_WeaponBase weaponBehaviour = pb.gameInformation.allWeapons[id];
                    //Assign Behaviour
                    runtimeData.weaponsInUseDataObjects[slot].behaviour = weaponBehaviour;
                    runtimeData.weaponsInUseDataObjects[slot].pb = pb;
                    //Setup FP
                    weaponBehaviour.SetupFirstPerson(pb, runtimeData.weaponsInUseDataObjects[slot]);
                    //Setup TP
                    weaponBehaviour.SetupThirdPerson(pb, runtimeData.weaponsInUseDataObjects[slot]);
                }

                SelectDefaultWeapon(pb, runtimeData);

                //Set time
                runtimeData.switchNextEnd = Time.time + runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.drawTime;
                //Set phase
                runtimeData.switchPhase = 1;
                //Set switching
                runtimeData.switchInProgress = true;
            }

            public override void InitializeClient(Kit_PlayerBehaviour pb)
            {
                if (!pb.weaponManagerNetworkData)
                {
                    //Find ours
                    pb.weaponManagerNetworkData = FindObjectsOfType<Kit_ModernWeaponManagerNetworkData>().Where(x => x.ownerPlayerNetworkId == pb.netId).FirstOrDefault();
                }

                if (pb.isClientOnly)
                {
                    Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;

                    //Setup input IDs
                    runtimeData.lastInputIDs = new bool[pb.input.weaponSlotUses.Length];

                    //Initially build list
                    runtimeData.weaponsInUseDataObjects = new Kit_WeaponRuntimeDataBase[runtimeData.weaponsInUseSync.Count];

                    for (int i = 0; i < runtimeData.weaponsInUseSync.Count; i++)
                    {
                        NetworkIdentity id = null;

                        if (NetworkServer.active)
                        {
                            id = NetworkServer.spawned[runtimeData.weaponsInUseSync[i]];
                        }
                        else
                        {
                            id = NetworkClient.spawned[runtimeData.weaponsInUseSync[i]];
                        }

                        if (id)
                        {
                            runtimeData.weaponsInUseDataObjects[i] = id.GetComponent<Kit_WeaponRuntimeDataBase>();
                        }
                        else
                        {
                            //Didn't find it. This shouldn't happen!
                            runtimeData.weaponsInUseDataObjects[i] = null;
                        }
                    }

                    for (int i = 0; i < runtimeData.weaponsInUseDataObjects.Length; i++)
                    {
                        int slot = i;
                        int id = runtimeData.weaponsInUseDataObjects[slot].id;
                        //Get their behaviour modules
                        Kit_WeaponBase weaponBehaviour = pb.gameInformation.allWeapons[id];
                        //Assign Behaviour
                        runtimeData.weaponsInUseDataObjects[slot].behaviour = weaponBehaviour;
                        runtimeData.weaponsInUseDataObjects[slot].pb = pb;
                        //Setup FP
                        weaponBehaviour.SetupFirstPerson(pb, runtimeData.weaponsInUseDataObjects[slot]);
                        //Setup TP
                        weaponBehaviour.SetupThirdPerson(pb, runtimeData.weaponsInUseDataObjects[slot]);
                    }

                    SelectDefaultWeapon(pb, runtimeData);

                    //Set time
                    runtimeData.switchNextEnd = Time.time + runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.drawTime;
                    //Set phase
                    runtimeData.switchPhase = 1;
                    //Set switching
                    runtimeData.switchInProgress = true;
                }
            }

            /// <summary>
            /// Selects the first weapon
            /// </summary>
            /// <param name="pb"></param>
            /// <param name="runtimeData"></param>
            void SelectDefaultWeapon(Kit_PlayerBehaviour pb, Kit_ModernWeaponManagerNetworkData runtimeData)
            {
                //Select default weapon
                for (int i = 0; i < runtimeData.weaponsInUseDataObjects.Length; i++)
                {
                    if (i < slotConfiguration.Length && slotConfiguration[i].enableEquipping)
                    {
                        if (runtimeData.weaponsInUseDataObjects[i].behaviour.CanBeSelected(pb, runtimeData.weaponsInUseDataObjects[i]))
                        {
                            int id = i;
                            //Select current weapon
                            runtimeData.weaponsInUseDataObjects[i].behaviour.DrawWeapon(pb, runtimeData.weaponsInUseDataObjects[i]);
                            //Play Third person animation
                            pb.thirdPersonPlayerModel.PlayWeaponChangeAnimation(runtimeData.weaponsInUseDataObjects[i].behaviour.thirdPersonAnimType, true, runtimeData.weaponsInUseDataObjects[i].behaviour.drawTime);
                            //Set current weapon
                            runtimeData.desiredWeapon = runtimeData.currentWeapon = id;
                            return;
                        }

                    }
                }
            }

            public override void TakeControl(Kit_PlayerBehaviour pb)
            {
                //Hide crosshair
                Kit_IngameMain.instance.hud.DisplayCrosshair(0f, false);

            }

            public override void ForceUnselectCurrentWeapon(Kit_PlayerBehaviour pb)
            {
                Debug.Log("[Weapon Manager] Forcing unselect of current weapon!");
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                bool foundWeapon = false;
                //Try to find next weapon
                int next = -1;
                for (int i = 0; i < runtimeData.weaponsInUseDataObjects.Length; i++)
                {
                    if (foundWeapon) break;


                    if (!runtimeData.weaponsInUseDataObjects[i].isInjectedFromPlugin)
                    {
                        //Check if this one works!
                        if (runtimeData.weaponsInUseDataObjects[i].behaviour.CanBeSelected(pb, runtimeData.weaponsInUseDataObjects[i]))
                        {
                            int id = i;
                            next = id;
                            //We found one
                            foundWeapon = true;
                            break;
                        }
                    }

                }

                //This should ALWAYS be true!
                if (next >= 0)
                {
                    runtimeData.desiredWeapon = next;
                    //Begin switch and skip putaway
                    runtimeData.switchInProgress = true;
                    //Set time (Because here we cannot use a coroutine)
                    runtimeData.switchNextEnd = 0f;
                    //Set phase
                    runtimeData.switchPhase = 0;
                    if (pb.isFirstPersonActive)
                    {
                        //Hide crosshair
                        Kit_IngameMain.instance.hud.DisplayCrosshair(0f, false);
                    }
                    //Set current one too!
                    runtimeData.currentWeapon = next;
                }
                else
                {
                    Debug.LogError("Could not find next weapon! This is not allowed!");
                }
            }

            public override void AuthorativeInput(Kit_PlayerBehaviour pb, Kit_PlayerInput input, float delta, double revertTime)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;

                if (!runtimeData.isDesiredWeaponLocked)
                {
                    for (int i = 0; i < runtimeData.weaponsInUseDataObjects.Length; i++)
                    {
                        if (!runtimeData.weaponsInUseDataObjects[i].isInjectedFromPlugin)
                        {
                            if (slotConfiguration.Length > i)
                            {
                                if (slotConfiguration[i].enableEquipping && slotConfiguration[i].equippingInputID >= 0 && !runtimeData.quickUseInProgress)
                                {
                                    if (runtimeData.lastInputIDs[slotConfiguration[i].equippingInputID] != input.weaponSlotUses[slotConfiguration[i].equippingInputID])
                                    {
                                        runtimeData.lastInputIDs[slotConfiguration[i].equippingInputID] = input.weaponSlotUses[slotConfiguration[i].equippingInputID];
                                        //Check for input
                                        if (input.weaponSlotUses[slotConfiguration[i].equippingInputID] && (allowSwitchingWhileRunning || !pb.movement.IsRunning(pb)))
                                        {
                                            int id = i;
                                            if (runtimeData.desiredWeapon != id)
                                            {
                                                if (runtimeData.weaponsInUseDataObjects[i].behaviour.CanBeSelected(pb, runtimeData.weaponsInUseDataObjects[i]))
                                                {
                                                    runtimeData.desiredWeapon = id;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }

                    if (input.nextWeapon)
                    {
                        int nextWeapon = runtimeData.desiredWeapon + 1;
                        if (nextWeapon >= runtimeData.weaponsInUseSync.Count) nextWeapon = 0;
                        while (runtimeData.weaponsInUseDataObjects[nextWeapon].isInjectedFromPlugin || !runtimeData.weaponsInUseDataObjects[nextWeapon].behaviour.CanBeSelected(pb, runtimeData.weaponsInUseDataObjects[nextWeapon]))
                        {
                            nextWeapon++;
                            if (nextWeapon >= runtimeData.weaponsInUseSync.Count) nextWeapon = 0;
                        }

                        runtimeData.desiredWeapon = nextWeapon;
                    }
                    else if (input.previousWeapon)
                    {
                        int previousWeapon = runtimeData.desiredWeapon - 1;
                        if (previousWeapon < 0) previousWeapon = runtimeData.weaponsInUseDataObjects.Length - 1;
                        while (runtimeData.weaponsInUseDataObjects[previousWeapon].isInjectedFromPlugin || !runtimeData.weaponsInUseDataObjects[previousWeapon].behaviour.CanBeSelected(pb, runtimeData.weaponsInUseDataObjects[previousWeapon]))
                        {
                            previousWeapon--;
                            if (previousWeapon < 0) previousWeapon = runtimeData.weaponsInUseDataObjects.Length - 1;
                        }

                        runtimeData.desiredWeapon = previousWeapon;
                    }

                    //Check if we can do a quick use!
                    if (runtimeData.currentWeapon == runtimeData.desiredWeapon && !runtimeData.switchInProgress)
                    {
                        if (!runtimeData.quickUseInProgress)
                        {
                            for (int i = 0; i < runtimeData.weaponsInUseDataObjects.Length; i++)
                            {
                                if (!runtimeData.weaponsInUseDataObjects[i].isInjectedFromPlugin)
                                {
                                    int slot = i;
                                    if (slotConfiguration.Length > slot)
                                    {
                                        if (slotConfiguration[slot].enableQuickUse)
                                        {
                                            if (slotConfiguration[slot].quickUseInputID >= 0)
                                            {
                                                if (runtimeData.lastInputIDs[slotConfiguration[slot].quickUseInputID] != input.weaponSlotUses[slotConfiguration[slot].quickUseInputID])
                                                {
                                                    runtimeData.lastInputIDs[slotConfiguration[slot].quickUseInputID] = input.weaponSlotUses[slotConfiguration[slot].quickUseInputID];
                                                    //Check for input
                                                    if (input.weaponSlotUses[slotConfiguration[slot].quickUseInputID] && (allowQuickUseWhileRunning || !pb.movement.IsRunning(pb)))
                                                    {
                                                        if (runtimeData.weaponsInUseDataObjects[slot].behaviour.SupportsQuickUse(pb, runtimeData.weaponsInUseDataObjects[slot]))
                                                        {
                                                            runtimeData.desiredQuickUse = slot;
                                                            runtimeData.quickUseInProgress = true;
                                                            //Also reset these!
                                                            runtimeData.quickUseState = 0;
                                                            runtimeData.quickUseOverAt = Time.time;
                                                            break;
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            if (runtimeData.quickUseState == 2)
                            {
                                //Check if quick use button needs to be released
                                if (runtimeData.weaponsInUseDataObjects[runtimeData.desiredQuickUse].behaviour.WaitForQuickUseButtonRelease(pb, runtimeData.weaponsInUseDataObjects[runtimeData.desiredQuickUse]) && (!pb.input.weaponSlotUses[slotConfiguration[runtimeData.desiredQuickUse].quickUseInputID]))
                                {
                                    runtimeData.quickUseSyncButtonWaitOver = true;
                                }
                            }
                        }
                    }
                }

                if (!runtimeData.switchInProgress && !runtimeData.quickUseInProgress)
                {
                    runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.AuthorativeInput(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon], input, delta, revertTime);
                }
            }

            public override void PredictionInput(Kit_PlayerBehaviour pb, Kit_PlayerInput input, float delta)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;

                AuthorativeInput(pb, input, delta, 0f);


                if (Physics.Raycast(pb.playerCameraTransform.position, pb.playerCameraTransform.forward, out runtimeData.hit, pickupDistance, pickupLayers.value))
                {
                    if (runtimeData.hit.transform.root.GetComponent<Kit_DropBehaviour>())
                    {
                        Kit_DropBehaviour drop = runtimeData.hit.transform.root.GetComponent<Kit_DropBehaviour>();
                        if (pb.isFirstPersonActive)
                        {
                            Kit_IngameMain.instance.hud.DisplayWeaponPickup(true, drop.weaponID);
                            Kit_IngameMain.instance.hud.DisplayInteraction(false);
                        }

                        if (runtimeData.lastInteract != input.interact)
                        {
                            runtimeData.lastInteract = input.interact;
                            if (input.interact && (allowSwitchingWhileRunning || !pb.movement.IsRunning(pb)))
                            {
                                drop.CmdTryPickUp();
                            }
                        }
                    }
                    else if (runtimeData.hit.transform.GetComponentInParent<Kit_InteractableObject>())
                    {
                        Kit_InteractableObject io = runtimeData.hit.transform.GetComponentInParent<Kit_InteractableObject>();

                        if (io.CanInteract(pb))
                        {
                            if (pb.isFirstPersonActive)
                            {
                                Kit_IngameMain.instance.hud.DisplayWeaponPickup(false);
                                Kit_IngameMain.instance.hud.DisplayInteraction(true, io.interactionText);
                            }

                            if (io.IsHold())
                            {
                                if (input.interact)
                                {
                                    //Store object
                                    runtimeData.holdingInteractableObject = io;

                                    //Tell object we want to interact
                                    io.Interact(pb);
                                }
                                else
                                {
                                    if (runtimeData.holdingInteractableObject)
                                    {
                                        runtimeData.holdingInteractableObject.InteractHoldEnd(pb);
                                        runtimeData.holdingInteractableObject = null;
                                    }
                                }
                            }
                            else
                            {
                                if (runtimeData.lastInteract != input.interact)
                                {
                                    runtimeData.lastInteract = input.interact;
                                    if (input.interact)
                                    {
                                        //Tell object we want to interact
                                        io.Interact(pb);
                                    }
                                }
                            }
                        }
                        else
                        {
                            if (pb.isFirstPersonActive)
                            {
                                Kit_IngameMain.instance.hud.DisplayWeaponPickup(false);
                                Kit_IngameMain.instance.hud.DisplayInteraction(false);
                            }

                            if (runtimeData.holdingInteractableObject)
                            {
                                runtimeData.holdingInteractableObject.InteractHoldEnd(pb);
                                runtimeData.holdingInteractableObject = null;
                            }
                        }
                    }
                    else
                    {
                        if (pb.isFirstPersonActive)
                        {
                            Kit_IngameMain.instance.hud.DisplayWeaponPickup(false);
                            Kit_IngameMain.instance.hud.DisplayInteraction(false);
                        }

                        if (runtimeData.holdingInteractableObject)
                        {
                            runtimeData.holdingInteractableObject.InteractHoldEnd(pb);
                            runtimeData.holdingInteractableObject = null;
                        }
                    }
                }
                else
                {
                    if (pb.isFirstPersonActive)
                    {
                        Kit_IngameMain.instance.hud.DisplayWeaponPickup(false);
                        Kit_IngameMain.instance.hud.DisplayInteraction(false);
                    }

                    if (runtimeData.holdingInteractableObject)
                    {
                        runtimeData.holdingInteractableObject.InteractHoldEnd(pb);
                        runtimeData.holdingInteractableObject = null;
                    }
                }
            }

            public override void CustomUpdate(Kit_PlayerBehaviour pb, double revertBy)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;

                //Quick use has priority!
                if ((runtimeData.quickUseInProgress || runtimeData.quickUseState > 0) && runtimeData.desiredQuickUse >= 0)
                {
                    //Update weapon animation
                    runtimeData.weaponsInUseDataObjects[runtimeData.desiredQuickUse].behaviour.AnimateWeapon(pb, runtimeData.weaponsInUseDataObjects[runtimeData.desiredQuickUse], pb.movement.GetCurrentWeaponMoveAnimation(pb), pb.movement.GetCurrentWalkAnimationSpeed(pb));

                    if (Time.time >= runtimeData.quickUseOverAt)
                    {
                        //First, put away current weapon!
                        if (runtimeData.quickUseState == 0)
                        {
                            if (!runtimeData.weaponsInUseDataObjects[runtimeData.desiredQuickUse].behaviour.QuickUseSkipsPutaway(pb, runtimeData.weaponsInUseDataObjects[runtimeData.desiredQuickUse]))
                            {
                                //Set time (Because here we cannot use a coroutine)
                                runtimeData.quickUseOverAt = Time.time + runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.putawayTime;
                                //Set phase
                                runtimeData.quickUseState = 1;
                                //Start putaway
                                runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.PutawayWeapon(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]);
                                //Play Third person animation
                                pb.thirdPersonPlayerModel.PlayWeaponChangeAnimation(runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.thirdPersonAnimType, false, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.putawayTime);
                                if (pb.isFirstPersonActive)
                                {
                                    //Hide crosshair
                                    Kit_IngameMain.instance.hud.DisplayCrosshair(0f, false);
                                }

                                if (pb.isLocalPlayer)
                                {
                                    pb.inputManager.ResetAiming(pb);
                                }
                            }
                            else
                            {
                                //Set phase
                                runtimeData.quickUseState = 1;
                                if (pb.isFirstPersonActive)
                                {
                                    //Hide crosshair
                                    Kit_IngameMain.instance.hud.DisplayCrosshair(0f, false);
                                }
                            }
                        }
                        else if (runtimeData.quickUseState == 1)
                        {
                            //Weapon has been put away, hide weapon
                            runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.PutawayWeaponHide(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]);
                            runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.QuickUseOnOtherWeaponBegin(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]);

                            //Set state
                            runtimeData.quickUseState = 2;

                            //Begin quick use....
                            runtimeData.quickUseOverAt = Time.time + runtimeData.weaponsInUseDataObjects[runtimeData.desiredQuickUse].behaviour.BeginQuickUse(pb, runtimeData.weaponsInUseDataObjects[runtimeData.desiredQuickUse], (float)revertBy);
                        }
                        else if (runtimeData.quickUseState == 2)
                        {
                            //Check if weapon wants to abort quick use
                            if (!runtimeData.weaponsInUseDataObjects[runtimeData.desiredQuickUse].behaviour.SupportsQuickUse(pb, runtimeData.weaponsInUseDataObjects[runtimeData.desiredQuickUse]) ||
                                //Check if we don't need to wait for the button
                                (!runtimeData.weaponsInUseDataObjects[runtimeData.desiredQuickUse].behaviour.WaitForQuickUseButtonRelease(pb, runtimeData.weaponsInUseDataObjects[runtimeData.desiredQuickUse])) ||
                                //Or button was released via sync
                                (runtimeData.quickUseSyncButtonWaitOver))
                            {
                                runtimeData.quickUseSyncButtonWaitOver = true;
                                //Set State
                                runtimeData.quickUseState = 3;
                                //End quick use...
                                runtimeData.quickUseOverAt = Time.time + runtimeData.weaponsInUseDataObjects[runtimeData.desiredQuickUse].behaviour.EndQuickUse(pb, runtimeData.weaponsInUseDataObjects[runtimeData.desiredQuickUse], (float)revertBy);
                            }
                        }
                        else if (runtimeData.quickUseState == 3)
                        {
                            //Hide Quick Use!
                            runtimeData.weaponsInUseDataObjects[runtimeData.desiredQuickUse].behaviour.EndQuickUseAfter(pb, runtimeData.weaponsInUseDataObjects[runtimeData.desiredQuickUse], (float)revertBy);
                            //Check if currently selected  weapon is valid.
                            if (runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.CanBeSelected(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]))
                            {
                                //Set weapon
                                runtimeData.currentWeapon = runtimeData.desiredWeapon;
                            }
                            else
                            {
                                //Its not, find a new one
                                int next = 0;
                                for (int i = 0; i < runtimeData.weaponsInUseDataObjects.Length; i++)
                                {
                                    //Check if this one works!
                                    if (runtimeData.weaponsInUseDataObjects[i].behaviour.CanBeSelected(pb, runtimeData.weaponsInUseDataObjects[i]))
                                    {
                                        int id = i;
                                        next = id;
                                        //We found one
                                        break;
                                    }
                                }

                                //This should ALWAYS be true!
                                if (next >= 0)
                                {
                                    runtimeData.desiredWeapon = next;
                                    //Set current one too!
                                    runtimeData.currentWeapon = next;
                                }
                                else
                                {
                                    Debug.LogError("Could not find next weapon! This is not allowed!");
                                }
                            }

                            //Draw that weapon
                            runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.DrawWeapon(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]);
                            //Play Third person animation
                            pb.thirdPersonPlayerModel.PlayWeaponChangeAnimation(runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.thirdPersonAnimType, true, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.drawTime);
                            //Set phase
                            runtimeData.quickUseState = 4;
                            //Set time
                            runtimeData.quickUseOverAt = Time.time + runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.drawTime;
                            //Done, now wait
                        }
                        else if (runtimeData.quickUseState == 4)
                        {
                            //End quick use
                            runtimeData.quickUseInProgress = false;
                            runtimeData.desiredQuickUse = -1;
                            runtimeData.quickUseSyncButtonWaitOver = false;
                            runtimeData.quickUseState = 0;
                            runtimeData.quickUseOverAt = Time.time;

                            //Also reset switching just to be sure!
                            runtimeData.switchPhase = 0;
                            runtimeData.switchNextEnd = 0f;
                            runtimeData.switchInProgress = false;
                        }
                    }
                }
                else
                {
                    //Update weapon animation
                    runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.AnimateWeapon(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon], pb.movement.GetCurrentWeaponMoveAnimation(pb), pb.movement.GetCurrentWalkAnimationSpeed(pb));

                    if (!runtimeData.switchInProgress)
                    {
                        //If we aren't switching weapons, update weapon behaviour
                        runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.CalculateWeaponUpdate(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]);

                        //Check if we want to select a different weapon
                        if (runtimeData.desiredWeapon != runtimeData.currentWeapon)
                        {
                            //If not, start to switch
                            runtimeData.switchInProgress = true;
                            //Set time (Because here we cannot use a coroutine)
                            runtimeData.switchNextEnd = Time.time + runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.putawayTime;
                            //Set phase
                            runtimeData.switchPhase = 0;
                            //Start putaway
                            runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.PutawayWeapon(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]);
                            //Play Third person animation
                            pb.thirdPersonPlayerModel.PlayWeaponChangeAnimation(runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.thirdPersonAnimType, false, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.putawayTime);
                            if (pb.isFirstPersonActive)
                            {
                                //Hide crosshair
                                Kit_IngameMain.instance.hud.DisplayCrosshair(0f, false);
                            }
                        }
                    }
                    else
                    {
                        //Switching, courtine less
                        #region Switching
                        //Check for time
                        if (Time.time >= runtimeData.switchNextEnd)
                        {
                            //Time is over, check which phase is next
                            if (runtimeData.switchPhase == 0)
                            {
                                //Weapon has been put away, hide weapon
                                runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.PutawayWeaponHide(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]);

                                runtimeData.currentWeapon = runtimeData.desiredWeapon;

                                //Draw that weapon
                                runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.DrawWeapon(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]);
                                //Set phase
                                runtimeData.switchPhase = 1;
                                //Set time
                                runtimeData.switchNextEnd = Time.time + runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.drawTime;
                                //Play Third person animation
                                pb.thirdPersonPlayerModel.PlayWeaponChangeAnimation(runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.thirdPersonAnimType, true, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.drawTime);
                                //Done, now wait
                            }
                            else if (runtimeData.switchPhase == 1)
                            {
                                //Switching is over
                                runtimeData.switchPhase = 0;
                                runtimeData.switchNextEnd = 0f;
                                runtimeData.switchInProgress = false;
                            }
                        }
                        #endregion
                    }
                }

                //Move weapons transform
                pb.weaponsGo.localPosition = Vector3.Lerp(pb.weaponsGo.localPosition, Vector3.zero + pb.looking.GetWeaponOffset(pb), Time.deltaTime * weaponPositionChangeSpeed);

                //Move weapons transform
                pb.weaponsGo.localRotation = Quaternion.Slerp(pb.weaponsGo.localRotation, pb.looking.GetWeaponRotationOffset(pb), Time.deltaTime * weaponPositionChangeSpeed);

                if (pb.isFirstPersonActive)
                {
                    Kit_IngameMain.instance.hud.DisplayWeaponsAndQuickUses(pb, runtimeData);
                }
            }

            public override void CustomLateUpdate(Kit_PlayerBehaviour pb, double revertTime)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;

                //Update weapon animation
                runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.CalculateWeaponLateUpdate(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]);
            }

            public override void CustomFixedUpdate(Kit_PlayerBehaviour pb, double revertTime)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;

                //Update weapon animation
                runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.CalculateWeaponFixedUpdate(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]);
            }

            public override void PlayerDead(Kit_PlayerBehaviour pb)
            {
                if (NetworkServer.active && (Kit_IngameMain.instance.currentPvPGameModeBehaviour && Kit_IngameMain.instance.currentPvPGameModeBehaviour.CanDropWeapons()) || (Kit_IngameMain.instance.currentPvEGameModeBehaviour && Kit_IngameMain.instance.currentPvEGameModeBehaviour.CanDropWeapons()))
                {
                    Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                    if (uponDeathDrop == DeadDrop.Selected)
                    {
                        DropWeaponDead(pb, runtimeData.currentWeapon);
                    }
                    else if (uponDeathDrop == DeadDrop.All)
                    {
                        for (int i = 0; i < runtimeData.weaponsInUseDataObjects.Length; i++)
                        {
                            if (!runtimeData.weaponsInUseDataObjects[i].isInjectedFromPlugin)
                            {
                                DropWeaponDead(pb, i);
                            }
                        }
                    }

                }
            }

            public override void OnAnimatorIKCallback(Kit_PlayerBehaviour pb, Animator anim)
            {
                //Get runtime data
                if (pb.isLocalPlayer)
                {
                    Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                    if (anim)
                    {
                        //Get Weapon IK
                        WeaponIKValues ikv = null;

                        if (runtimeData.quickUseInProgress && runtimeData.quickUseState > 0 && runtimeData.quickUseState < 4)
                        {
                            ikv = runtimeData.weaponsInUseDataObjects[runtimeData.desiredQuickUse].behaviour.GetIK(pb, anim, runtimeData.weaponsInUseDataObjects[runtimeData.desiredQuickUse]);
                        }
                        else
                        {
                            ikv = runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.GetIK(pb, anim, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]);
                        }

                        if (ikv != null)
                        {
                            if (ikv.leftHandIK)
                            {
                                anim.SetIKPosition(AvatarIKGoal.LeftHand, ikv.leftHandIK.position);
                                anim.SetIKRotation(AvatarIKGoal.LeftHand, ikv.leftHandIK.rotation);
                            }
                            if (!runtimeData.switchInProgress && ikv.canUseIK && ikv.leftHandIK)
                            {
                                runtimeData.leftHandIKWeight = Mathf.Lerp(runtimeData.leftHandIKWeight, 1f, Time.deltaTime * 3);
                            }
                            else
                            {
                                runtimeData.leftHandIKWeight = Mathf.Lerp(runtimeData.leftHandIKWeight, 0f, Time.deltaTime * 20);
                            }
                            anim.SetIKPositionWeight(AvatarIKGoal.LeftHand, runtimeData.leftHandIKWeight);
                            anim.SetIKRotationWeight(AvatarIKGoal.LeftHand, runtimeData.leftHandIKWeight);
                        }
                        else
                        {
                            runtimeData.leftHandIKWeight = Mathf.Lerp(runtimeData.leftHandIKWeight, 0f, Time.deltaTime * 20);
                            anim.SetIKPositionWeight(AvatarIKGoal.LeftHand, runtimeData.leftHandIKWeight);
                            anim.SetIKRotationWeight(AvatarIKGoal.LeftHand, runtimeData.leftHandIKWeight);
                        }
                    }

                }
                else
                {
                    Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                    if (anim)
                    {
                        //Get Weapon IK
                        WeaponIKValues ikv = null;

                        if (runtimeData.quickUseInProgress && runtimeData.quickUseState > 0 && runtimeData.quickUseState < 4)
                        {
                            ikv = runtimeData.weaponsInUseDataObjects[runtimeData.desiredQuickUse].behaviour.GetIK(pb, anim, runtimeData.weaponsInUseDataObjects[runtimeData.desiredQuickUse]);
                        }
                        else
                        {
                            ikv = runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.GetIK(pb, anim, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]);
                        }

                        if (ikv != null)
                        {
                            if (ikv.leftHandIK)
                            {
                                anim.SetIKPosition(AvatarIKGoal.LeftHand, ikv.leftHandIK.position);
                                anim.SetIKRotation(AvatarIKGoal.LeftHand, ikv.leftHandIK.rotation);
                            }
                            if (!runtimeData.switchInProgress && ikv.canUseIK && ikv.leftHandIK)
                            {
                                runtimeData.leftHandIKWeight = Mathf.Lerp(runtimeData.leftHandIKWeight, 1f, Time.deltaTime * 3);
                            }
                            else
                            {
                                runtimeData.leftHandIKWeight = Mathf.Lerp(runtimeData.leftHandIKWeight, 0f, Time.deltaTime * 20);
                            }
                            anim.SetIKPositionWeight(AvatarIKGoal.LeftHand, runtimeData.leftHandIKWeight);
                            anim.SetIKRotationWeight(AvatarIKGoal.LeftHand, runtimeData.leftHandIKWeight);
                        }
                        else
                        {
                            runtimeData.leftHandIKWeight = Mathf.Lerp(runtimeData.leftHandIKWeight, 0f, Time.deltaTime * 20);
                            anim.SetIKPositionWeight(AvatarIKGoal.LeftHand, runtimeData.leftHandIKWeight);
                            anim.SetIKRotationWeight(AvatarIKGoal.LeftHand, runtimeData.leftHandIKWeight);
                        }
                    }

                }
            }

            public override void FallDownEffect(Kit_PlayerBehaviour pb, bool wasFallDamageApplied)
            {
                if (pb.isBot) return;
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                if (runtimeData.weaponsInUseDataObjects.Length <= runtimeData.currentWeapon) return;
                if (!runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]) return;
                if (!runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour) return;
                runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.FallDownEffect(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon], wasFallDamageApplied);

            }

            public override void OnControllerColliderHitRelay(Kit_PlayerBehaviour pb, ControllerColliderHit hit)
            {
                if (!pb.weaponManagerNetworkData) return;
                //Get runtime data
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                if (runtimeData.weaponsInUseDataObjects.Length <= runtimeData.currentWeapon) return;
                if (!runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]) return;
                if (!runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour) return;
                runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.OnControllerColliderHitCallback(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon], hit);
            }

            public override void NetworkSemiRPCReceived(Kit_PlayerBehaviour pb)
            {
                if (!pb.weaponManagerNetworkData) return;
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                if (runtimeData.weaponsInUseDataObjects.Length <= runtimeData.currentWeapon) return;
                if (!runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]) return;
                if (!runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour) return;
                //Relay to weapon script
                runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.NetworkSemiRPCReceived(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]);
            }

            public override void NetworkBoltActionRPCReceived(Kit_PlayerBehaviour pb, int state)
            {
                if (!pb.weaponManagerNetworkData) return;
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                if (runtimeData.weaponsInUseDataObjects.Length <= runtimeData.currentWeapon) return;
                if (!runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]) return;
                if (!runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour) return;
                //Relay to weapon script
                runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.NetworkBoltActionRPCReceived(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon], state);
            }

            public override void NetworkBurstRPCReceived(Kit_PlayerBehaviour pb, int burstLength)
            {
                if (!pb.weaponManagerNetworkData) return;
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                if (runtimeData.weaponsInUseDataObjects.Length <= runtimeData.currentWeapon) return;
                if (!runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]) return;
                if (!runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour) return;
                //Relay to weapon script
                runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.NetworkBurstRPCReceived(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon], burstLength);
            }

            public override void NetworkReloadRPCReceived(Kit_PlayerBehaviour pb, bool isEmpty)
            {
                if (!pb.weaponManagerNetworkData) return;
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                if (runtimeData.weaponsInUseDataObjects.Length <= runtimeData.currentWeapon) return;
                if (!runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]) return;
                if (!runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour) return;
                //Relay to weapon script
                runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.NetworkReloadRPCReceived(pb, isEmpty, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]);

            }

            public override void NetworkProceduralReloadRPCReceived(Kit_PlayerBehaviour pb, int stage)
            {
                if (!pb.weaponManagerNetworkData) return;
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                if (runtimeData.weaponsInUseDataObjects.Length <= runtimeData.currentWeapon) return;
                if (!runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]) return;
                if (!runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour) return;
                //Relay to weapon script
                runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.NetworkProceduralReloadRPCReceived(pb, stage, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]);

            }

            public override void NetworkMeleeChargeRPCReceived(Kit_PlayerBehaviour pb, int state, int slot)
            {
                if (!pb.weaponManagerNetworkData) return;
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                if (runtimeData.weaponsInUseDataObjects.Length <= runtimeData.currentWeapon) return;
                if (!runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]) return;
                if (!runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour) return;
                //Relay to weapon script
                runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.NetworkMeleeChargeRPCReceived(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon], state, slot);

            }

            public override void NetworkMeleeHealRPCReceived(Kit_PlayerBehaviour pb, int slot)
            {
                if (!pb.weaponManagerNetworkData) return;
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                if (runtimeData.weaponsInUseDataObjects.Length <= runtimeData.currentWeapon) return;
                if (!runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]) return;
                if (!runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour) return;
                //Relay to weapon script
                runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.NetworkMeleeHealRPCReceived(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon], slot);
            }

            public override void NetworkMeleeStabRPCReceived(Kit_PlayerBehaviour pb, int state, int slot)
            {
                if (!pb.weaponManagerNetworkData) return;
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                if (runtimeData.weaponsInUseDataObjects.Length <= runtimeData.currentWeapon) return;
                if (!runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]) return;
                if (!runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour) return;
                //Relay to weapon script
                runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.NetworkMeleeStabRPCReceived(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon], state, slot);
            }

            public override void NetworkGrenadePullPinRPCReceived(Kit_PlayerBehaviour pb)
            {
                if (!pb.weaponManagerNetworkData) return;
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                if (runtimeData.weaponsInUseDataObjects.Length <= runtimeData.currentWeapon) return;
                if (!runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]) return;
                if (!runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour) return;
                //Relay to weapon script
                runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.NetworkGrenadePullPinRPCReceived(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]);
            }

            public override void NetworkGrenadeThrowRPCReceived(Kit_PlayerBehaviour pb)
            {
                if (!pb.weaponManagerNetworkData) return;
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                if (runtimeData.weaponsInUseDataObjects.Length <= runtimeData.currentWeapon) return;
                if (!runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]) return;
                if (!runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour) return;
                //Relay to weapon script
                runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.NetworkGrenadeThrowRPCReceived(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]);
            }

            public override float GetAimingPercentage(Kit_PlayerBehaviour pb)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                return runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.GetAimingPercentage(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]); //Relay to weapon script
            }

            public override bool IsAiming(Kit_PlayerBehaviour pb)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                return runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.IsWeaponAiming(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]); //Relay to weapon script
            }

            public override float AimInTime(Kit_PlayerBehaviour pb)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                return runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.AimInTime(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]); //Relay to weapon script
            }

            public override bool ForceIntoFirstPerson(Kit_PlayerBehaviour pb)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                return runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.ForceIntoFirstPerson(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]); //Relay to weapon script
            }

            public override bool CanRun(Kit_PlayerBehaviour pb)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                if (allowSwitchingWhileRunning) return true;
                else return !runtimeData.switchInProgress;
            }

            public override float CurrentMovementMultiplier(Kit_PlayerBehaviour pb)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                return runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.SpeedMultiplier(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]); //Relay to weapon script
            }

            public override float CurrentSensitivity(Kit_PlayerBehaviour pb)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                return runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.Sensitivity(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]); //Relay to weapon script
            }

            public override int GetCurrentWeapon(Kit_PlayerBehaviour pb)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                //Just return ID
                return runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].id;
            }

            public override int HasWeapon(Kit_PlayerBehaviour pb, int id)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;

                for (int i = 0; i < runtimeData.weaponsInUseDataObjects.Length; i++)
                {
                    if (runtimeData.weaponsInUseDataObjects[i].id == id)
                    {
                        return i;
                    }
                }

                return -1;
            }

            public override Kit_WeaponRuntimeDataBase GetRuntimeDataOfWeapon(Kit_PlayerBehaviour pb, int slot)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                //Just return ID
                return runtimeData.weaponsInUseDataObjects[slot];
            }

            public override bool CanBuyWeapon(Kit_PlayerBehaviour pb, int id)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;

                for (int i = 0; i < runtimeData.weaponsInUseDataObjects.Length; i++)
                {
                    if (runtimeData.weaponsInUseDataObjects[i].id == id)
                    {
                        //Special case for grenades - let us buy more grenades if we are below that #
                        if (runtimeData.weaponsInUseDataObjects[i] != null && runtimeData.weaponsInUseDataObjects[i].GetType() == typeof(Kit_ModernGrenadeScriptRuntimeData))
                        {
                            Kit_ModernGrenadeScriptRuntimeData gcrd = runtimeData.weaponsInUseDataObjects[i] as Kit_ModernGrenadeScriptRuntimeData;
                            Kit_ModernGrenadeScript grenadeData = runtimeData.weaponsInUseDataObjects[i].behaviour as Kit_ModernGrenadeScript;

                            if (gcrd.amountOfGrenadesLeft < grenadeData.amountOfGrenadesAtStart)
                            {
                                return true;
                            }

                        }

                        return false;
                    }

                }

                //Can buy
                return true;
            }

            public override void NetworkReplaceWeapon(Kit_PlayerBehaviour pb, int slot, int weapon, int bulletsLeft, int bulletsLeftToReload, int[] attachments)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;

                GameObject spawnObject = Kit_IngameMain.instance.gameInformation.allWeapons[weapon].SetupSpawnData(pb, slot, new LoadoutWeapon { weaponID = weapon, attachments = attachments });

                Kit_WeaponRuntimeDataBase wrdb = spawnObject.GetComponent<Kit_WeaponRuntimeDataBase>();

                if (wrdb is Kit_ModernWeaponScriptRuntimeData)
                {
                    Kit_ModernWeaponScriptRuntimeData mwsrd = wrdb as Kit_ModernWeaponScriptRuntimeData;
                    mwsrd.bulletsLeft = bulletsLeft;
                    mwsrd.bulletsLeftToReload = bulletsLeftToReload;
                }

                NetworkServer.Spawn(spawnObject, pb.gameObject);
                NetworkIdentity id = spawnObject.GetComponent<NetworkIdentity>();

                NetworkIdentity oldIdentity = NetworkServer.spawned[runtimeData.weaponsInUseSync[slot]];

                if (oldIdentity)
                {
                    NetworkServer.Destroy(oldIdentity.gameObject);
                }

                runtimeData.weaponsInUseSync[slot] = id.netId;
            }

            public override void NetworkPhysicalBulletFired(Kit_PlayerBehaviour pb, Vector3 pos, Vector3 dir)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                if (runtimeData.weaponsInUseDataObjects.Length > runtimeData.currentWeapon)
                    //Relay to weapon script
                    runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.NetworkPhysicalBulletFired(pb, pos, dir, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]);
            }


            public override void DropWeapon(Kit_PlayerBehaviour pb, int slot)
            {
                if ((Kit_IngameMain.instance.currentPvPGameModeBehaviour && Kit_IngameMain.instance.currentPvPGameModeBehaviour.CanDropWeapons()) || (Kit_IngameMain.instance.currentPvEGameModeBehaviour && Kit_IngameMain.instance.currentPvEGameModeBehaviour.CanDropWeapons()))
                {
                    if (pb.weaponManagerNetworkData != null && pb.weaponManagerNetworkData.GetType() == typeof(Kit_ModernWeaponManagerNetworkData))
                    {
                        //Get the manager's runtime data
                        Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                        if (runtimeData.weaponsInUseDataObjects[slot] != null && runtimeData.weaponsInUseDataObjects[slot].GetType() == typeof(Kit_ModernWeaponScriptRuntimeData))
                        {
                            //Get the weapon's runtime data
                            Kit_ModernWeaponScriptRuntimeData wepData = runtimeData.weaponsInUseDataObjects[slot] as Kit_ModernWeaponScriptRuntimeData;
                            //Get the Scriptable object
                            Kit_ModernWeaponScript wepScript = runtimeData.weaponsInUseDataObjects[slot].behaviour as Kit_ModernWeaponScript;
                            //Instantiate
                            GameObject go = Instantiate(dropPrefab, pb.playerCameraTransform.position, pb.playerCameraTransform.rotation);
                            Kit_DropBehaviour dp = go.GetComponent<Kit_DropBehaviour>();
                            dp.isSceneOwned = true;
                            dp.weaponID = wepScript.gameGunID;
                            dp.bulletsLeft = wepData.bulletsLeft;
                            dp.bulletsLeftToReload = wepData.bulletsLeftToReload;

                            for (int i = 0; i < wepData.attachments.Count; i++)
                            {
                                dp.attachments.Add(wepData.attachments[i]);
                            }

                            NetworkServer.Spawn(go);
                        }
                        else if (runtimeData.weaponsInUseDataObjects[slot] != null && runtimeData.weaponsInUseDataObjects[slot].GetType() == typeof(Kit_ModernMeleeScriptRuntimeData))
                        {
                            //Get the weapon's runtime data
                            Kit_ModernMeleeScriptRuntimeData wepData = runtimeData.weaponsInUseDataObjects[slot] as Kit_ModernMeleeScriptRuntimeData;
                            //Get the Scriptable object
                            Kit_ModernMeleeScript wepScript = runtimeData.weaponsInUseDataObjects[slot].behaviour as Kit_ModernMeleeScript;
                            //Instantiate
                            GameObject go = Instantiate(dropPrefab, pb.playerCameraTransform.position, pb.playerCameraTransform.rotation);
                            Kit_DropBehaviour dp = go.GetComponent<Kit_DropBehaviour>();
                            dp.isSceneOwned = true;
                            dp.weaponID = wepScript.gameGunID;
                            dp.bulletsLeft = 0;
                            dp.bulletsLeftToReload = 0;

                            for (int i = 0; i < wepData.attachments.Count; i++)
                            {
                                dp.attachments.Add(wepData.attachments[i]);
                            }

                            NetworkServer.Spawn(go);
                        }
                        else if (runtimeData.weaponsInUseDataObjects[slot] != null && runtimeData.weaponsInUseDataObjects[slot].GetType() == typeof(Kit_ModernGrenadeScriptRuntimeData))
                        {
                            //Get the weapon's runtime data
                            Kit_ModernGrenadeScriptRuntimeData wepData = runtimeData.weaponsInUseDataObjects[slot] as Kit_ModernGrenadeScriptRuntimeData;
                            if (wepData.amountOfGrenadesLeft <= 0) return;
                            //Get the Scriptable object
                            Kit_ModernGrenadeScript wepScript = runtimeData.weaponsInUseDataObjects[slot].behaviour as Kit_ModernGrenadeScript;
                            //Instantiate
                            GameObject go = Instantiate(dropPrefab, pb.playerCameraTransform.position, pb.playerCameraTransform.rotation);
                            Kit_DropBehaviour dp = go.GetComponent<Kit_DropBehaviour>();
                            dp.isSceneOwned = true;
                            dp.weaponID = wepScript.gameGunID;
                            dp.bulletsLeft = 0;
                            dp.bulletsLeftToReload = 0;

                            for (int i = 0; i < wepData.attachments.Count; i++)
                            {
                                dp.attachments.Add(wepData.attachments[i]);
                            }

                            NetworkServer.Spawn(go);
                        }
                    }
                }
            }

            /// <summary>
            /// Drops a weapon and applies the ragdoll force!
            /// </summary>
            /// <param name="pb"></param>
            /// <param name="slot"></param>
            public void DropWeaponDead(Kit_PlayerBehaviour pb, int slot)
            {
                if ((Kit_IngameMain.instance.currentPvPGameModeBehaviour && Kit_IngameMain.instance.currentPvPGameModeBehaviour.CanDropWeapons()) || (Kit_IngameMain.instance.currentPvEGameModeBehaviour && Kit_IngameMain.instance.currentPvEGameModeBehaviour.CanDropWeapons()))
                {
                    if (pb.weaponManagerNetworkData != null && pb.weaponManagerNetworkData.GetType() == typeof(Kit_ModernWeaponManagerNetworkData))
                    {
                        //Get the manager's runtime data
                        Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                        if (runtimeData.weaponsInUseDataObjects[slot] != null && runtimeData.weaponsInUseDataObjects[slot].GetType() == typeof(Kit_ModernWeaponScriptRuntimeData))
                        {
                            //Get the weapon's runtime data
                            Kit_ModernWeaponScriptRuntimeData wepData = runtimeData.weaponsInUseDataObjects[slot] as Kit_ModernWeaponScriptRuntimeData;
                            //Get the Scriptable object
                            Kit_ModernWeaponScript wepScript = runtimeData.weaponsInUseDataObjects[slot].behaviour as Kit_ModernWeaponScript;
                            //Instantiate
                            GameObject go = Instantiate(dropPrefab, pb.playerCameraTransform.position, pb.playerCameraTransform.rotation);
                            Kit_DropBehaviour dp = go.GetComponent<Kit_DropBehaviour>();
                            dp.isSceneOwned = true;
                            dp.weaponID = wepScript.gameGunID;
                            dp.bulletsLeft = wepData.bulletsLeft;
                            dp.bulletsLeftToReload = wepData.bulletsLeftToReload;

                            for (int i = 0; i < wepData.attachments.Count; i++)
                            {
                                dp.attachments.Add(wepData.attachments[i]);
                            }

                            NetworkServer.Spawn(go);
                            Rigidbody body = go.GetComponent<Rigidbody>();
                            if (body)
                            {
                                body.velocity = pb.movement.GetVelocity(pb);
                                body.AddForceNextFrame(pb.ragdollForward * pb.ragdollForce / 10);
                            }
                        }
                        else if (runtimeData.weaponsInUseDataObjects[slot] != null && runtimeData.weaponsInUseDataObjects[slot].GetType() == typeof(Kit_ModernMeleeScriptRuntimeData))
                        {
                            //Get the weapon's runtime data
                            Kit_ModernMeleeScriptRuntimeData wepData = runtimeData.weaponsInUseDataObjects[slot] as Kit_ModernMeleeScriptRuntimeData;
                            //Get the Scriptable object
                            Kit_ModernMeleeScript wepScript = runtimeData.weaponsInUseDataObjects[slot].behaviour as Kit_ModernMeleeScript;
                            //Instantiate
                            GameObject go = Instantiate(dropPrefab, pb.playerCameraTransform.position, pb.playerCameraTransform.rotation);
                            Kit_DropBehaviour dp = go.GetComponent<Kit_DropBehaviour>();
                            dp.isSceneOwned = true;
                            dp.weaponID = wepScript.gameGunID;
                            dp.bulletsLeft = 0;
                            dp.bulletsLeftToReload = 0;

                            for (int i = 0; i < wepData.attachments.Count; i++)
                            {
                                dp.attachments.Add(wepData.attachments[i]);
                            }

                            NetworkServer.Spawn(go);
                            Rigidbody body = go.GetComponent<Rigidbody>();
                            if (body)
                            {
                                body.velocity = pb.movement.GetVelocity(pb);
                                body.AddForceNextFrame(pb.ragdollForward * pb.ragdollForce / 10);
                            }
                        }
                        else if (runtimeData.weaponsInUseDataObjects[slot] != null && runtimeData.weaponsInUseDataObjects[slot].GetType() == typeof(Kit_ModernGrenadeScriptRuntimeData))
                        {
                            //Get the weapon's runtime data
                            Kit_ModernGrenadeScriptRuntimeData wepData = runtimeData.weaponsInUseDataObjects[slot] as Kit_ModernGrenadeScriptRuntimeData;
                            if (wepData.amountOfGrenadesLeft <= 0) return;
                            //Get the Scriptable object
                            Kit_ModernGrenadeScript wepScript = runtimeData.weaponsInUseDataObjects[slot].behaviour as Kit_ModernGrenadeScript;
                            //Instantiate
                            GameObject go = Instantiate(dropPrefab, pb.playerCameraTransform.position, pb.playerCameraTransform.rotation);
                            Kit_DropBehaviour dp = go.GetComponent<Kit_DropBehaviour>();
                            dp.isSceneOwned = true;
                            dp.weaponID = wepScript.gameGunID;
                            dp.bulletsLeft = 0;
                            dp.bulletsLeftToReload = 0;

                            for (int i = 0; i < wepData.attachments.Count; i++)
                            {
                                dp.attachments.Add(wepData.attachments[i]);
                            }

                            NetworkServer.Spawn(go);
                            Rigidbody body = go.GetComponent<Rigidbody>();
                            if (body)
                            {
                                body.velocity = pb.movement.GetVelocity(pb);
                                body.AddForceNextFrame(pb.ragdollForward * pb.ragdollForce / 10);
                            }
                        }
                    }
                }
            }

            public override void DropWeapon(Kit_PlayerBehaviour pb, int slot, Transform replace)
            {
                if (pb.weaponManagerNetworkData != null && pb.weaponManagerNetworkData.GetType() == typeof(Kit_ModernWeaponManagerNetworkData))
                {
                    //Get the manager's runtime data
                    Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                    if (runtimeData.weaponsInUseDataObjects[slot] != null && runtimeData.weaponsInUseDataObjects[slot].GetType() == typeof(Kit_ModernWeaponScriptRuntimeData))
                    {
                        //Get the weapon's runtime data
                        Kit_ModernWeaponScriptRuntimeData wepData = runtimeData.weaponsInUseDataObjects[slot] as Kit_ModernWeaponScriptRuntimeData;
                        //Get the Scriptable object
                        Kit_ModernWeaponScript wepScript = runtimeData.weaponsInUseDataObjects[slot].behaviour as Kit_ModernWeaponScript;
                        //Instantiate
                        GameObject go = Instantiate(dropPrefab, replace.position, replace.rotation);
                        Kit_DropBehaviour dp = go.GetComponent<Kit_DropBehaviour>();
                        dp.isSceneOwned = true;
                        dp.weaponID = wepScript.gameGunID;
                        dp.bulletsLeft = wepData.bulletsLeft;
                        dp.bulletsLeftToReload = wepData.bulletsLeftToReload;

                        for (int i = 0; i < wepData.attachments.Count; i++)
                        {
                            dp.attachments.Add(wepData.attachments[i]);
                        }

                        NetworkServer.Spawn(go);
                    }
                    else if (runtimeData.weaponsInUseDataObjects[slot] != null && runtimeData.weaponsInUseDataObjects[slot].GetType() == typeof(Kit_ModernMeleeScriptRuntimeData))
                    {
                        //Get the weapon's runtime data
                        Kit_ModernMeleeScriptRuntimeData wepData = runtimeData.weaponsInUseDataObjects[slot] as Kit_ModernMeleeScriptRuntimeData;
                        //Get the Scriptable object
                        Kit_ModernMeleeScript wepScript = runtimeData.weaponsInUseDataObjects[slot].behaviour as Kit_ModernMeleeScript;
                        //Instantiate
                        GameObject go = Instantiate(dropPrefab, replace.position, replace.rotation);
                        Kit_DropBehaviour dp = go.GetComponent<Kit_DropBehaviour>();
                        dp.isSceneOwned = true;
                        dp.weaponID = wepScript.gameGunID;
                        dp.bulletsLeft = 0;
                        dp.bulletsLeftToReload = 0;

                        for (int i = 0; i < wepData.attachments.Count; i++)
                        {
                            dp.attachments.Add(wepData.attachments[i]);
                        }

                        NetworkServer.Spawn(go);
                    }
                    else if (runtimeData.weaponsInUseDataObjects[slot] != null && runtimeData.weaponsInUseDataObjects[slot].GetType() == typeof(Kit_ModernGrenadeScriptRuntimeData))
                    {
                        //Get the weapon's runtime data
                        Kit_ModernGrenadeScriptRuntimeData wepData = runtimeData.weaponsInUseDataObjects[slot] as Kit_ModernGrenadeScriptRuntimeData;
                        if (wepData.amountOfGrenadesLeft <= 0) return;
                        //Get the Scriptable object
                        Kit_ModernGrenadeScript wepScript = runtimeData.weaponsInUseDataObjects[slot].behaviour as Kit_ModernGrenadeScript;
                        //Instantiate
                        GameObject go = Instantiate(dropPrefab, replace.position, replace.rotation);
                        Kit_DropBehaviour dp = go.GetComponent<Kit_DropBehaviour>();
                        dp.isSceneOwned = true;
                        dp.weaponID = wepScript.gameGunID;
                        dp.bulletsLeft = 0;
                        dp.bulletsLeftToReload = 0;

                        for (int i = 0; i < wepData.attachments.Count; i++)
                        {
                            dp.attachments.Add(wepData.attachments[i]);
                        }

                        NetworkServer.Spawn(go);
                    }
                }
            }

            public override int WeaponState(Kit_PlayerBehaviour pb)
            {
                //Get the manager's runtime data
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                return runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.WeaponState(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]);
            }

            public override int WeaponType(Kit_PlayerBehaviour pb)
            {
                //Get the manager's runtime data
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                return runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.GetWeaponType(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]);
            }

            public override void FirstThirdPersonChanged(Kit_PlayerBehaviour pb, Kit_GameInformation.Perspective perspective)
            {
                if (pb.syncSetup)
                {
                    //Forward to currently selected weapon
                    Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                    if (runtimeData.quickUseInProgress && runtimeData.quickUseState > 0 && runtimeData.quickUseState < 4)
                    {
                        runtimeData.weaponsInUseDataObjects[runtimeData.desiredQuickUse].behaviour.FirstThirdPersonChanged(pb, perspective, runtimeData.weaponsInUseDataObjects[runtimeData.desiredQuickUse]);
                    }
                    else
                    {
                        runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.FirstThirdPersonChanged(pb, perspective, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]);
                    }
                }
            }

            public override void OnAmmoPickup(Kit_PlayerBehaviour pb, Kit_AmmoPickup pickup)
            {
                //Forward to currently selected weapon
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.OnAmmoPickup(pb, pickup, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]);
            }

            public override void RestockAmmo(Kit_PlayerBehaviour pb, bool allWeapons)
            {
                if (pb.isServer)
                {
                    if (pb.weaponManagerNetworkData != null && pb.weaponManagerNetworkData.GetType() == typeof(Kit_ModernWeaponManagerNetworkData))
                    {
                        if (allWeapons)
                        {
                            Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                            for (int i = 0; i < runtimeData.weaponsInUseDataObjects.Length; i++)
                            {
                                runtimeData.weaponsInUseDataObjects[i].behaviour.RestockAmmo(pb, runtimeData.weaponsInUseDataObjects[i]);
                            }
                        }
                        else
                        {
                            //Forward to currently selected weapon
                            Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                            runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.RestockAmmo(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]);
                        }
                    }
                }
            }

            public override bool IsCurrentWeaponFull(Kit_PlayerBehaviour pb)
            {
                //Forward to currently selected weapon
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                return runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon].behaviour.IsWeaponFull(pb, runtimeData.weaponsInUseDataObjects[runtimeData.currentWeapon]);
            }

            public override void PluginSelectWeapon(Kit_PlayerBehaviour pb, int slot, bool locked = true)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                //Just set, thats all!
                runtimeData.desiredWeapon = slot;
                runtimeData.isDesiredWeaponLocked = locked;
            }

            public override int GetCurrentlyDesiredWeapon(Kit_PlayerBehaviour pb)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                return runtimeData.desiredWeapon;
            }

            public override int GetCurrentlyDesiredQuickUse(Kit_PlayerBehaviour pb)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                return runtimeData.desiredQuickUse;
            }

            public override int GetCurrentlySelectedWeapon(Kit_PlayerBehaviour pb)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                return runtimeData.currentWeapon;
            }

            public override void SetDesiredWeapon(Kit_PlayerBehaviour pb, int desiredWeapon)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
                if (runtimeData.weaponsInUseDataObjects[desiredWeapon].behaviour.CanBeSelected(pb, runtimeData.weaponsInUseDataObjects[desiredWeapon]))
                {
                    runtimeData.desiredWeapon = desiredWeapon;

                }
            }

            public override int[] GetSlotsWithEmptyWeapon(Kit_PlayerBehaviour pb)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;

                List<int> emptySlots = new List<int>();

                for (int i = 0; i < runtimeData.weaponsInUseDataObjects.Length; i++)
                {
                    //Check if that slot contains a placehodler weapon
                    if (runtimeData.weaponsInUseDataObjects[i].behaviour.GetType() == typeof(Kit_WeaponUnselectable))
                    {
                        int id = i;
                        //Add it to list of empty slots
                        emptySlots.Add(id);
                    }
                }

                return emptySlots.ToArray();
            }

            public override void BeginSpectating(Kit_PlayerBehaviour pb)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;

                for (int i = 0; i < runtimeData.weaponsInUseDataObjects.Length; i++)
                {
                    //Relay
                    runtimeData.weaponsInUseDataObjects[i].behaviour.BeginSpectating(pb, runtimeData.weaponsInUseDataObjects[i], runtimeData.weaponsInUseDataObjects[i].attachments.ToArray());
                }
            }

            public override void EndSpectating(Kit_PlayerBehaviour pb)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;

                for (int i = 0; i < runtimeData.weaponsInUseDataObjects.Length; i++)
                {
                    //Relay
                    runtimeData.weaponsInUseDataObjects[i].behaviour.EndSpectating(pb, runtimeData.weaponsInUseDataObjects[i]);
                }
            }

            public override void OnTriggerEnterRelay(Kit_PlayerBehaviour pb, Collider col)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;

                for (int i = 0; i < runtimeData.weaponsInUseDataObjects.Length; i++)
                {
                    if (runtimeData.weaponsInUseDataObjects[i].behaviour)
                    {
                        //Relay
                        runtimeData.weaponsInUseDataObjects[i].behaviour.OnTriggerEnterRelay(pb, runtimeData.weaponsInUseDataObjects[i], col);
                    }
                }
            }

            public override void OnTriggerExitRelay(Kit_PlayerBehaviour pb, Collider col)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;

                for (int i = 0; i < runtimeData.weaponsInUseDataObjects.Length; i++)
                {
                    if (runtimeData.weaponsInUseDataObjects[i].behaviour)
                    {
                        //Relay
                        runtimeData.weaponsInUseDataObjects[i].behaviour.OnTriggerExitRelay(pb, runtimeData.weaponsInUseDataObjects[i], col);
                    }
                }
            }

            public override void OnDestroyRelay(Kit_PlayerBehaviour pb)
            {
                Kit_ModernWeaponManagerNetworkData runtimeData = pb.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;

                for (int i = 0; i < runtimeData.weaponsInUseDataObjects.Length; i++)
                {
                    if (runtimeData.weaponsInUseDataObjects[i].behaviour)
                    {
                        //Relay
                        runtimeData.weaponsInUseDataObjects[i].behaviour.OnDestroyRelay(pb, runtimeData.weaponsInUseDataObjects[i]);
                    }
                }
            }
        }
    }
}
ASSISTANT
Thanks for sharing the relevant `Kit_ModernWeaponManager` source! From the code, here are key observations relevant to adding/giving a weapon:

- `HasWeapon(Kit_PlayerBehaviour pb, int id)` returns **the slot index** or -1 if not owned.
- Weapons are managed in the `Kit_ModernWeaponManagerNetworkData.weaponsInUseDataObjects` array.
- New weapons are spawned and added via `NetworkReplaceWeapon` or during spawn/setup, but **there is no simple `TryGiveWeapon` method**.

---

## How to add/give a weapon to a player?

You need to:

1. Instantiate the weapon prefab for that weapon ID (via `Kit_IngameMain.instance.gameInformation.allWeapons[id].SetupSpawnData(...)`).
2. Spawn it on the network.
3. Add the spawned weapon's `NetworkIdentity.netId` to `Kit_ModernWeaponManagerNetworkData.weaponsInUseSync`.
4. This will cause the manager to sync the new weapon and add it to `weaponsInUseDataObjects`.

Fortunately, the method `NetworkReplaceWeapon` shows similar steps, so you can adapt it for adding a **new weapon at the first empty slot** or **at the end**.

---

# Here's a practical implementation for `TryGiveWeapon`:

```csharp
private bool TryGiveWeapon(Kit_ModernWeaponManager wpnManager, Kit_PlayerBehaviour player, int weaponID)
{
    if (player == null || wpnManager == null) return false;
    if (player.weaponManagerNetworkData == null) return false;

    // Get the player's network data for this weapon manager
    var runtimeData = player.weaponManagerNetworkData as MarsFPSKit.Weapons.Kit_ModernWeaponManagerNetworkData;
    if (runtimeData == null)
    {
        Debug.LogWarning("[Kit_WeaponPickup] Player's weaponManagerNetworkData is null or not Kit_ModernWeaponManagerNetworkData.");
        return false;
    }
    
    // Find a slot for the new weapon
    int slot = -1;

    // Try to find an empty slot or slot with "Kit_WeaponUnselectable" placeholder weapon to replace
    for (int i = 0; i < runtimeData.weaponsInUseDataObjects.Length; ++i)
    {
        var w = runtimeData.weaponsInUseDataObjects[i];
        if (w == null || w.behaviour == null || w.behaviour.GetType() == typeof(MarsFPSKit.Weapons.Kit_WeaponUnselectable))
        {
            slot = i;
            break;
        }
    }

    // If no empty slot found, add to the end (and expect the arrays support it)
    if (slot == -1)
    {
        slot = runtimeData.weaponsInUseDataObjects.Length;
    }

    try
    {
        // Spawn the weapon for the player at the found slot
        wpnManager.NetworkReplaceWeapon(player, slot, weaponID, 0, 0, new int[0]);
        return true;
    }
    catch (System.Exception e)
    {
        Debug.LogError("[Kit_WeaponPickup] Exception in TryGiveWeapon: " + e);
        return false;
    }
}
```

---

# How to fix your `Kit_WeaponPickup` script's relevant parts to integrate this:

Update your `TryGiveWeapon` in `Kit_WeaponPickup.cs` with the above.

Optionally, add ammo refill for existing weapons by forwarding to the weapon behaviours (if desired).

---

# Full minimal integration snippet in `Kit_WeaponPickup.cs`:

```csharp
using UnityEngine;
using MarsFPSKit;
using MarsFPSKit.Weapons;

public class Kit_WeaponPickup : MonoBehaviour
{
    public int weaponID = 1;
    private Kit_WeaponPickupRespawnManager respawnManager;

    private void Start()
    {
        if (respawnManager == null)
        {
            respawnManager = GetComponentInParent<Kit_WeaponPickupRespawnManager>();
            if (respawnManager == null)
            {
                Debug.LogWarning("[Kit_WeaponPickup] No Kit_WeaponPickupRespawnManager in parents or assigned.");
            }
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        if (!other.CompareTag("Player")) return;

        var player = other.GetComponent<Kit_PlayerBehaviour>();
        if (player == null) return;

        var wpnManager = player.weaponManager as Kit_ModernWeaponManager;
        if (wpnManager == null)
        {
            Debug.LogWarning("[Kit_WeaponPickup] Player's weaponManager is not Kit_ModernWeaponManager.");
            return;
        }

        int slot = wpnManager.HasWeapon(player, weaponID);
        if (slot != -1)
        {
            // Optionally implement ammo refill here if desired by accessing runtimeData directly    
            Debug.Log("[Kit_WeaponPickup] Player already has weapon.");
            return;
        }
        else
        {
            bool success = TryGiveWeapon(wpnManager, player, weaponID);
            if (!success)
            {
                Debug.LogWarning("[Kit_WeaponPickup] Failed to give weapon!");
                return;
            }
        }

        respawnManager?.PickupTaken();
    }

    private bool TryGiveWeapon(Kit_ModernWeaponManager wpnManager, Kit_PlayerBehaviour player, int weaponID)
    {
        if (player == null || wpnManager == null) return false;

        var runtimeData = player.weaponManagerNetworkData as Kit_ModernWeaponManagerNetworkData;
        if (runtimeData == null)
        {
            Debug.LogWarning("[Kit_WeaponPickup] Player's weaponManagerNetworkData is null or wrong type.");
            return false;
        }

        int slot = -1;
        for (int i = 0; i < runtimeData.weaponsInUseDataObjects.Length; ++i)
        {
            var w = runtimeData.weaponsInUseDataObjects[i];
            if (w == null || w.behaviour == null || w.behaviour.GetType() == typeof(Kit_WeaponUnselectable))
            {
                slot = i;
                break;
            }
        }
        if (slot == -1) slot = runtimeData.weaponsInUseDataObjects.Length;

        try
        {
            wpnManager.NetworkReplaceWeapon(player, slot, weaponID, 0, 0, new int[0]);
            return true;
        }
        catch (System.Exception e)
        {
            Debug.LogError("[Kit_WeaponPickup] Exception giving weapon: " + e);
            return false;
        }
    }
}
```

---

### This will:

- Check if player has weapon.
- If not, add the weapon in the next empty slot or at the end using `NetworkReplaceWeapon`.
- Notify the respawn manager to disable and respawn the pickup later.

---

If you want ammo refill logic for existing weapons let me know — that can be added by accessing `runtimeData.weaponsInUseDataObjects[slot].behaviour` and calling weapon-specific refill methods.

---

# TL;DR

**Your MMFPSE uses the `NetworkReplaceWeapon` method to add/replace weapons for a player. Use that to implement the `TryGiveWeapon` logic as above.**

---

Let me know if you want help implementing ammo refill or anything else!