/// <summary> /// Generates a list of all owners of the cubegrid and all grids that are statically attached to it. /// </summary> /// <param name="cubeGrid"></param> /// <returns></returns> public static List <long> GetAllSmallOwners(this IMyCubeGrid cubeGrid) { List <IMyCubeGrid> allGrids = cubeGrid.GetAttachedGrids(AttachedGrids.Static); HashSet <long> allSmallOwners = new HashSet <long>(); foreach (var owner in allGrids.SelectMany(myCubeGrid => myCubeGrid.SmallOwners)) { allSmallOwners.Add(owner); } return(allSmallOwners.ToList()); }
// TODO: deal with cubes that need to be rotated. // LargeBlockBeacon, SmallBlockBeacon, ConveyorTube, ConveyorTubeSmall private bool ScaleShip(ulong steamId, IMyCubeGrid shipEntity, MyCubeSize newScale) { if (shipEntity == null) { return(false); } if (shipEntity.GridSizeEnum == newScale) { MyAPIGateway.Utilities.SendMessage(steamId, "scaledown", "Ship is already the right scale."); return(true); } var grids = shipEntity.GetAttachedGrids(); var newGrids = new MyObjectBuilder_CubeGrid[grids.Count]; foreach (var cubeGrid in grids) { // ejects any player prior to deleting the grid. cubeGrid.EjectControllingPlayers(); cubeGrid.Physics.Enabled = false; } var tempList = new List <MyObjectBuilder_EntityBase>(); var gridIndex = 0; foreach (var cubeGrid in grids) { var blocks = new List <IMySlimBlock>(); cubeGrid.GetBlocks(blocks); var gridObjectBuilder = cubeGrid.GetObjectBuilder(true) as MyObjectBuilder_CubeGrid; gridObjectBuilder.EntityId = 0; Regex rgx = new Regex(Regex.Escape(gridObjectBuilder.GridSizeEnum.ToString())); var rgxScale = Regex.Escape(newScale.ToString()); gridObjectBuilder.GridSizeEnum = newScale; var removeList = new List <MyObjectBuilder_CubeBlock>(); foreach (var block in gridObjectBuilder.CubeBlocks) { MyCubeBlockDefinition definition; string newSubType = null; if (newScale == MyCubeSize.Small && LargeToSmall.ContainsKey(block.SubtypeName)) { newSubType = LargeToSmall[block.SubtypeName]; } else if (newScale == MyCubeSize.Large && SmallToLarge.ContainsKey(block.SubtypeName)) { newSubType = SmallToLarge[block.SubtypeName]; } else { newSubType = rgx.Replace(block.SubtypeName, rgxScale, 1); // Match using the BlockPairName if there is a matching cube. if (MyDefinitionManager.Static.TryGetCubeBlockDefinition(new MyDefinitionId(block.GetType(), block.SubtypeName), out definition)) { var newDef = MyDefinitionManager.Static.GetAllDefinitions().Where(d => d is MyCubeBlockDefinition && ((MyCubeBlockDefinition)d).BlockPairName == definition.BlockPairName && ((MyCubeBlockDefinition)d).CubeSize == newScale).FirstOrDefault(); if (newDef != null) { newSubType = newDef.Id.SubtypeName; } } } if (MyDefinitionManager.Static.TryGetCubeBlockDefinition(new MyDefinitionId(block.GetType(), newSubType), out definition) && definition.CubeSize == newScale) { block.SubtypeName = newSubType; //block.EntityId = 0; } else { removeList.Add(block); } } foreach (var block in removeList) { gridObjectBuilder.CubeBlocks.Remove(block); } // This will Delete the entity and sync to all. // Using this, also works with player ejection in the same Tick. cubeGrid.SyncObject.SendCloseRequest(); var name = cubeGrid.DisplayName; MyAPIGateway.Utilities.SendMessage(steamId, "ship", "'{0}' resized.", name); tempList.Add(gridObjectBuilder); gridIndex++; } // TODO: reposition multiple grids so rotors and pistons re-attach. tempList.CreateAndSyncEntities(); return(true); }
private void _cubeGrid_OnBlockOwnershipChanged(IMyCubeGrid cubeGrid) { // only execute on server instance if (ChatCommandLogic.Instance != null && ChatCommandLogic.Instance.ServerCfg == null) { return; } if (_firstOwnershipChange) { _firstOwnershipChange = false; _cachedOwners = new List <long>(cubeGrid.GetAllSmallOwners()); return; } var allSmallOwners = cubeGrid.GetAllSmallOwners(); if (_cachedOwners == allSmallOwners) { return; } // if the grid wasn't owned or a owner was removed, we dont need to do anything but update the cached owners if (_cachedOwners.Count == 0 || _cachedOwners.Count > allSmallOwners.Count) { _cachedOwners = new List <long>(allSmallOwners); return; } var newOwners = allSmallOwners.Except(_cachedOwners).ToList(); if (newOwners.Count == 0) { return; } if (!ProtectionHandler.IsProtected(cubeGrid)) { _cachedOwners = new List <long>(allSmallOwners); return; } Dictionary <long, int> blocksPerOwner = new Dictionary <long, int>(); foreach (IMyCubeGrid attachedCubeGrid in cubeGrid.GetAttachedGrids(AttachedGrids.Static)) { List <IMySlimBlock> blocks = new List <IMySlimBlock>(); attachedCubeGrid.GetBlocks(blocks, b => b.FatBlock != null); foreach (IMySlimBlock block in blocks) { long ownerId = block.FatBlock.OwnerId; // we dont want the new owners, the small owners or the 'nobody' (0) if (ownerId == 0 || !attachedCubeGrid.BigOwners.Contains(ownerId) || newOwners.Contains(ownerId)) { continue; } if (!blocksPerOwner.ContainsKey(ownerId)) { blocksPerOwner.Add(ownerId, 1); } else { blocksPerOwner[ownerId]++; } } } var sortedBpo = new List <KeyValuePair <long, int> >(blocksPerOwner.OrderBy(pair => pair.Value)); // if we cannot identify an owner we allow the change if (sortedBpo.Count == 0) { _cachedOwners = new List <long>(allSmallOwners); return; } var bigOwner = sortedBpo[0].Key; List <IMySlimBlock> ownershipChangedBlocks = new List <IMySlimBlock>(); cubeGrid.GetBlocks(ownershipChangedBlocks, b => b.FatBlock != null && newOwners.Contains(b.FatBlock.OwnerId)); foreach (IMySlimBlock slimBlock in ownershipChangedBlocks) { var block = (Sandbox.Game.Entities.MyCubeBlock)slimBlock.FatBlock; // TODO check if the block was created/built just moments ago, do not change owner otherwise block.ChangeOwner(bigOwner, MyOwnershipShareModeEnum.None); ConnectionHelper.SendMessageToAllPlayers(new MessageSyncBlockOwner() { OwnerId = bigOwner, EntityId = block.EntityId }); // no need to update the cached owners as we don't want them to change } // TODO maybe allow the faction to build... }
// TODO: deal with cubes that need to be rotated. // LargeBlockBeacon, SmallBlockBeacon, ConveyorTube, ConveyorTubeSmall public static bool ScaleShip(IMyCubeGrid shipEntity, MyCubeSize newScale) { if (shipEntity == null) return false; if (shipEntity.GridSizeEnum == newScale) { MyAPIGateway.Utilities.ShowMessage("scaledown", "Ship is already the right scale."); return true; } var grids = shipEntity.GetAttachedGrids(); var newGrids = new MyObjectBuilder_CubeGrid[grids.Count]; foreach (var cubeGrid in grids) { // ejects any player prior to deleting the grid. cubeGrid.EjectControllingPlayers(); cubeGrid.Physics.Enabled = false; } var tempList = new List<MyObjectBuilder_EntityBase>(); var gridIndex = 0; foreach (var cubeGrid in grids) { var blocks = new List<Sandbox.ModAPI.IMySlimBlock>(); cubeGrid.GetBlocks(blocks); var gridObjectBuilder = cubeGrid.GetObjectBuilder(true) as MyObjectBuilder_CubeGrid; gridObjectBuilder.EntityId = 0; Regex rgx = new Regex(Regex.Escape(gridObjectBuilder.GridSizeEnum.ToString())); var rgxScale = Regex.Escape(newScale.ToString()); gridObjectBuilder.GridSizeEnum = newScale; var removeList = new List<MyObjectBuilder_CubeBlock>(); foreach (var block in gridObjectBuilder.CubeBlocks) { MyCubeBlockDefinition defintion; string newSubType = null; if (newScale == MyCubeSize.Small && LargeToSmall.ContainsKey(block.SubtypeName)) newSubType = LargeToSmall[block.SubtypeName]; else if (newScale == MyCubeSize.Large && SmallToLarge.ContainsKey(block.SubtypeName)) newSubType = SmallToLarge[block.SubtypeName]; else { newSubType = rgx.Replace(block.SubtypeName, rgxScale, 1); // Match using the BlockPairName if there is a matching cube. if (MyDefinitionManager.Static.TryGetCubeBlockDefinition(new MyDefinitionId(block.GetType(), block.SubtypeName), out defintion)) { var newDef = MyDefinitionManager.Static.GetAllDefinitions().Where(d => d is MyCubeBlockDefinition && ((MyCubeBlockDefinition)d).BlockPairName == defintion.BlockPairName && ((MyCubeBlockDefinition)d).CubeSize == newScale).FirstOrDefault(); if (newDef != null) newSubType = newDef.Id.SubtypeName; } } if (MyDefinitionManager.Static.TryGetCubeBlockDefinition(new MyDefinitionId(block.GetType(), newSubType), out defintion) && defintion.CubeSize == newScale) { block.SubtypeName = newSubType; //block.EntityId = 0; } else { removeList.Add(block); } } foreach (var block in removeList) { gridObjectBuilder.CubeBlocks.Remove(block); } // This will Delete the entity and sync to all. // Using this, also works with player ejection in the same Tick. cubeGrid.SyncObject.SendCloseRequest(); var name = cubeGrid.DisplayName; MyAPIGateway.Utilities.ShowMessage("ship", "'{0}' resized.", name); tempList.Add(gridObjectBuilder); gridIndex++; } // TODO: reposition multiple grids so rotors and pistons re-attach. tempList.CreateAndSyncEntities(); return true; }
private void _cubeGrid_OnBlockOwnershipChanged(IMyCubeGrid cubeGrid) { // only execute on server instance if (ChatCommandLogic.Instance != null && ChatCommandLogic.Instance.ServerCfg == null) return; if (_firstOwnershipChange) { _firstOwnershipChange = false; _cachedOwners = new List<long>(cubeGrid.GetAllSmallOwners()); return; } var allSmallOwners = cubeGrid.GetAllSmallOwners(); if (_cachedOwners == allSmallOwners) return; // if the grid wasn't owned or a owner was removed, we dont need to do anything but update the cached owners if (_cachedOwners.Count == 0 || _cachedOwners.Count > allSmallOwners.Count) { _cachedOwners = new List<long>(allSmallOwners); return; } var newOwners = allSmallOwners.Except(_cachedOwners).ToList(); if (newOwners.Count == 0) return; if (!ProtectionHandler.IsProtected(cubeGrid)) { _cachedOwners = new List<long>(allSmallOwners); return; } Dictionary<long, int> blocksPerOwner = new Dictionary<long, int>(); foreach (IMyCubeGrid attachedCubeGrid in cubeGrid.GetAttachedGrids(AttachedGrids.Static)) { List<IMySlimBlock> blocks = new List<IMySlimBlock>(); attachedCubeGrid.GetBlocks(blocks, b => b.FatBlock != null); foreach (IMySlimBlock block in blocks) { long ownerId = block.FatBlock.OwnerId; // we dont want the new owners, the small owners or the 'nobody' (0) if (ownerId == 0 || !attachedCubeGrid.BigOwners.Contains(ownerId) || newOwners.Contains(ownerId)) continue; if (!blocksPerOwner.ContainsKey(ownerId)) blocksPerOwner.Add(ownerId, 1); else blocksPerOwner[ownerId]++; } } var sortedBpo = new List<KeyValuePair<long, int>>(blocksPerOwner.OrderBy(pair => pair.Value)); // if we cannot identify an owner we allow the change if (sortedBpo.Count == 0) { _cachedOwners = new List<long>(allSmallOwners); return; } var bigOwner = sortedBpo[0].Key; List<IMySlimBlock> ownershipChangedBlocks = new List<IMySlimBlock>(); cubeGrid.GetBlocks(ownershipChangedBlocks, b => b.FatBlock != null && newOwners.Contains(b.FatBlock.OwnerId)); foreach (IMySlimBlock slimBlock in ownershipChangedBlocks) { var block = (Sandbox.Game.Entities.MyCubeBlock)slimBlock.FatBlock; block.ChangeOwner(bigOwner, MyOwnershipShareModeEnum.None); ConnectionHelper.SendMessageToAllPlayers(new MessageSyncBlockOwner() {OwnerId = bigOwner, EntityId = block.EntityId}); // no need to update the cached owners as we don't want them to change } // TODO maybe allow the faction to build... }