public override ModularPlacableObject Duplicate()
        {
            ModularSetStoreData SetData = new ModularSetStoreData(this);
            ModularSet          NewSet  = Management.GameManager.I.Modular.ModularBuildingSystem.InitNewModularSet(this);

            NewSet.AsyncLoadModularSet(SetData, (object[] Data) => {
                ModularSet Set = (ModularSet)Data[0];                                                                                                 // get set data
                ModularPieceSaveData PieceData = (ModularPieceSaveData)Data[1];                                                                       // get piece data
                Set.AddModularPiece(Management.GameManager.I.Modular.ModularBuildingSystem.InitStoreItem(PieceData), (ModularPlacableData)PieceData); // add store item
            });
            NewSet.gameObject.layer = this.gameObject.layer;                                                                                          // set layer
            NewSet.RegisterUndoable();                                                                                                                // register as undoable
            return(NewSet);
        }
        private ModularSet InitModularSetCore(ModularSet NewSet, ModularSetData SetData, bool InitInEditMode = false)
        {
            if (InitInEditMode)
            {
                NewSet.InitializeEditable();
            }                                                                   // init in edit mode
            NewSet.AsyncLoadModularSet(SetData, (object[] Data) => {
                ModularSet Set = (ModularSet)Data[0];                           // get set data
                ModularPieceSaveData PieceData = (ModularPieceSaveData)Data[1]; // get piece data

                ModularPiece Piece = InitStoreItem(PieceData);                  // init store item to modular piece
                if (Piece != null)                                              // only add when piece is not null
                {
                    Set.AddModularPiece(Piece, (ModularPlacableData)PieceData); // add store item
                }
            });
            return(NewSet);
        }         // core function for init modular set
        public void PlaceModularPieceAsSet(ModularPieceData Piece, Vector3 Scale, System.Func <ModularPlacableObject, bool> CanPlace, Vector3 RotationOffset = default(Vector3), Vector3 InitRotation = default(Vector3), Vector3 InitPosition = default(Vector3), object[] ExtraData = default(object[]), bool Interrupt = false)
        {
            ModularSet Set = InitNewModularSet();                                                                                                     // create new modular set

            Set.InitializeEditable();                                                                                                                 // init as editable
            GameManager.I.Modular.ScopedSet = Set;                                                                                                    // set new scoped set
            ModularPlacableObject NewPlacableObject = (ModularPlacableObject)InitStoreItem(Piece, Scale, RotationOffset, InitRotation, InitPosition); // init modular piece afther setting the scoped set

            PlaceModularPlacable(NewPlacableObject, (object[] data) => {
                // on object is placed
                ModularPiece PlacedPiece  = (ModularPiece)data.Find <ModularPiece>();                                                                  // get modular piece
                LocalGridSystem LocalGrid = (LocalGridSystem)data.Find <LocalGridSystem>();                                                            // get last local grid
                PlacePlacableObject.PlaceObjectCache Cache = (PlacePlacableObject.PlaceObjectCache)data.Find <PlacePlacableObject.PlaceObjectCache>(); // get last state cache
                PlacedPiece.InitializeEditable();                                                                                                      // initialize editable modular piece
                PlacedPiece.OnPlaced();                                                                                                                // call on placed callback

                // Economy
                int Price = GameManager.I.Economy.EvaluateModularPiece(Piece);
                GameManager.I.Economy.RemoveMoney(Price);
                GameManager.I.Economy.SpawnMoneyIndicator(PlacedPiece.transform.position, Price);

                // add piece to set
                Set.AddModularPiece(PlacedPiece);
                Set.Name = PlacedPiece.name;
                Set.FinalizeSet(GameManager.I.Modular.ModularPieceLayer, true);                 // finalize set

                // place new modular piece with last rotation
                PlaceModularPieceAsSet(Piece, Scale, CanPlace, PlacedPiece.RotationOffset.eulerAngles, PlacedPiece.NoneOffsettedRotation.eulerAngles, PlacedPiece.transform.position, new object[] { LocalGrid, Cache });
            }, CanPlace, (Data) => {
                // on canceled
                GameManager.I.Modular.ScopedSet.DeregisterPlacingObject();       // de register object
                ModularPlacableObject PlacableObject = (ModularPlacableObject)Data.Find <ModularPlacableObject>();
                PlacableObject.Destroy();                                        // destroy on cancle
                Set.FinalizeSet(GameManager.I.Modular.ModularPieceLayer, false); // finalize set

                Statemachine.changeState(new ModularSpectate(), this);
            }, SnapTypes.Default, ExtraData, Interrupt);          // place new created store modular piece
            Set.RegisterPlacingObject(NewPlacableObject);         // register new placable object to be placed inside building
        }