Exemplo n.º 1
0
    private void Update()
    {
        if (state == State.SELECTING)
        {
            // ignore when we are over UI
            if (EventSystem.current.IsPointerOverGameObject())
            {
                return;
            }

            //check which objects we are over, pick the top one to spawn
            if (CommonInput.GetMouseButtonDown(0))
            {
                //NOTE: Avoiding multiple enumeration by converting IEnumerables to lists.
                var hitGOs = MouseUtils.GetOrderedObjectsUnderMouse(layerMask,
                                                                    go => go.GetComponent <CustomNetTransform>() != null).ToList();
                //warn about objects which cannot be cloned
                var nonPooledHits = hitGOs
                                    .Where(go => Spawn.DeterminePrefab(go) == null).ToList();
                if (nonPooledHits.Any())
                {
                    foreach (GameObject nonPooled in nonPooledHits)
                    {
                        Logger.LogWarningFormat("Object {0} does not have a PoolPrefabTracker component and its name" +
                                                " did not match one of our existing prefabs " +
                                                "therefore cannot be cloned (because we wouldn't know which prefab to instantiate). " +
                                                "Please attach this component to the object and specify the prefab" +
                                                " to allow it to be cloned.", Category.ItemSpawn, nonPooled.name);
                    }
                }

                var pooledHits = hitGOs.Where(go => Spawn.DeterminePrefab(go) != null).ToList();
                if (pooledHits.Any())
                {
                    toClone = pooledHits.First();
                    ToState(State.DRAWING);
                }
            }
        }
        else if (state == State.DRAWING)
        {
            cursorObject.transform.position = Camera.main.ScreenToWorldPoint(CommonInput.mousePosition);
            if (CommonInput.GetMouseButtonDown(0))
            {
                Vector3Int position = cursorObject.transform.position.RoundToInt();
                position.z = 0;
                if (MatrixManager.IsPassableAtAllMatricesOneTile(position, false))
                {
                    if (CustomNetworkManager.IsServer)
                    {
                        Spawn.ServerClone(toClone, position);
                    }
                    else
                    {
                        DevCloneMessage.Send(toClone, (Vector3)position, ServerData.UserID, PlayerList.Instance.AdminToken);
                    }
                }
            }
        }
    }
Exemplo n.º 2
0
    public SpawnableResult SpawnAt(SpawnDestination destination)
    {
        var prefab = Spawn.DeterminePrefab(toClone);

        if (prefab == null)
        {
            Logger.LogErrorFormat(
                "Object {0} cannot be cloned because it has no PoolPrefabTracker and its name" +
                " does not match a prefab name, so we cannot" +
                " determine the prefab to instantiate. Please fix this object so that it" +
                " has an attached PoolPrefabTracker or so its name matches the prefab it was created from.",
                Category.ItemSpawn, toClone);
            return(SpawnableResult.Fail(destination));
        }

        GameObject tempObject = Spawn._PoolInstantiate(prefab, destination,
                                                       out var isPooled);

        if (!isPooled)
        {
            NetworkServer.Spawn(tempObject);
            tempObject.GetComponent <CustomNetTransform>()
            ?.NotifyPlayers();                     //Sending clientState for newly spawned items
        }

        return(SpawnableResult.Single(tempObject, destination));
    }
Exemplo n.º 3
0
    /// <summary>
    /// Special type of spawn, performed on each object mapped in the scene once the scene is done loading.
    /// </summary>
    /// <param name="mappedObject">object which was mapped into the scene.</param>
    /// <returns></returns>
    public static SpawnInfo Mapped(GameObject mappedObject)
    {
        var destination = SpawnDestination.At(mappedObject);
        //assume prefab
        var prefab    = Spawn.DeterminePrefab(mappedObject);
        var spawnable = SpawnablePrefab.For(prefab);

        return(new SpawnInfo(SpawnType.Mapped, spawnable, destination, null, 1, null));
    }
Exemplo n.º 4
0
 private void InitStacksWith()
 {
     if (stacksWith == null)
     {
         stacksWith = new List <GameObject>();
     }
     prefab = Spawn.DeterminePrefab(gameObject);
     if (prefab != null && !stacksWith.Contains(prefab))
     {
         stacksWith.Add(prefab);
     }
 }
Exemplo n.º 5
0
    public void CmdSplitStack(uint fromSlotID, NamedSlot fromSlot, int amountToTransfer)
    {
        if (fromSlot != NamedSlot.leftHand && fromSlot != NamedSlot.rightHand)
        {
            return;                                                                            //Only allowed to transfer from one hand to another
        }
        if (!Validations.CanInteract(playerScript, NetworkSide.Server, allowCuffed: false))
        {
            return;                                                                                         //Not allowed to transfer while cuffed
        }
        if (!Cooldowns.TryStartServer(playerScript, CommonCooldowns.Instance.Interaction))
        {
            return;
        }

        ItemSlot emptySlot = PlayerManager.LocalPlayerScript.DynamicItemStorage.GetActiveHandSlot();         //Were assuming that slot to which player wants to transfer stuff is always active hand

        if (NetworkIdentity.spawned.TryGetValue(fromSlotID, out var objFS) == false)
        {
            return;
        }
        var stackSlot = itemStorage.GetNamedItemSlot(objFS.gameObject, fromSlot);

        if (stackSlot.ServerIsObservedBy(gameObject) == false || emptySlot.ServerIsObservedBy(gameObject) == false)
        {
            return;                                                                                                                 //Checking if we can observe our hands
        }
        if (stackSlot.ItemObject == null || emptySlot.ItemObject != null)
        {
            return;
        }
        if (stackSlot.ItemObject.TryGetComponent <Stackable>(out var stackSlotStackable) == false)
        {
            return;
        }
        if (stackSlotStackable.Amount < amountToTransfer || amountToTransfer <= 0)
        {
            return;
        }

        var multiple = Spawn.ServerPrefab(Spawn.DeterminePrefab(stackSlot.ItemObject)).GameObject;

        multiple.GetComponent <Stackable>().ServerSetAmount(amountToTransfer);
        Inventory.ServerAdd(multiple, emptySlot);
        stackSlotStackable.ServerConsume(amountToTransfer);
    }
Exemplo n.º 6
0
    /// <summary>
    /// Special type of spawn, performed on each object mapped in the scene once the scene is done loading.
    /// </summary>
    /// <param name="mappedObject">object which was mapped into the scene.</param>
    /// <returns></returns>
    public static SpawnInfo Mapped(GameObject mappedObject)
    {
        //is it a prefab or cloth?
        var clothing = mappedObject.GetComponent <Clothing>();

        if (clothing == null)
        {
            //assume prefab
            var prefab = Spawn.DeterminePrefab(mappedObject);
            return(new SpawnInfo(SpawnableType.Prefab, SpawnType.Mapped, prefab, null, ClothingVariantType.Default, -1,
                                 mappedObject.WorldPosServer(),
                                 mappedObject.transform.parent, mappedObject.transform.rotation, null, 1, null));
        }
        else
        {
            //assume cloth
            return(new SpawnInfo(SpawnableType.Cloth, SpawnType.Mapped, null, clothing.clothingData, clothing.Type,
                                 clothing.Variant,
                                 mappedObject.WorldPosServer(),
                                 mappedObject.transform.parent, mappedObject.transform.rotation, null, 1, null));
        }
    }
Exemplo n.º 7
0
    public SpawnableResult SpawnAt(SpawnDestination destination)
    {
        var prefab = Spawn.DeterminePrefab(toClone);

        if (prefab == null)
        {
            Logger.LogErrorFormat(
                "Object {0} cannot be cloned because it has no PoolPrefabTracker and its name" +
                " does not match a prefab name, so we cannot" +
                " determine the prefab to instantiate. Please fix this object so that it" +
                " has an attached PoolPrefabTracker or so its name matches the prefab it was created from.",
                Category.ItemSpawn, toClone);
            return(SpawnableResult.Fail(destination));
        }

        if (Spawn._ObjectPool.TryPoolInstantiate(prefab, destination, false, out var spawnedObject))
        {
            return(SpawnableResult.Single(spawnedObject, destination));
        }
        else
        {
            return(SpawnableResult.Fail(destination));
        }
    }
Exemplo n.º 8
0
    public override IEnumerator Process()
    {
        var clientStorage = SentByPlayer.Script.ItemStorage;
        var usedSlot      = clientStorage.GetActiveHandSlot();

        if (usedSlot == null || usedSlot.ItemObject == null)
        {
            yield break;
        }

        var hasConstructionMenu = usedSlot.ItemObject.GetComponent <BuildingMaterial>();

        if (hasConstructionMenu == null)
        {
            yield break;
        }

        var entry = hasConstructionMenu.BuildList.Entries.ToArray()[EntryIndex];

        if (!entry.CanBuildWith(hasConstructionMenu))
        {
            yield break;
        }

        //check if the space to construct on is passable
        if (!MatrixManager.IsPassableAt((Vector3Int)SentByPlayer.GameObject.TileWorldPosition(), true, includingPlayers: false))
        {
            Chat.AddExamineMsg(SentByPlayer.GameObject, "It won't fit here.");
            yield break;
        }

        //if we are building something impassable, check if there is anything on the space other than the performer.
        var atPosition =
            MatrixManager.GetAt <RegisterTile>((Vector3Int)SentByPlayer.GameObject.TileWorldPosition(), true);

        if (entry.Prefab == null)
        {
            //requires immediate attention, show it regardless of log filter:
            Logger.Log($"Construction entry is missing prefab for {entry.Name}");
            yield break;
        }

        var registerTile = entry.Prefab.GetComponent <RegisterTile>();

        if (registerTile == null)
        {
            Logger.LogWarningFormat("Buildable prefab {0} has no registerTile, no idea if it's passable", Category.Construction, entry.Prefab);
        }
        var builtObjectIsImpassable = registerTile == null || !registerTile.IsPassable(true);

        foreach (var thingAtPosition in atPosition)
        {
            if (entry.OnePerTile)
            {
                //can only build one of this on a given tile
                if (entry.Prefab.Equals(Spawn.DeterminePrefab(thingAtPosition.gameObject)))
                {
                    Chat.AddExamineMsg(SentByPlayer.GameObject, $"There's already one here.");
                    yield break;
                }
            }

            if (builtObjectIsImpassable)
            {
                //if the object we are building is itself impassable, we should check if anything blocks construciton.
                //otherwise it's fine to add it to the pile on the tile
                if (ServerValidations.IsConstructionBlocked(SentByPlayer.GameObject, null,
                                                            SentByPlayer.GameObject.TileWorldPosition()))
                {
                    yield break;
                }
            }
        }

        //build and consume
        void ProgressComplete()
        {
            if (entry.ServerBuild(SpawnDestination.At(SentByPlayer.Script.registerTile), hasConstructionMenu))
            {
                Chat.AddActionMsgToChat(SentByPlayer.GameObject, $"You finish building the {entry.Name}.",
                                        $"{SentByPlayer.GameObject.ExpensiveName()} finishes building the {entry.Name}.");
            }
        }

        Chat.AddActionMsgToChat(SentByPlayer.GameObject, $"You begin building the {entry.Name}...",
                                $"{SentByPlayer.GameObject.ExpensiveName()} begins building the {entry.Name}...");
        ToolUtils.ServerUseTool(SentByPlayer.GameObject, usedSlot.ItemObject,
                                ActionTarget.Tile(SentByPlayer.Script.registerTile.WorldPositionServer), entry.BuildTime,
                                ProgressComplete);
    }