/// <summary> /// <param name="sync"></param> arg determines if it sends the paint request using the API, and automatically checks skin ownership. Must be false for mod-added skins. /// </summary> public void PaintBlock(bool sync, IMyCubeGrid grid, Vector3I gridPosition, PaintMaterial paint, ulong originalSenderSteamId) { IMySlimBlock slim = grid.GetCubeBlock(gridPosition); if (sync) { grid.SkinBlocks(gridPosition, gridPosition, paint.ColorMask, paint.Skin?.String); if (paint.Skin.HasValue) { // check if skin was applied to alert player CheckSkinned[slim] = new CheckData(paint.Skin.Value); // add or replace SetUpdateMethods(UpdateFlags.UPDATE_AFTER_SIM, true); } } else { // NOTE getting a MySlimBlock and sending it straight to arguments avoids getting prohibited errors. MyCubeGrid gridInternal = (MyCubeGrid)grid; gridInternal.ChangeColorAndSkin(gridInternal.GetCubeBlock(gridPosition), paint.ColorMask, paint.Skin); if (paint.Skin.HasValue) { CheckSkinned.Remove(slim); // prevent alerting if skin gets changed into an always-owned one } } }
/// <summary> /// <param name="sync"></param> arg determines if it sends the paint request using the API, and automatically checks skin ownership. Must be false for mod-added skins. /// </summary> public void ReplaceColorInGrid(bool sync, IMyCubeGrid selectedGrid, BlockMaterial oldPaint, PaintMaterial paint, bool includeSubgrids, ulong originalSenderSteamId) { //long timeStart = Stopwatch.GetTimestamp(); ConnectedGrids.Clear(); if (includeSubgrids) { MyAPIGateway.GridGroups.GetGroup(selectedGrid, GridLinkTypeEnum.Mechanical, ConnectedGrids); } else { ConnectedGrids.Add(selectedGrid); } bool queueCheck = paint.Skin.HasValue; // only care if new paint affects skin //int total = 0; int affected = 0; foreach (IMyCubeGrid grid in ConnectedGrids) { MyCubeGrid internalGrid = (MyCubeGrid)grid; // avoiding GetCubeBlock() lookup by feeding MySlimBlock directly // must remain `var` because it's uses a prohibited type in the generic. var enumerator = internalGrid.CubeBlocks.GetEnumerator(); try { while (enumerator.MoveNext()) { IMySlimBlock block = enumerator.Current; BlockMaterial blockMaterial = new BlockMaterial(block); if (paint.Skin.HasValue && blockMaterial.Skin != oldPaint.Skin) { continue; } if (paint.ColorMask.HasValue && !Utils.ColorMaskEquals(blockMaterial.ColorMask, oldPaint.ColorMask)) { continue; } if (sync) { grid.SkinBlocks(block.Position, block.Position, paint.ColorMask, paint.Skin?.String); if (queueCheck) { queueCheck = false; // only check first block CheckSkinned[block] = new CheckData(paint.Skin.Value); // replace, in case they swap out skins quickly } } else { internalGrid.ChangeColorAndSkin(enumerator.Current, paint.ColorMask, paint.Skin); if (queueCheck) { queueCheck = false; // only check first block CheckSkinned.Remove(block); } } affected++; } } finally { enumerator.Dispose(); } //total += grid.CubeBlocks.Count; } if (CheckSkinned.Count > 0) { SetUpdateMethods(UpdateFlags.UPDATE_AFTER_SIM, true); } //long timeEnd = Stopwatch.GetTimestamp(); if (originalSenderSteamId == MyAPIGateway.Multiplayer.MyId) { Main.Notifications.Show(2, $"Replaced color for {affected.ToString()} blocks.", MyFontEnum.Debug, 5000); //double seconds = (timeEnd - timeStart) / (double)Stopwatch.Frequency; //if(affected == total) // Main.Notifications.Show(2, $"Replaced color for all {affected.ToString()} blocks in {(seconds * 1000).ToString("0.######")}ms", MyFontEnum.White, 5000); //else // Main.Notifications.Show(2, $"Replaced color for {affected.ToString()} of {total.ToString()} blocks in {(seconds * 1000).ToString("0.######")}ms", MyFontEnum.White, 5000); } ConnectedGrids.Clear(); }