VRageMath.Vector3D? IMyCubeGrid.GetLineIntersectionExactAll(ref VRageMath.LineD line, out double distance, out IMySlimBlock intersectedBlock) { MySlimBlock block; var retVal = GetLineIntersectionExactAll(ref line, out distance, out block); intersectedBlock = block; return retVal; }
public HullClassifier(IMySlimBlock block) { SlimBlock = block; FatBlock = block.FatBlock; m_SubTypeName = FatBlock.BlockDefinition.SubtypeName; Class = HullClassFromSubTypeString(m_SubTypeName); }
/// <summary> /// If we recognize the block's subtype as belonging to a classifier, return true /// </summary> public static bool isClassifierBlock(IMySlimBlock block) { IMyCubeBlock fatblock = block.FatBlock; if (fatblock != null && fatblock is Ingame.IMyBeacon) { String subTypeName = fatblock.BlockDefinition.SubtypeName; if (subTypeName.Contains(SHARED_SUBTYPE)) return true; } return false; }
public bool Contains(IMySlimBlock block) { if (block.CubeGrid == null) return false; // FatBlock is null for non functional blocks such as armor if (block.FatBlock != null) return Contains(block.FatBlock); // since some blocks aren't an entity we have to deal with them otherwise // we'll create an grid that acts as substitute for the block to get an entity that has a collision // TODO find a better suited way to get the boundings of an armor block var worldPosition = block.CubeGrid.GetPosition() + block.Position; // creating grid var gridBuilder = new MyObjectBuilder_CubeGrid() { PersistentFlags = MyPersistentEntityFlags2.None, PositionAndOrientation = new MyPositionAndOrientation(worldPosition, Vector3.Forward, Vector3.Up), DisplayName = "substitute", GridSizeEnum = block.CubeGrid.GridSizeEnum }; // creating cube block MyObjectBuilder_CubeBlock cube = new MyObjectBuilder_CubeBlock(); cube.Min = block.Position; cube.SubtypeName = block.CubeGrid.GridSizeEnum == MyCubeSize.Large ? "LargeBlockArmorBlock" : "SmallBlockArmorBlock"; cube.BuildPercent = 0; gridBuilder.CubeBlocks.Add(cube); // add grid MyAPIGateway.Entities.RemapObjectBuilder(gridBuilder); var entity = MyAPIGateway.Entities.CreateFromObjectBuilder(gridBuilder); var grid = entity as IMyCubeGrid; var blocks = new List<IMySlimBlock>(); // get blocks grid.GetBlocks(blocks, b => b != null); if (blocks.Count > 0) { // found block var cubeBlock = blocks[0].FatBlock; bool isInside = Contains(cubeBlock); grid.Close(); return isInside; } return false; }
/// <summary> /// if added is a thruster, call newThruster() /// </summary> /// <param name="added">block that was added</param> private void grid_OnBlockAdded(IMySlimBlock added) { MainLock.MainThread_ReleaseExclusive(); try { if (added.FatBlock == null) return; if (added.FatBlock is IMyThrust) newThruster(added); } catch (Exception e) { myLogger.alwaysLog("Exception: " + e, "grid_OnBlockAdded()", Logger.severity.ERROR); } finally { MainLock.MainThread_AcquireExclusive(); } }
/// <summary> /// Does the passed block belong to this group? /// </summary> public bool appliesToBlock(IMySlimBlock block) { // IMySlimBlock.ToString() does: // FatBlock != null ? FatBlock.ToString() : BlockDefinition.DisplayNameText.ToString(); // which is nice since we're not allowed access to BlockDefinition of a SlimBlock String blockString = block.ToString().ToLower(); log("Does " + blockString + " belong in group " + SubTypeStrings.ToString() + " ? ", "appliedToBlock", Logger.severity.TRACE); foreach (String subType in SubTypeStrings) { if (blockString.Contains(subType.ToLower())) { log("It does!", "appliedToBlock", Logger.severity.TRACE); return true; } } log("It doesn't", "appliedToBlock", Logger.severity.TRACE); return false; }
public static void grid_OnBlockAdded(IMySlimBlock obj) { try { Logger.Log.Debug("BeaconSecurity.grid_OnBlockAdded {0}", obj); MyCubeGrid grid = obj.CubeGrid as MyCubeGrid; if (grid == null) return; bool removing = false; if (!grid.DestructibleBlocks && Core.Settings != null && Core.Settings.BuildingNotAllowed) { Logger.Log.Debug(" * DestructibleBlocks {0}, so block removed...", grid.DestructibleBlocks); removing = true; } // check admins grids if (Core.Settings != null && Core.Settings.IndestructibleNoBuilds && Core.Settings.Indestructible.Contains(grid.EntityId) && !Core.Settings.IndestructibleOverrideBuilds.Contains(grid.EntityId)) { Logger.Log.Debug(" * Target '{0}' in indestructible list, so block removed...", grid.DisplayName); removing = true; } if (removing) { Logger.Log.Debug("RTY Grid: {0} {1} OBJ: {2} {3} POS: {4} {5}", grid, grid is IMyCubeGrid, obj, obj is IMySlimBlock, obj.Position, obj.CubeGrid.PositionComp); Core.EnqueueRemoveBlock(obj); //m_handler = new MyTimer.TimerEventHandler((a, b, c, d, e) => //{ // TryToRemoveBlockFromGrid((grid as IMyCubeGrid), obj); //}); //MyTimer.StartOneShot(10, m_handler); } } catch (Exception ex) { Logger.Log.Error("Exception grid_OnBlockAdded in {0}", ex.Message); } }
public WeldBlock(Mover mover, AllNavigationSettings navSet, PseudoBlock welder, IMySlimBlock block) : base(mover, navSet) { this.m_logger = new Logger(GetType().Name, () => mover.Block.CubeGrid.DisplayName, () => block.getBestName(), () => m_stage.ToString()); this.m_offset = welder.Block.LocalAABB.GetLongestDim() * 0.5f; // this works for default welders, may not work if mod has an exotic design this.m_welder = welder; this.m_targetSlim = block; this.m_timeout_start = Globals.UpdateCount + TimeoutStart; IMyCubeBlock Projector = ((MyCubeGrid)block.CubeGrid).Projector; if (Projector != null) { this.m_weldProjection = true; this.m_otherGrid = Projector.CubeGrid; this.m_slimTarget_initDmg = 1f; this.m_targetCell = Projector.CubeGrid.WorldToGridInteger(block.CubeGrid.GridIntegerToWorld(block.Position)); } else { this.m_weldProjection = false; this.m_slimTarget_initDmg = block.Damage(); this.m_targetCell = block.Position; } m_navSet.Settings_Task_NavEngage.NavigatorMover = this; m_navSet.Settings_Task_NavEngage.NavigatorRotator = this; m_navSet.Settings_Task_NavEngage.DestinationEntity = m_realGrid; IEnumerator<Vector3I> neighbours = this.m_targetSlim.ForEachNeighbourCell(); while (neighbours.MoveNext()) { Vector3I cell = m_weldProjection ? Projector.CubeGrid.WorldToGridInteger(block.CubeGrid.GridIntegerToWorld(neighbours.Current)) : neighbours.Current; m_neighbours.Add(cell); if (this.m_realGrid.GetCubeBlock(cell) == null) m_emptyNeighbours.Add(cell); } m_targetSlim.ComputeWorldCenter(out m_targetWorld); m_lineUp.To = m_targetWorld; }
private void updateProjectorsWithout(IMySlimBlock block) { // update projectors // track these outside of block types, because those are currently user-configurable InGame.IMyProjector projector = block.FatBlock as InGame.IMyProjector; if (projector != null) { log("Removed a projector", "blockRemoved"); m_Projectors.Remove(projector.EntityId); } }
/// <summary> /// Decrements the BlockType counts for a given removed block /// </summary> private void updateBlockTypeCountsWithout(IMySlimBlock block) { BlockType[] types = s_Settings.BlockTypes; for (int i = 0; i < types.Length; i++) { BlockType type = types[i]; if (type.appliesToBlock(block)) { m_BlockTypeCounts[i]--; log(type.DisplayName + " count now: " + m_BlockTypeCounts[i], "updateBlockCountsWithout"); return; } } }
/// <summary> /// Applies the new class if block is a Classifier and we can reserve the Class /// Returns true if this was a happy update, /// false if the block needs to be removed /// </summary> /// <param name="block"></param> private VIOLATION_TYPE updateClassifiersWith(IMySlimBlock block) { log("", "updateClassificationWith"); try { // If it's not a classifier, we don't care about it if (!HullClassifier.isClassifierBlock(block)) { return VIOLATION_TYPE.NONE; } // load up the classifier helper object HullClassifier classifier = new HullClassifier(block); HullClass.CLASS classID = classifier.Class; log("Adding a classifier for class " + classID + " - " + s_Settings.HullRules[(int)classID].DisplayName, "updateClassificationWith"); addClassifier(classifier); // Ensure it's the right type for this grid if (s_Settings.HullRules[(int)classifier.Class].ShouldBeStation && !m_Grid.IsStatic) { return VIOLATION_TYPE.SHOULD_BE_STATIC; } // Two classifiers not allowed if (m_Classifiers.Count > 1) { return VIOLATION_TYPE.TOO_MANY_CLASSIFIERS; } // Too many per Player/Faction not allowed if (!checkClassAllowed(classID)) { return VIOLATION_TYPE.TOO_MANY_OF_CLASS; } } catch (Exception e) { log("Error: " + e, "updateClassificationWith", Logger.severity.ERROR); } return VIOLATION_TYPE.NONE; }
private static bool DoesGridHaveTarget(IMyCubeGrid grid, IMySlimBlock block, bool disabling = false) { if (m_scanCache.Count < 1) { BoundingSphereD sphere = new BoundingSphereD(grid.GetPosition(), PluginSettings.Instance.DynamicTurretTargetDistance); m_scanCache = MyAPIGateway.Entities.GetEntitiesInSphere(ref sphere); } /* * HashSet<IMyEntity> testEntities = new HashSet<IMyEntity>(); * try * { * MyAPIGateway.Entities.GetEntities(testEntities); * } * catch * { * return false; * } */ //bool found = false; foreach (IMyEntity testEntity in m_scanCache) { if ((IMyEntity)grid == testEntity) { continue; } if (!testEntity.InScene) { continue; } if (testEntity is IMyCubeBlock) { continue; /* * IMyCubeBlock cubeBlock = (IMyCubeBlock)testEntity; * if (cubeBlock.OwnerId == 0) * continue; * * if (PluginSettings.Instance.DynamicTurretManagementType == DynamicTurretManagementTypes.AllButOwner) * { * if (block.FatBlock.GetUserRelationToOwner(cubeBlock.OwnerId) != Sandbox.Common.MyRelationsBetweenPlayerAndBlock.Owner) * { * Console.WriteLine("Block: Not owner"); * return true; * } * } * * if (PluginSettings.Instance.DynamicTurretManagementType == DynamicTurretManagementTypes.NeutralAndEnemy) * { * if (block.FatBlock.GetUserRelationToOwner(cubeBlock.OwnerId) == Sandbox.Common.MyRelationsBetweenPlayerAndBlock.Enemies || * block.FatBlock.GetUserRelationToOwner(cubeBlock.OwnerId) == Sandbox.Common.MyRelationsBetweenPlayerAndBlock.Neutral) * { * Console.WriteLine("Block: Enemy or Neutral: {0} {1} {2}", cubeBlock.OwnerId, cubeBlock.Parent.DisplayName, cubeBlock.BlockDefinition); * return true; * } * } * * if (PluginSettings.Instance.DynamicTurretManagementType == DynamicTurretManagementTypes.Enemy) * { * if (block.FatBlock.GetUserRelationToOwner(cubeBlock.OwnerId) == Sandbox.Common.MyRelationsBetweenPlayerAndBlock.Enemies) * { * // Console.WriteLine("Block: Enemy: {0} {1} {2}", cubeBlock.OwnerId, cubeBlock.Parent.DisplayName, cubeBlock.BlockDefinition); * return true; * } * } */ } if (testEntity is IMyCubeGrid) { if (PluginSettings.Instance.DynamicTurretManagementType == DynamicTurretManagementTypes.All) { return(true); } IMyCubeGrid testGrid = (IMyCubeGrid)testEntity; // Always enable if grid has no owner. Seems suspect. Might be a user trying to abuse a no ownership ship. /* * if (testGrid.BigOwners.Count < 1 && testGrid.SmallOwners.Count < 1) * { * //if(!(testEntity is IMyControllableEntity)) * //Console.WriteLine("Grid: No owner"); * return true; * } */ foreach (long owner in testGrid.BigOwners) { if (PluginSettings.Instance.DynamicTurretManagementType == DynamicTurretManagementTypes.AllButOwner) { if (block.FatBlock.GetUserRelationToOwner(owner) != MyRelationsBetweenPlayerAndBlock.Owner) { //Console.WriteLine("Grid: Not owner"); return(true); } } if (PluginSettings.Instance.DynamicTurretManagementType == DynamicTurretManagementTypes.NeutralAndEnemy) { if (block.FatBlock.GetUserRelationToOwner(owner) == MyRelationsBetweenPlayerAndBlock.Enemies || block.FatBlock.GetUserRelationToOwner(owner) == MyRelationsBetweenPlayerAndBlock.Neutral) { //Console.WriteLine("Grid: Enemy or Neutral: {0} {1}", owner, grid.DisplayName); return(true); } } if (PluginSettings.Instance.DynamicTurretManagementType == DynamicTurretManagementTypes.Enemy) { if (block.FatBlock.GetUserRelationToOwner(owner) == MyRelationsBetweenPlayerAndBlock.Enemies) { //Console.WriteLine("{3} Target: Grid - Enemy: {0} - {1} ({2})", block.FatBlock.OwnerId, owner, testEntity.DisplayName, ((IMyTerminalBlock)block.FatBlock).Parent.DisplayName); //Console.WriteLine("Grid: Enemy: {0} {1}", owner, grid.DisplayName); return(true); } } } foreach (long owner in testGrid.SmallOwners) { if (PluginSettings.Instance.DynamicTurretManagementType == DynamicTurretManagementTypes.AllButOwner) { if (block.FatBlock.GetUserRelationToOwner(owner) != MyRelationsBetweenPlayerAndBlock.Owner) { //Console.WriteLine("Grid: Not owner"); return(true); } } if (PluginSettings.Instance.DynamicTurretManagementType == DynamicTurretManagementTypes.NeutralAndEnemy) { if (block.FatBlock.GetUserRelationToOwner(owner) == MyRelationsBetweenPlayerAndBlock.Enemies || block.FatBlock.GetUserRelationToOwner(owner) == MyRelationsBetweenPlayerAndBlock.Neutral) { //Console.WriteLine("Grid: Enemy or Neutral: {0} {1}", owner, grid.DisplayName); return(true); } } if (PluginSettings.Instance.DynamicTurretManagementType == DynamicTurretManagementTypes.Enemy) { if (block.FatBlock.GetUserRelationToOwner(owner) == MyRelationsBetweenPlayerAndBlock.Enemies) { //Console.WriteLine("Grid: Enemy: {0} {1}", owner, grid.DisplayName); return(true); } } } } else { if (PluginSettings.Instance.DynamicTurretManagementType == DynamicTurretManagementTypes.All) { return(true); } if (testEntity is IMyCharacter) // var builderBase = testEntity.GetObjectBuilder(); // if (builderBase is MyObjectBuilder_Character) { IMyPlayer player = null; IMyIdentity identity = null; long playerId = 0; try { identity = m_identityCache.FirstOrDefault(x => x.DisplayName == testEntity.DisplayName); //List<IMyPlayer> players = new List<IMyPlayer>(); //MyAPIGateway.Players.GetPlayers(players); //player = players.FirstOrDefault(x => x.DisplayName == testEntity.DisplayName); if (player == null) { /* * //player = players.FirstOrDefault(x => x.Controller != null && x.Controller.ControlledEntity != null && x.Controller.ControlledEntity.Entity != null && x.Controller.ControlledEntity.Entity.EntityId == testEntity.EntityId); * if(testEntity is IMyControllableEntity) * { * IMyControllableEntity control = (IMyControllableEntity)testEntity; * List<PlayerMap.InternalPlayerItem> items = PlayerMap.Instance.GetPlayerItemsFromPlayerName(control.Entity.DisplayName); * if (items != null) * playerId = items.First().playerId; * } */ } } catch { //Console.WriteLine("{3} Target: Character - Unknown: {0} - {1} ({2})", block.FatBlock.OwnerId, testEntity.EntityId, testEntity.DisplayName, ((IMyTerminalBlock)block.FatBlock).Parent.DisplayName); //Console.WriteLine("Unknown1: {0}", testEntity.DisplayName); return(true); } if (identity == null) { //Console.WriteLine("{3} Target: Character - Unknown2: {0} - {1} ({2})", block.FatBlock.OwnerId, testEntity.EntityId, testEntity.DisplayName, ((IMyTerminalBlock)block.FatBlock).Parent.DisplayName); //Console.WriteLine("Unknown2: {0} - {1}", testEntity.DisplayName, testEntity.GetFriendlyName()); return(true); //continue; } if (identity != null) { playerId = identity.PlayerId; } if (player != null) { playerId = player.PlayerID; } if (PluginSettings.Instance.DynamicTurretManagementType == DynamicTurretManagementTypes.AllButOwner && block.FatBlock.GetUserRelationToOwner(playerId) != MyRelationsBetweenPlayerAndBlock.Owner) { //Console.WriteLine("Character: Not Owner: {0} - {1}", block.FatBlock.OwnerId, playerId); return(true); } if (PluginSettings.Instance.DynamicTurretManagementType == DynamicTurretManagementTypes.NeutralAndEnemy) { if (block.FatBlock.GetUserRelationToOwner(playerId) == MyRelationsBetweenPlayerAndBlock.Enemies || block.FatBlock.GetUserRelationToOwner(playerId) == MyRelationsBetweenPlayerAndBlock.Neutral) { //Console.WriteLine("Character: Enemy or Neutral: {0} - {1}", block.FatBlock.OwnerId, playerId); return(true); } } if (PluginSettings.Instance.DynamicTurretManagementType == DynamicTurretManagementTypes.Enemy) { if (block.FatBlock.GetUserRelationToOwner(playerId) == MyRelationsBetweenPlayerAndBlock.Enemies) { //Console.WriteLine("{3} Target: Character - Enemy: {0} - {1} ({2})", block.FatBlock.OwnerId, playerId, testEntity.DisplayName, ((IMyTerminalBlock)block.FatBlock).Parent.DisplayName); return(true); } } } } } return(false); }
/// <summary> /// Forces a block to be removed, usually in the case of a rule violation. /// </summary> /// <param name="b"></param> private void removeBlock(IMySlimBlock b) { // spawn materials in place so they're not lost // TODO: determine best inventory target //IMyInventory inventory = null; // WAITING: once Keen accepts this PR // https://github.com/KeenSoftwareHouse/SpaceEngineers/pull/52 // the below will spawn materials in the inventory if it exists and has space, // or otherwise as floating objects in space, //b.FullyDismount(inventory); //b.MoveItemsFromConstructionStockpile(inventory); //b.SpawnConstructionStockpile(); m_Grid.RemoveBlock(b, true); }
private void AddConnectedGridBlock(NaniteDeconstructionGrid deconstruct, IMySlimBlock slimBlock) { if (slimBlock.FatBlock == null) { return; } IMyCubeBlock cubeBlock = (IMyCubeBlock)slimBlock.FatBlock; IMySlimBlock otherBlock = null; if (cubeBlock is IMyPistonBase) { IMyPistonBase pistonBase = (IMyPistonBase)cubeBlock; if (pistonBase.Top != null) { MyCubeBlock cubeOther = (MyCubeBlock)pistonBase.Top; if (deconstruct.GridsProcessed.Contains(cubeOther.CubeGrid)) { return; } if (!deconstruct.AddingGridList.Contains(cubeOther.SlimBlock)) { deconstruct.AddingGridList.Add(cubeOther.SlimBlock); otherBlock = cubeOther.SlimBlock; } } } else if (cubeBlock is Ingame.IMyShipConnector) { Ingame.IMyShipConnector connector = (Ingame.IMyShipConnector)cubeBlock; if (connector.Status == Sandbox.ModAPI.Ingame.MyShipConnectorStatus.Connected) { MyCubeBlock cubeOther = (MyCubeBlock)connector.OtherConnector; if (deconstruct.GridsProcessed.Contains(cubeOther.CubeGrid)) { return; } if (!deconstruct.AddingGridList.Contains(cubeOther.SlimBlock)) { deconstruct.AddingGridList.Add(cubeOther.SlimBlock); otherBlock = cubeOther.SlimBlock; } } } else if (cubeBlock is IMyAttachableTopBlock) { var motorRotor = cubeBlock as IMyAttachableTopBlock; if (motorRotor.Base != null) { MyCubeBlock cubeOther = motorRotor.Base as MyCubeBlock; if (deconstruct.GridsProcessed.Contains(cubeOther.CubeGrid)) { return; } if (!deconstruct.AddingGridList.Contains(cubeOther.SlimBlock)) { deconstruct.AddingGridList.Add(cubeOther.SlimBlock); otherBlock = cubeOther.SlimBlock; } } } else if (cubeBlock is IMyMechanicalConnectionBlock) { var motorBase = cubeBlock as IMyMechanicalConnectionBlock; if (motorBase.TopGrid != null) { var cubeOther = motorBase.Top as MyCubeBlock; if (deconstruct.GridsProcessed.Contains(cubeOther.CubeGrid)) { return; } if (!deconstruct.AddingGridList.Contains(cubeOther.SlimBlock)) { deconstruct.AddingGridList.Add(cubeOther.SlimBlock); otherBlock = cubeOther.SlimBlock; } } } }
IEnumerator <bool> GrindBlocks(ICollection <IMySlimBlock> Blocks) { if (Blocks.Count == 0) { yield return(false); } if (MyKernel.TermControls.ToolMode == true) { yield return(false); } if (MyKernel.TermControls.DistanceMode) { IMySlimBlock ClosestBlock = Blocks.OrderBy(x => Vector3D.DistanceSquared(x.CubeGrid.GridIntegerToWorld(x.Position), MyKernel.Block.GetPosition())).First(); Blocks.Clear(); Blocks.Add(ClosestBlock); } float SpeedRatio = (VanillaToolConstants.GrinderSpeed * NominalWorkingFrequency * MyKernel.TermControls.SpeedMultiplier * WeldGrindSpeedMultiplier) / Blocks.Count; foreach (IMySlimBlock Block in Blocks) { Block.DoDamage(0, MyStringHash.GetOrCompute("Grind"), true, null, MyKernel.Block.EntityId); } int grindedBlocks = 0; if (MyKernel.Session.Settings.AllowAsyncWelding) { Action worker = () => { foreach (IMySlimBlock Block in Blocks) { grindedBlocks++; MyAPIGateway.Parallel.StartBackground(() => Grind(Block, SpeedRatio, Raze: false)); } }; bool completed = false; Action callback = () => completed = true; MyAPIGateway.Parallel.StartBackground(worker, callback); while (!completed) { yield return(true); } List <IMySlimBlock> blocksToRaze = Blocks.Where(x => x.IsFullyDismounted).ToList(); foreach (IMySlimBlock Block in blocksToRaze) { Block.CubeGrid.RazeBlock(Block.Position); } } else { Stopwatch watch = new Stopwatch(); foreach (IMySlimBlock Block in Blocks) { grindedBlocks++; //WriteToLog($"GrindBlocks", $"Block pre-grind", EemRdx.SessionModules.LoggingLevelEnum.DebugLog); watch.Start(); Grind(Block, SpeedRatio); //WriteToLog($"GrindBlocks", $"Block post-grind", EemRdx.SessionModules.LoggingLevelEnum.DebugLog); watch.Stop(); if ((grindedBlocks + 1) < Blocks.Count) { yield return(true); } } watch.Stop(); if (MyAPIGateway.Session.IsServer && MyKernel.Session.Settings.Debug) { WriteToLog($"GrindBlocks[{MyKernel.Block.CustomName}]", $"Grinding in total took {Math.Round(watch.Elapsed.TotalMilliseconds, 3)}ms", EemRdx.SessionModules.LoggingLevelEnum.ProfilingLog); } } //WriteToLog($"GrindBlocks", $"Exiting GrindBlocks", EemRdx.SessionModules.LoggingLevelEnum.DebugLog); yield return(false); }
/// <summary> /// Checks if given slim block is projected or a preview. /// </summary> /// <param name="slimBlock">The given slim block to check.</param> /// <returns>Return true if if slim block is projected or a preview.</returns> public static bool IsProjected(this IMySlimBlock slimBlock) { return(slimBlock.CubeGrid.IsProjected()); }
/// <summary> /// MUST CALL RECREATEFACTION FIRST! /// </summary> /// <param name="ob"></param> /// <param name="playerId"></param> public static void FindPositionAndSpawn(MyObjectBuilder_CubeGrid ob, long playerId, Vector3I controlledBlock) { MyAPIGateway.Entities.RemapObjectBuilder(ob); ob.IsStatic = false; IMyEntity ent = MyAPIGateway.Entities.CreateFromObjectBuilder(ob); IMyFaction fac = MyAPIGateway.Session.Factions.TryGetPlayerFaction(playerId); foreach (MyObjectBuilder_CubeBlock block in ob.CubeBlocks) { block.Owner = playerId; var c = block as MyObjectBuilder_Cockpit; if (c == null) { continue; } c.Pilot = null; } Vector3D pos = RandomPositionFromPoint(Vector3D.Zero, Random.NextDouble() * Settings.Instance.SpawnRadius); ent.SetPosition(MyAPIGateway.Entities.FindFreePlace(pos, (float)ent.WorldVolume.Radius) ?? pos); IMyPlayer player = GetPlayerById(playerId); if (fac != null) { var entities = new HashSet <IMyEntity>(); MyAPIGateway.Entities.GetEntities(entities); foreach (IMyEntity entity in entities) { var g = entity as IMyCubeGrid; if (g == null) { continue; } if (g.BigOwners.Count == 0) { continue; } long owner = g.BigOwners[0]; IMyFaction f = MyAPIGateway.Session.Factions.TryGetPlayerFaction(owner); if (f != fac) { continue; } Vector3D p = RandomPositionFromPoint(g.GetPosition(), 100); ent.SetPosition(MyAPIGateway.Entities.FindFreePlace(p, (float)ent.WorldVolume.Radius) ?? p); break; } } MyAPIGateway.Entities.AddEntity(ent); ((IMyCubeGrid)ent).ChangeGridOwnership(playerId, MyOwnershipShareModeEnum.Faction); IMySlimBlock slim = ((IMyCubeGrid)ent).GetCubeBlock(controlledBlock); if (slim?.FatBlock is IMyCockpit && player?.Character != null) { var c = (IMyCockpit)slim.FatBlock; player.Character.SetPosition(c.GetPosition()); c.AttachPilot(player.Character); } else { Vector3D cPos = RandomPositionFromPoint(ent.WorldVolume.Center, ent.WorldVolume.Radius + 10); player?.Character?.SetPosition(cPos); } }
public EasyBlock(IMyTerminalBlock Block) { this.Block = Block; this.slim = null; }
/// <summary> /// Adds thruster to thrustersInDirection /// </summary> /// <param name="thruster">The new thruster</param> private void newThruster(IMySlimBlock thruster) { if (TP_ThrustOverride == null) TP_ThrustOverride = ((IMyTerminalBlock)thruster.FatBlock).GetProperty("Override") as ITerminalProperty<float>; using (lock_thrustersInDirection.AcquireExclusiveUsing()) thrustersInDirection[Base6Directions.GetFlippedDirection(thruster.FatBlock.Orientation.Forward)].Add(thruster.FatBlock as MyThrust); if (TP_ThrustOverride.GetValue(thruster.FatBlock) != 0f) TP_ThrustOverride.SetValue(thruster.FatBlock, 0f); }
public void TargetIntersectionCheck() { _entityScanList.Clear(); _voxelScanList.Clear(); _entityScanList = new List <MyLineSegmentOverlapResult <MyEntity> >(); MyGamePruningStructure.GetTopmostEntitiesOverlappingRay(ref Line, _entityScanList); IMyCubeGrid closestGrid = null; double closestGridDistance = -1; MySafeZone closestZone = null; double closestZoneDistance = -1; IMyCharacter closestCharacter = null; double closestCharacterDistance = -1; foreach (var item in _entityScanList) { var targetGrid = item.Element as IMyCubeGrid; var targetZone = item.Element as MySafeZone; var targetVoxel = item.Element as MyVoxelBase; var targetPlayer = item.Element as IMyCharacter; if (targetGrid != null) { if (targetGrid == _collisionSystem.RemoteControl.SlimBlock.CubeGrid || _collisionSystem.RemoteControl.SlimBlock.CubeGrid.IsSameConstructAs(targetGrid)) { continue; } if (closestGrid == null || (closestGrid != null && item.Distance < closestGridDistance)) { closestGrid = targetGrid; closestGridDistance = item.Distance; } } if (targetZone != null) { if (closestZone == null || (closestZone != null && item.Distance < closestZoneDistance)) { closestZone = targetZone; closestZoneDistance = item.Distance; } } if (targetVoxel != null) { _voxelScanList.Add(targetVoxel); } if (targetPlayer != null) { if (closestCharacter == null || (closestCharacter != null && item.Distance < closestCharacterDistance)) { closestCharacter = targetPlayer; closestCharacterDistance = item.Distance; } } } if (closestGrid != null) { double minDist = 0; double maxDist = 0; bool boxCheckResult = closestGrid.PositionComp.WorldAABB.Intersect(ref Ray, out minDist, out maxDist); Vector3D startBox = boxCheckResult ? (minDist - 5) * DirectionVector + StartPosition : StartPosition; Vector3D endBox = boxCheckResult ? (maxDist + 5) * DirectionVector + StartPosition : EndPosition; var blockPos = closestGrid.RayCastBlocks(startBox, endBox); if (!blockPos.HasValue) { return; } IMySlimBlock slimBlock = closestGrid.GetCubeBlock(blockPos.Value); if (slimBlock == null) { return; } Vector3D blockPosition = Vector3D.Zero; slimBlock.ComputeWorldCenter(out blockPosition); GridCoords = blockPosition; GridDistance = Vector3D.Distance(blockPosition, StartPosition); GridEntity = closestGrid; GridOwner = OwnershipHelper.GetOwnershipTypes(closestGrid, false); GridRelation = OwnershipHelper.GetTargetReputation(_collisionSystem.Owner, closestGrid, false); } if (closestZone != null) { SafezoneEntity = closestZone; SafezoneCoords = closestZoneDistance * DirectionVector + StartPosition; SafezoneDistance = closestZoneDistance; } if (closestCharacter != null) { PlayerEntity = closestCharacter; PlayerCoords = PlayerEntity.PositionComp.WorldAABB.Center; PlayerDistance = closestCharacterDistance; } }
private void CreateRemovalOrder(NaniteDeconstructionGrid deconstruct, IMySlimBlock startBlock) { IMySlimBlock currentBlock = startBlock; deconstruct.AddingList.Clear(); deconstruct.GridsProcessed.Clear(); while (true) { if (!deconstruct.GridsProcessed.Contains(currentBlock.CubeGrid)) { ((MyCubeGrid)currentBlock.CubeGrid).OnGridSplit += OnGridSplit; deconstruct.GridsProcessed.Add(currentBlock.CubeGrid); } MyObjectBuilder_CubeBlock block = (MyObjectBuilder_CubeBlock)currentBlock.GetObjectBuilder(); MyCubeBlockDefinition blockDefinition; MyDefinitionManager.Static.TryGetCubeBlockDefinition(block.GetId(), out blockDefinition); // Get real block max Vector3I Max = Vector3I.Zero; Vector3I Min = block.Min; ComputeMax(blockDefinition, block.BlockOrientation, ref Min, out Max); AddNeighbours(deconstruct, currentBlock, Min, new Vector3I(Min.X, Max.Y, Max.Z), -Vector3I.UnitX); AddNeighbours(deconstruct, currentBlock, Min, new Vector3I(Max.X, Min.Y, Max.Z), -Vector3I.UnitY); AddNeighbours(deconstruct, currentBlock, Min, new Vector3I(Max.X, Max.Y, Min.Z), -Vector3I.UnitZ); AddNeighbours(deconstruct, currentBlock, new Vector3I(Max.X, Min.Y, Min.Z), Max, Vector3I.UnitX); AddNeighbours(deconstruct, currentBlock, new Vector3I(Min.X, Max.Y, Min.Z), Max, Vector3I.UnitY); AddNeighbours(deconstruct, currentBlock, new Vector3I(Min.X, Min.Y, Max.Z), Max, Vector3I.UnitZ); // Check if currentBlock is a connector of some kind, then follow it AddConnectedGridBlock(deconstruct, currentBlock); // Add to removal list if (!deconstruct.RemoveList.Contains(currentBlock)) { deconstruct.RemoveList.AddStart(currentBlock); } if (deconstruct.AddingList.Count < 1 && deconstruct.AddingGridList.Count < 1) { break; } if (deconstruct.AddingList.Count < 1 && deconstruct.AddingGridList.Count > 0) { currentBlock = deconstruct.AddingGridList[0]; deconstruct.AddingGridList.Remove(currentBlock); //deconstruct.TreePosition++; //deconstruct.GridTree.Add(new Node<IMySlimBlock>(currentBlock)); } else { currentBlock = deconstruct.AddingList[0]; deconstruct.AddingList.Remove(currentBlock); } } // Find user defined priority blocks for deconstruction. FindPriorityBlocks(deconstruct, startBlock); Logging.Instance.WriteLine(string.Format("Block Count: {0}", deconstruct.RemoveList.Count)); //Logging.Instance.WriteLine(string.Format("Grid Count: {0}", deconstruct.GridsProcessed.Count)); //Logging.Instance.WriteLine(string.Format("Tree Size: {0}", deconstruct.GridTree.Sum(x => x.All.Count()))); }
private void ProcessItem(IMySlimBlock target) { if (Sync.IsServer) { if (!IsEnabled()) { Logging.Instance.WriteLine("CANCELLING Deconstruction Target due to being disabled"); CancelTarget(target); return; } if (!NaniteConstructionPower.HasRequiredPowerForCurrentTarget((IMyFunctionalBlock)m_constructionBlock.ConstructionBlock)) { Logging.Instance.WriteLine("CANCELLING Deconstruction Target due to power shortage"); CancelTarget(target); return; } if (m_constructionBlock.FactoryState != NaniteConstructionBlock.FactoryStates.Active) { return; } NaniteGrinder grinder = (NaniteGrinder)m_constructionBlock.ToolManager.Tools.FirstOrDefault(x => x.TargetBlock == target && x is NaniteGrinder); if (grinder == null) { double distance = EntityHelper.GetDistanceBetweenBlockAndSlimblock((IMyCubeBlock)m_constructionBlock.ConstructionBlock, target); int time = (int)Math.Max(GetMinTravelTime() * 1000f, (distance / GetSpeed()) * 1000f); grinder = new NaniteGrinder(m_constructionBlock, target, (int)(time / 2.5f), NaniteConstructionManager.Settings.DeconstructionPerformanceFriendly); m_constructionBlock.ToolManager.Tools.Add(grinder); m_constructionBlock.SendAddTarget(target, TargetTypes.Deconstruction); } if (m_areaTargetBlocks.ContainsKey(target.CubeGrid)) { if (!m_areaTargetBlocks[target.CubeGrid].IsInsideBox(target.CubeGrid.WorldAABB, false)) { CancelTarget(target); RemoveGridTarget(target.CubeGrid); return; } if (target.CubeGrid.Physics.LinearVelocity.LengthSquared() != 0f || target.CubeGrid.Physics.AngularVelocity.LengthSquared() != 0f) { CancelTarget(target); return; } } if (target.IsDestroyed || target.IsFullyDismounted || target.CubeGrid.GetCubeBlock(target.Position) == null || (target.FatBlock != null && target.FatBlock.Closed)) { CompleteTarget(target); return; } if (target.CubeGrid.Closed) { Logging.Instance.WriteLine("CANCELLING Deconstruction Target due to grid being closed"); CancelTarget(target); return; } if (EntityHelper.GetDistanceBetweenBlockAndSlimblock((IMyCubeBlock)m_constructionBlock.ConstructionBlock, target) > m_maxDistance) { Logging.Instance.WriteLine("CANCELLING Deconstruction Target due to target being out of range"); CancelTarget(target); return; } } CreateDeconstructionParticle(target); }
/// <summary> /// Called when a block is removed. Decrements counts and checks for declassification. /// </summary> /// <param name="removed"></param> private void blockRemoved(IMySlimBlock removed) { try { updateClassificationWithout(removed); decrementBlockCount(); updateBlockTypeCountsWithout(removed); updateProjectorsWithout(removed); log(removed.ToString() + " removed from grid '" + m_Grid.DisplayName + "'. Total Count now: " + m_BlockCount, "blockRemoved"); m_CheckCleanupNextUpdate = true; } catch (Exception e) { log("Error: " + e, "blockRemoved"); } }
void IMyProjector.Build(IMySlimBlock cubeBlock, long owner, long builder) { Build((MySlimBlock)cubeBlock, owner, builder); }
/*public static bool IsPeacefulNPC(this IMyFaction Faction) * { * try * { * if (!Faction.IsNPC()) return false; * return Diplomacy.LawfulFactionsTags.Contains(Faction.Tag); * } * catch (Exception Scrap) * { * AISessionCore.LogError("Faction.IsPeacefulNPC", Scrap); * return false; * } * }*/ public static float GetHealth(this IMySlimBlock Block) { return(Math.Min(Block.DamageRatio, Block.BuildLevelRatio)); }
internal bool ProcessMissingComponents(IMySlimBlock target) { if (MyAPIGateway.Session.CreativeMode) { return(true); } int pos = 0; try { IMyInventory inventory = GetConstructionInventory(); if (inventory == null) { Logging.Instance.WriteLine(string.Format("Inventory {0} is null.", inventory == null)); return(false); } Dictionary <string, int> missingComponents = new Dictionary <string, int>(); // Target block is on a real grid if (target.CubeGrid.Physics != null) { target.GetMissingComponents(missingComponents); if (missingComponents.Count == 0) { return(true); } } else // Target block is projection, let's just put 1 item in it { try { MyCubeBlockDefinition blockDefinition = (MyCubeBlockDefinition)target.BlockDefinition; missingComponents.Add(blockDefinition.Components[0].Definition.Id.SubtypeName, 1); } catch (Exception ex) { Logging.Instance.WriteLine(string.Format("Process Error: {0}", ex.ToString())); return(false); } } foreach (var item in inventory.GetItems().ToList()) { if (missingComponents.ContainsKey(item.Content.SubtypeName)) { var amount = (float)missingComponents[item.Content.SubtypeName]; if (amount >= (float)item.Amount) { amount = (float)item.Amount; } missingComponents[item.Content.SubtypeName] -= (int)item.Amount; if (missingComponents[item.Content.SubtypeName] <= 0) { missingComponents.Remove(item.Content.SubtypeName); } inventory.RemoveItemsOfType((int)amount, (MyObjectBuilder_PhysicalObject)item.Content); } } if (missingComponents.Count == 0) { return(true); } return(false); } catch (Exception ex) { Logging.Instance.WriteLine(string.Format("Exception {0} : {1}", pos, ex.ToString())); return(false); } }
/// <summary> /// Updates the appearance of the block if the integrity has changed. Only used for welding/griding. /// </summary> private static void UpdateBlockModel(IMySlimBlock realBlock, IMyCubeGrid holoGrid) { IMySlimBlock holoBlock = holoGrid.GetCubeBlock(realBlock.Position); Static.logger.debugLog(holoBlock == null, "holoBlock == null", Logger.severity.FATAL); float realIntegrityRatio = (realBlock.BuildIntegrity - realBlock.CurrentDamage) / realBlock.MaxIntegrity; float holoIntegrityRatio = (holoBlock.BuildIntegrity - holoBlock.CurrentDamage) / holoBlock.MaxIntegrity; if (realIntegrityRatio == holoIntegrityRatio) return; float min, max; if (realIntegrityRatio > holoIntegrityRatio) { max = realIntegrityRatio; min = holoIntegrityRatio; } else { max = holoIntegrityRatio; min = realIntegrityRatio; } if (((MyCubeBlockDefinition)realBlock.BlockDefinition).ModelChangeIsNeeded(min, max)) { holoGrid.RemoveBlock(holoBlock); MyObjectBuilder_CubeBlock objBuilder = realBlock.GetObjectBuilder(); objBuilder.EntityId = 0L; holoGrid.AddBlock(objBuilder, false); IMyCubeBlock cubeBlock = holoGrid.GetCubeBlock(realBlock.Position).FatBlock; if (cubeBlock != null) SetupProjection(cubeBlock); } }
public static double GetDistanceBetweenBlockAndSlimblock(IMyCubeBlock block, IMySlimBlock slimBlock) { return(Vector3D.Distance(block.GetPosition(), GetBlockPosition(slimBlock))); }
public static void SetBuildPercent(IMySlimBlock block, float percent) { try { // Set locally object constructionManager = GetEntityFieldValue(block, CubeBlockConstructionManagerField); float maxIntegrity = (float)InvokeEntityMethod(constructionManager, ConstructionManagerGetMaxIntegrityMethod); float integrity = percent * maxIntegrity; float build = percent * maxIntegrity; InvokeEntityMethod(constructionManager, ConstructionManagerSetIntegrityBuildValuesMethod, new object[] { build, integrity }); // Broadcast to players Type someEnum = CubeGridEntity.InternalType.GetNestedType(CubeGridNetworkManager.CubeGridIntegrityChangeEnumClass); Array someEnumValues = someEnum.GetEnumValues(); object enumValue = someEnumValues.GetValue(0); object netManager = BaseObject.InvokeEntityMethod(block.CubeGrid, CubeGridNetworkManager.CubeGridGetNetManagerMethod); BaseObject.InvokeEntityMethod(netManager, CubeGridNetworkManager.CubeGridNetManagerBroadcastCubeBlockBuildIntegrityValuesMethod, new object[] { block, enumValue, 0L }); } catch (Exception ex) { LogManager.ErrorLog.WriteLineAndConsole(string.Format("SetBuildPercent(): {0}", ex.ToString())); } }
public static Vector3D GetBlockPosition(IMySlimBlock slimBlock) { return(slimBlock.CubeGrid.GridIntegerToWorld(slimBlock.Position)); }
BuildCheckResult IMyProjector.CanBuild(IMySlimBlock projectedBlock, bool checkHavokIntersections) { return(CanBuild((MySlimBlock)projectedBlock, checkHavokIntersections)); }
public static Vector3D GetPosition(this IMySlimBlock block) { return(block.CubeGrid.GridIntegerToWorld(block.Position)); }
IEnumerator <bool> WeldAndPlaceBlocks(ICollection <IMySlimBlock> RealBlocks, ICollection <IMySlimBlock> ProjectedBlocks) { if (RealBlocks == null || ProjectedBlocks == null) { yield return(false); } if (RealBlocks.Count == 0 && ProjectedBlocks.Count == 0) { yield return(false); } if (MyKernel.TermControls.ToolMode == false) { yield return(false); } if (!SafeZonesHelper.IsActionAllowed(MyKernel.Block.GetPosition(), MySafeZoneAction.Welding | MySafeZoneAction.Building, MyKernel.Block.EntityId)) { yield return(false); } bool ShouldContinue = RealBlocks.Count > 0 || ProjectedBlocks.Count > 0; //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"Entry Point: real blocks: {RealBlocks.Count}, projected blocks: {ProjectedBlocks.Count}, should continue: {ShouldContinue}"); if (!ShouldContinue) { yield return(false); } if (MyKernel.TermControls.DistanceMode && RealBlocks.Count > 0) { IMySlimBlock FarthestBlock = RealBlocks.OrderBy(x => Vector3D.DistanceSquared(x.CubeGrid.GridIntegerToWorld(x.Position), MyKernel.Block.GetPosition())).Last(); RealBlocks.Clear(); RealBlocks.Add(FarthestBlock); //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"Selected block for distance mode"); } float SpeedRatio = NominalWorkingFrequency * MyKernel.TermControls.SpeedMultiplier * WeldGrindSpeedMultiplier * (VanillaToolConstants.WelderSpeed / RealBlocks.Count); float BoneFixSpeed = VanillaToolConstants.WelderBoneRepairSpeed * NominalWorkingFrequency; IMyProjector Projector = null; if (ProjectedBlocks.Count > 0) { Projector = ((ProjectedBlocks.First().CubeGrid as MyCubeGrid).Projector as IMyProjector); } //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"Checked for projectors"); if (!MyAPIGateway.Session.CreativeMode) { Dictionary <string, int> RequiredComponentNames = new Dictionary <string, int>(); { Action worker = () => { foreach (IMySlimBlock Block in RealBlocks) { Block.GetMissingComponents(RequiredComponentNames); } }; bool completed = false; Action callback = () => completed = true; MyAPIGateway.Parallel.StartBackground(worker, callback); while (!completed) { yield return(true); } } //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"Got missing components"); foreach (IMySlimBlock Block in ProjectedBlocks) { var FirstItem = ((MyCubeBlockDefinition)Block.BlockDefinition).Components[0].Definition.Id; if (RequiredComponentNames.ContainsKey(FirstItem.SubtypeName)) { RequiredComponentNames[FirstItem.SubtypeName] += 1; } else { RequiredComponentNames.Add(FirstItem.SubtypeName, 1); } } //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"Got missing components for projected blocks"); Dictionary <MyItemType, float> RequiredComponents = new Dictionary <MyItemType, float>(); var list = RequiredComponentNames.ToList(); foreach (KeyValuePair <string, int> kvp in list) { //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"Trying to generate itemtype..."); //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"for {kvp.Key}"); MyItemType itemtype = new MyItemType("MyObjectBuilder_Component", kvp.Key); //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"Generated item value"); //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"(item: {itemtype.SubtypeId}, amount: {kvp.Value})"); RequiredComponents.Add(itemtype, kvp.Value); } //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"Reassembled missing dictionary"); List <IMyTerminalBlock> InventoryOwners = new List <IMyTerminalBlock>(MyKernel.Inventory.InventoryOwners); InventoryOwners.Add(MyKernel.Tool); InventoryModule.CalculateMissingItems(RequiredComponents, MyKernel.Inventory.GetAggregateItemsFor(InventoryOwners)); //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"Calculated aggregate missing components"); if (MyKernel.Tool.UseConveyorSystem) { Dictionary <MyItemType, float> _RqComponents = new Dictionary <MyItemType, float>(RequiredComponents); foreach (var RequiredComponent in RequiredComponents) { float pulledAmount = MyKernel.Inventory.TryTransferTo(ToolCargo, RequiredComponent.Key, RequiredComponent.Value, InventoryOwners); _RqComponents[RequiredComponent.Key] -= pulledAmount; } RequiredComponents = _RqComponents; //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"Pulled missing components"); } MyKernel.ResponderModule.UpdateMissing(RequiredComponents); yield return(true); int weldedBlocks = 0; List <IMySlimBlock> UnweldedBlocks = new List <IMySlimBlock>(); foreach (IMySlimBlock Block in RealBlocks) { if (Block.CanContinueBuild(ToolCargo) || Block.HasDeformation) { if (MyKernel.Session.Settings.AllowAsyncWelding) { if (CanWeldInAsyncMode(Block)) { MyAPIGateway.Parallel.StartBackground(() => Weld(Block, SpeedRatio, BoneFixSpeed)); } else { Weld(Block, SpeedRatio, BoneFixSpeed); } } else { Weld(Block, SpeedRatio, BoneFixSpeed); } weldedBlocks++; if (!MyKernel.Session.Settings.AllowAsyncWelding && weldedBlocks != RealBlocks.Count - 1) { yield return(true); } } else { UnweldedBlocks.Add(Block); } } //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"Welded real blocks"); if (weldedBlocks > 0) { yield return(true); } int placedBlocks = 0; List <IMySlimBlock> NonplacedBlocksByLimit = new List <IMySlimBlock>(); List <IMySlimBlock> NonplacedBlocksByResources = new List <IMySlimBlock>(); List <IMySlimBlock> PlaceableProjectedBlocks = new List <IMySlimBlock>(); foreach (IMySlimBlock Block in ProjectedBlocks) { MyCubeBlockDefinition blockDef = Block.BlockDefinition as MyCubeBlockDefinition; if (MyKernel.Tool.IsWithinWorldLimits(Projector, blockDef.BlockPairName, blockDef.PCU)) { var FirstItem = blockDef.Components[0].Definition.Id; if (ToolCargo.GetItemAmount(FirstItem) >= 1) { PlaceableProjectedBlocks.Add(Block); } else { NonplacedBlocksByResources.Add(Block); } } else { NonplacedBlocksByLimit.Add(Block); } } foreach (IMySlimBlock Block in PlaceableProjectedBlocks) { var FirstItem = ((MyCubeBlockDefinition)Block.BlockDefinition).Components[0].Definition.Id; Projector.Build(Block, MyKernel.Tool.OwnerId, MyKernel.Tool.EntityId, false); ToolCargo.RemoveItemsOfType(1, FirstItem); placedBlocks++; if (placedBlocks != ProjectedBlocks.Count - 1) { yield return(true); } } if (UnweldedBlocks.Count > 0) { StringBuilder UnweldedReport = new StringBuilder(); UnweldedReport.AppendLine($"Failed to weld {UnweldedBlocks.Count} blocks:"); List <IGrouping <MyObjectBuilderType, IMySlimBlock> > unweldedByType = UnweldedBlocks.GroupBy(x => x.BlockDefinition.Id.TypeId).ToList(); foreach (IGrouping <MyObjectBuilderType, IMySlimBlock> grouping in unweldedByType) { UnweldedReport.AppendLine($"{grouping.Key.ToString().Replace("MyObjectBuilder_", "")} ({grouping.Count()})"); } if (NonplacedBlocksByLimit.Count > 0 || NonplacedBlocksByResources.Count > 0) { UnweldedReport.AppendLine(); } MyKernel.ResponderModule.UpdateStatusReport(UnweldedReport, append: true); } if (NonplacedBlocksByLimit.Count > 0) { StringBuilder NonplacedReport = new StringBuilder(); NonplacedReport.AppendLine($"Failed to place {UnweldedBlocks.Count} blocks,"); NonplacedReport.AppendLine($"reached the PCU/block limit:"); List <IGrouping <MyObjectBuilderType, IMySlimBlock> > unplacedByType = UnweldedBlocks.GroupBy(x => x.BlockDefinition.Id.TypeId).ToList(); foreach (IGrouping <MyObjectBuilderType, IMySlimBlock> grouping in unplacedByType) { NonplacedReport.AppendLine($"{grouping.Key.ToString().Replace("MyObjectBuilder_", "")} ({grouping.Count()})"); } MyKernel.ResponderModule.UpdateStatusReport(NonplacedReport, append: true); } if (NonplacedBlocksByResources.Count > 0) { StringBuilder NonplacedReport = new StringBuilder(); NonplacedReport.AppendLine($"Failed to place {UnweldedBlocks.Count} blocks,"); NonplacedReport.AppendLine($"out of resources:"); List <IGrouping <MyObjectBuilderType, IMySlimBlock> > unplacedByType = UnweldedBlocks.GroupBy(x => x.BlockDefinition.Id.TypeId).ToList(); foreach (IGrouping <MyObjectBuilderType, IMySlimBlock> grouping in unplacedByType) { NonplacedReport.AppendLine($"{grouping.Key.ToString().Replace("MyObjectBuilder_", "")} ({grouping.Count()})"); } MyKernel.ResponderModule.UpdateStatusReport(NonplacedReport, append: true); } //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"Placed projected blocks"); } else if (MyAPIGateway.Session.CreativeMode) { foreach (IMySlimBlock Block in RealBlocks) { if (MyKernel.Session.Settings.AllowAsyncWelding) { if (CanWeldInAsyncMode(Block)) { MyAPIGateway.Parallel.StartBackground(() => Weld(Block, SpeedRatio, BoneFixSpeed)); } else { Weld(Block, SpeedRatio, BoneFixSpeed); } } else { Weld(Block, SpeedRatio, BoneFixSpeed); } } foreach (IMySlimBlock Block in ProjectedBlocks) { Projector.Build(Block, MyKernel.Tool.OwnerId, MyKernel.Tool.EntityId, false); } } //MyKernel.SessionBase.Log.DebugLog.WriteToLog($"WeldAndPlaceBlocks", $"Exit Point"); yield return(false); }
public static long SlimId(this IMySlimBlock block) { return(block.CubeGrid.EntityId.GetHashCode() + block.Position.GetHashCode()); }
void Grind(IMySlimBlock Block, float SpeedRatio, bool Raze = true) { if (Block == null) { return; } try { Stopwatch watch = Stopwatch.StartNew(); Block.DecreaseMountLevel(SpeedRatio, ToolCargo); watch.Stop(); //WriteToLog($"GrindBlocks[{MyKernel.Block.CustomName}]", $"Decreasing mount level took {Math.Round(watch.Elapsed.TotalMilliseconds, 3)}ms", EemRdx.SessionModules.LoggingLevelEnum.ProfilingLog); watch.Restart(); Block.MoveItemsFromConstructionStockpile(ToolCargo); watch.Stop(); //WriteToLog($"GrindBlocks[{MyKernel.Block.CustomName}]", $"Moving items took {Math.Round(watch.Elapsed.TotalMilliseconds, 3)}ms", EemRdx.SessionModules.LoggingLevelEnum.ProfilingLog); watch.Restart(); // This is necessary for compatibility with EEM and other mods which react to damage to their grids Block.DoDamage(0, MyStringHash.GetOrCompute("Grind"), true, null, MyKernel.Block.EntityId); watch.Stop(); //WriteToLog($"GrindBlocks[{MyKernel.Block.CustomName}]", $"Doing damage took {Math.Round(watch.Elapsed.TotalMilliseconds, 3)}ms", EemRdx.SessionModules.LoggingLevelEnum.ProfilingLog); watch.Restart(); if (Block.FatBlock?.IsFunctional == false && Block.FatBlock?.HasInventory == true) { foreach (IMyInventory Inventory in Block.FatBlock.GetInventories()) { if (Inventory.CurrentVolume == VRage.MyFixedPoint.Zero) { continue; } List <MyInventoryItem> Items = new List <MyInventoryItem>(); Inventory.GetItems(Items); foreach (MyInventoryItem Item in Items) { VRage.MyFixedPoint Amount = (VRage.MyFixedPoint)Math.Min((float)(Inventory as Sandbox.Game.MyInventory).ComputeAmountThatFits(Item.Type), (float)Item.Amount); if ((float)Amount > 0) { ToolCargo.TransferItemFrom(Inventory, (int)Item.ItemId, null, null, Amount, false); } } } watch.Stop(); //WriteToLog($"GrindBlocks[{MyKernel.Block.CustomName}]", $"Block has an inventory; cleaning took {Math.Round(watch.Elapsed.TotalMilliseconds, 3)}ms", EemRdx.SessionModules.LoggingLevelEnum.ProfilingLog); watch.Reset(); } if (Raze && Block.IsFullyDismounted) { watch.Restart(); Block.CubeGrid.RazeBlock(Block.Position); watch.Stop(); //WriteToLog($"GrindBlocks[{MyKernel.Block.CustomName}]", $"Razing the block took {Math.Round(watch.Elapsed.TotalMilliseconds, 3)}ms", EemRdx.SessionModules.LoggingLevelEnum.ProfilingLog); } } catch (Exception Scrap) { LogError($"GrindBlocks[{MyKernel.Block.CustomName}]", $"Grinding of the block {Extensions.GeneralExtensions.GetTypeName(Block)} failed", Scrap); } }
public static bool Closed(this IMySlimBlock block) { return(block.CubeGrid?.GetCubeBlock(block.Position) == null); }
private bool helpsClassifyUnclassified(IMySlimBlock block) { if (m_EffectiveClass != DEFAULT_CLASS) { return false; } if (m_ReservedClass == DEFAULT_CLASS) { return HullClassifier.isClassifierBlock(block); } else { IMyReactor reactor = block.FatBlock as IMyReactor; return (reactor != null); } }
public static float BuildPercent(this IMySlimBlock block) { return(block.Integrity / block.MaxIntegrity); }
/// <summary> /// Increments the BlockType counts for a given new block /// Returns the violated limits if any /// </summary> private List<BlockType> updateBlockTypeCountsWith(IMySlimBlock block) { log("", "updateBlockTypeCountsWith"); List<BlockType> violated_types = new List<BlockType>(); BlockType[] types = s_Settings.BlockTypes; for (int typeID = 0; typeID < types.Length; typeID++) { BlockType type = types[typeID]; if (type.appliesToBlock(block)) { //log("incrementing type count " + m_BlockTypeCounts[typeID], "updateBlockCountsWith"); m_BlockTypeCounts[typeID] = m_BlockTypeCounts[typeID] + 1; int count = m_BlockTypeCounts[typeID]; int limit = m_EffectiveRules.BlockTypeLimits[typeID]; log(type.DisplayName + " count now: " + count, "updateBlockCountsWith"); if (count > limit && limit >= 0) violated_types.Add(type); } } return violated_types; }
VRageMath.Vector3D?IMyCubeGrid.GetLineIntersectionExactAll(ref VRageMath.LineD line, out double distance, out IMySlimBlock intersectedBlock) { MySlimBlock block; var retVal = GetLineIntersectionExactAll(ref line, out distance, out block); intersectedBlock = block; return(retVal); }
/// <summary> /// Removes the classifier and reserved class if block is a Classifier /// </summary> private void updateClassificationWithout(IMySlimBlock block) { // classifier? if (!HullClassifier.isClassifierBlock(block)) return; log("removing classifier", "updateClassificationWithout"); removeClassifier(block.FatBlock.EntityId); }
/// <summary> /// Returns True if tool has painted. /// </summary> void HandleTool(bool trigger) { AimedPlayer = null; AimedBlock = null; AimedState = SelectionState.Invalid; SymmetryInputAvailable = false; IMyCharacter character = MyAPIGateway.Session.Player.Character; IMyCubeGrid targetGrid; IMySlimBlock targetBlock; IMyPlayer targetPlayer; Vector3D aimPoint; GetTarget(character, out targetGrid, out targetBlock, out targetPlayer, out aimPoint); if (targetPlayer != null && Main.Palette.ColorPickMode) { HandleTool_ColorPickFromPlayer(trigger, targetPlayer); return; } if (targetBlock == null) { if (Main.Palette.ColorPickMode) { Main.Notifications.Show(0, "Aim at a block or player and click to pick color.", MyFontEnum.Blue); } else if (!Utils.SafeZoneCanPaint(aimPoint, MyAPIGateway.Multiplayer.MyId)) { // sound likely already played by the shoot restriction in the safe zone //HUDSounds.PlayUnable(); if (trigger) { Main.Notifications.Show(0, "Can't paint in this safe zone.", MyFontEnum.Red); } } else if (Main.Palette.ReplaceMode) { Main.Notifications.Show(0, $"Aim at a block to replace its color on {(Main.Palette.ReplaceShipWide ? "the entire ship" : "this grid")}.", MyFontEnum.Blue); } else if (trigger) { //Main.HUDSounds.PlayUnable(); if (!Main.IgnoreAmmoConsumption && LocalTool.Ammo == 0) { Main.Notifications.Show(0, "No ammo and no target.", MyFontEnum.Red); } else { Main.Notifications.Show(0, "Aim at a block to paint it.", MyFontEnum.Red); } } return; } Main.SelectionGUI.UpdateSymmetryStatus(targetBlock); PaintMaterial paintMaterial = Main.Palette.GetLocalPaintMaterial(); BlockMaterial blockMaterial = new BlockMaterial(targetBlock); AimedBlock = targetBlock; if (Main.Palette.ColorPickMode) { HandleTool_ColorPickModeFromBlock(paintMaterial, blockMaterial, trigger); return; } if (!ValidateMainBlock(targetBlock, paintMaterial, blockMaterial, trigger)) { return; } string blockName = Utils.GetBlockName(targetBlock); if (!Main.IgnoreAmmoConsumption && LocalTool.Ammo == 0) { if (trigger) { //Main.HUDSounds.PlayUnable(); Main.Notifications.Show(1, "No ammo.", MyFontEnum.Red); } Main.SelectionGUI.SetGUIStatus(0, "No ammo!", "red"); return; } AimedState = SelectionState.Valid; if (trigger) { float paintSpeed = (1.0f / Utils.GetBlockSurface(targetBlock)); PaintMaterial finalMaterial = HandleTool_PaintProcess(paintMaterial, blockMaterial, paintSpeed, blockName); if (Main.Palette.ReplaceMode && Main.ReplaceColorAccess) { Main.Painting.ToolReplacePaint(targetGrid, blockMaterial, finalMaterial, Main.Palette.ReplaceShipWide); } else { bool useMirroring = (Main.SymmetryAccess && MyAPIGateway.CubeBuilder.UseSymmetry); Main.Painting.ToolPaintBlock(targetGrid, targetBlock.Position, finalMaterial, useMirroring); } } }
private void updateProjectorsWith(IMySlimBlock block) { log("", "updateProjectorsWith"); InGame.IMyProjector projector = block.FatBlock as InGame.IMyProjector; if (projector != null) { log("Added a projector", "blockAdded"); m_Projectors.Add(projector.EntityId, projector); } }
void GetTarget(IMyCharacter character, out IMyCubeGrid targetGrid, out IMySlimBlock targetBlock, out IMyPlayer targetPlayer, out Vector3D aimPoint) { targetGrid = null; targetBlock = null; targetPlayer = null; bool aiming = Utils.IsAimingDownSights(character); MatrixD head = character.GetHeadMatrix(false, true); Vector3D rayDir = head.Forward; Vector3D rayFrom = head.Translation; if (aiming) { rayFrom += rayDir * PAINT_AIM_START_OFFSET; } Vector3D rayTo = head.Translation + rayDir * PAINT_DISTANCE; aimPoint = rayTo; targetGrid = MyAPIGateway.CubeBuilder.FindClosestGrid(); if (targetGrid == null || targetGrid.Physics == null || !targetGrid.Physics.Enabled) { targetGrid = null; return; } // older selection behavior when aiming down sights if (aiming) { Vector3I?blockPos = targetGrid.RayCastBlocks(rayFrom, rayTo); if (blockPos.HasValue) { targetBlock = targetGrid.GetCubeBlock(blockPos.Value); } return; } // HACK copied and converted from MyDrillSensorRayCast.ReadEntitiesInRange() + MyCasterComponent.OnWorldPosChanged() // last cloned in SE v201 #region Welder-like block selection hits.Clear(); detections.Clear(); rayOverlapResults.Clear(); MyAPIGateway.Physics.CastRay(rayFrom, rayTo, hits, 24); foreach (IHitInfo hit in hits) { IMyEntity parent = hit.HitEntity?.GetTopMostParent(); if (parent == null || parent.Physics == null || !parent.Physics.Enabled) { continue; } Vector3D hitPos = hit.Position; IMyCubeGrid grid = parent as IMyCubeGrid; if (grid != null) { // just how it's set in game code /shrug hitPos += hit.Normal * -0.005f; } DetectionInfo detected; if (detections.TryGetValue(parent.EntityId, out detected)) { double dist1 = Vector3D.DistanceSquared(rayFrom, detected.DetectionPoint); double dist2 = Vector3D.DistanceSquared(rayFrom, hitPos); if (dist1 > dist2) { detections[parent.EntityId] = new DetectionInfo(parent, hitPos); } } else { detections[parent.EntityId] = new DetectionInfo(parent, hitPos); } } hits.Clear(); LineD line = new LineD(rayFrom, rayTo); MyGamePruningStructure.GetAllEntitiesInRay(ref line, rayOverlapResults); foreach (MyLineSegmentOverlapResult <MyEntity> result in rayOverlapResults) { if (result.Element == null) { continue; } IMyCubeBlock block = result.Element as IMyCubeBlock; if (block == null) { continue; } MyCubeBlockDefinition def = (MyCubeBlockDefinition)block.SlimBlock.BlockDefinition; if (def.HasPhysics) { continue; // this section is only for things that are not caught by the raycast } MyEntity parent = result.Element.GetTopMostParent(); if (parent.Physics == null || !parent.Physics.Enabled) { continue; } MatrixD invMatrix = block.PositionComp.WorldMatrixNormalizedInv; Vector3 localFrom = Vector3D.Transform(rayFrom, ref invMatrix); Vector3 localTo = Vector3D.Transform(rayTo, ref invMatrix); float?intersectDistance = new Ray(localFrom, Vector3.Normalize(localTo - localFrom)).Intersects(block.PositionComp.LocalAABB) + 0.01f; if (intersectDistance.HasValue && intersectDistance <= PAINT_DISTANCE) { Vector3D hitPos = rayFrom + rayDir * intersectDistance.Value; DetectionInfo detected; if (detections.TryGetValue(parent.EntityId, out detected)) { double dist1 = Vector3D.DistanceSquared(rayFrom, detected.DetectionPoint); double dist2 = Vector3D.DistanceSquared(rayFrom, hitPos); if (dist1 > dist2) { detections[parent.EntityId] = new DetectionInfo(parent, hitPos); } } else { detections[parent.EntityId] = new DetectionInfo(parent, hitPos); } } } rayOverlapResults.Clear(); if (detections.Count == 0) { return; } double closetDist = double.MaxValue; DetectionInfo closestObj = new DetectionInfo(null, Vector3D.Zero); foreach (DetectionInfo detected in detections.Values) { double dist = Vector3D.DistanceSquared(detected.DetectionPoint, rayFrom); if (dist < closetDist) { closestObj = detected; closetDist = dist; } } detections.Clear(); targetGrid = closestObj.Entity as IMyCubeGrid; if (targetGrid == null) { return; } Vector3D localPos = Vector3D.Transform(closestObj.DetectionPoint, targetGrid.WorldMatrixNormalizedInv); Vector3I cube; targetGrid.FixTargetCube(out cube, localPos / targetGrid.GridSize); targetBlock = targetGrid.GetCubeBlock(cube); #endregion Welder-like block selection }
/// <summary> /// Called when a block is added to the grid. /// Decides whether or not to allow the block to be placed. /// Increments counts, checks for classification, and sets /// a flag to refresh cleanup status /// </summary> /// <param name="added">block that was added to the grid</param> private void blockAdded(IMySlimBlock added) { //log(added.ToString() + " added to grid " + m_Grid.DisplayName, "blockAdded"); try { // Counts and Caches must be updated whether we're removing the block or not, // because blockRemoved has no way of knowing if we touched counts for it log("Update block lists and counts", "blockAdded"); VIOLATION_TYPE classifierViolation = updateClassifiersWith(added); VIOLATION_TYPE totalBlocksViolation = incrementBlockCount(); List<BlockType> violatedTypes = updateBlockTypeCountsWith(added); updateProjectorsWith(added); // we skip violation checks: // for blocks that aren't actually placed by a user, i.e. during World Load or a Merge log("checking enforcement skip conditions", "blockAdded"); if (m_Merging || !m_BeyondFirst100) { log("Currently merging or initing, don't do placement enforcment", "blockAdded"); goto Allowed; } // if we're projecting if (Projecting) { log("We are projecting, don't do placement enforcment", "blockAdded"); goto Allowed; } // If there are violations, disallow placement // Everything will eventually be cleaned up over time, but we do this // enforcment on placement to help keep people in line log("check placement violations", "blockAdded"); // classifier violations come first if (classifierViolation != VIOLATION_TYPE.NONE) { // people find it really annoying that they have to have an // owned block before placing a classifier. if (classifierViolation == VIOLATION_TYPE.TOO_MANY_OF_CLASS && isUnowned()) { log("Too many of class but unowned, don't do placement enforcment", "checkClassAllowed"); goto Allowed; } log("classifierViolation enforce", "blockAdded"); notifyPlacementViolation(classifierViolation); goto Denied; } // then total blocks else if (totalBlocksViolation != VIOLATION_TYPE.NONE) { // people also find it annoying to have to delete all the blocks // on a ship that just became unclassified before they can build // another classifier or reactor to bring it in line if (helpsClassifyUnclassified(added)) { log("provides needed classification, don't do placement enforcment", "blockAdded"); goto Allowed; } log("totalBlocksViolation enforce", "blockAdded"); notifyPlacementViolation(totalBlocksViolation); goto Denied; } else if (violatedTypes.Count > 0) { notifyPlacementViolation(VIOLATION_TYPE.BLOCK_TYPE); log("block type violation enforced", "blockAdded"); goto Denied; } } catch (Exception e) { log("Error: " + e, "blockAdded"); } Allowed: log(added.ToString() + " added to grid '" + m_Grid.DisplayName + "'. Total Count now: " + m_BlockCount, "blockAdded"); m_CheckOwnerNextUpdate = true; m_CheckCleanupNextUpdate = true; return; Denied: log(added.ToString() + " denied for grid '" + m_Grid.DisplayName + "'. Total Count now: " + m_BlockCount, "blockAdded"); removeBlock(added); }
bool ValidateMainBlock(IMySlimBlock block, PaintMaterial paintMaterial, BlockMaterial blockMaterial, bool trigger) { if (!paintMaterial.ColorMask.HasValue && !paintMaterial.Skin.HasValue) { string assigned = InputHandler.GetFriendlyStringForControl(MyAPIGateway.Input.GetGameControl(MyControlsSpace.CUBE_COLOR_CHANGE)); Main.Notifications.Show(0, "No paint or skin enabled.", MyFontEnum.Red); Main.Notifications.Show(1, $"Press [{assigned}] to toggle color or combined with [Shift] to toggle skin.", MyFontEnum.Debug); Main.SelectionGUI.SetGUIStatus(0, "No paint or skin enabled.", "red"); Main.SelectionGUI.SetGUIStatus(1, null); return(false); } if (!Utils.AllowedToPaintGrid(block.CubeGrid, MyAPIGateway.Session.Player.IdentityId)) { if (trigger) { Main.HUDSounds.PlayUnable(); Main.Notifications.Show(0, "Can't paint enemy ships.", MyFontEnum.Red, 2000); } Main.SelectionGUI.SetGUIStatus(0, "Not allied ship.", "red"); Main.SelectionGUI.SetGUIStatus(1, null); return(false); } if (!Utils.SafeZoneCanPaint(block, MyAPIGateway.Multiplayer.MyId)) { if (trigger) { Main.HUDSounds.PlayUnable(); Main.Notifications.Show(0, "Can't paint in this safe zone.", MyFontEnum.Red, 2000); } Main.SelectionGUI.SetGUIStatus(0, "Protected by safe zone", "red"); Main.SelectionGUI.SetGUIStatus(1, null); return(false); } bool materialEquals = paintMaterial.PaintEquals(blockMaterial); if (Main.Palette.ReplaceMode) { AimedState = (materialEquals ? SelectionState.Invalid : SelectionState.Valid); string assigned = InputHandler.GetFriendlyStringForControl(MyAPIGateway.Input.GetGameControl(MyControlsSpace.USE_SYMMETRY)); if (AimedState == SelectionState.Invalid) { Main.SelectionGUI.SetGUIStatus(0, "Already this material.", "red"); } else { Main.SelectionGUI.SetGUIStatus(0, "Click to replace material.", "lime"); } Main.SelectionGUI.SetGUIStatus(1, $"[{assigned}] {(Main.Palette.ReplaceShipWide ? "<color=yellow>" : "")}Replace mode: {(Main.Palette.ReplaceShipWide ? "Ship-wide" : "Grid")}"); return(AimedState == SelectionState.Valid); } if (!Main.InstantPaintAccess) { MyCubeBlockDefinition def = (MyCubeBlockDefinition)block.BlockDefinition; bool built = (block.BuildLevelRatio >= def.CriticalIntegrityRatio); if (!built || block.CurrentDamage > (block.MaxIntegrity / 10.0f)) { AimedState = SelectionState.Invalid; if (trigger) { Main.HUDSounds.PlayUnable(); Main.Notifications.Show(0, "Unfinished blocks can't be painted!", MyFontEnum.Red); } Main.SelectionGUI.SetGUIStatus(0, (!built ? "Block not built" : "Block damaged"), "red"); Main.SelectionGUI.SetGUIStatus(1, null); return(false); } } MyCubeGrid grid = (MyCubeGrid)block.CubeGrid; bool symmetry = Main.SymmetryAccess && MyCubeBuilder.Static.UseSymmetry && (grid.XSymmetryPlane.HasValue || grid.YSymmetryPlane.HasValue || grid.ZSymmetryPlane.HasValue); bool symmetrySameColor = true; if (materialEquals) { AimedState = SelectionState.Invalid; if (symmetry) { Vector3I?mirrorX = null; Vector3I?mirrorY = null; Vector3I?mirrorZ = null; Vector3I?mirrorYZ = null; // NOTE: do not optimize, all methods must be called if (!MirrorCheckSameColor(grid, 0, block.Position, paintMaterial, out mirrorX)) { symmetrySameColor = false; } if (!MirrorCheckSameColor(grid, 1, block.Position, paintMaterial, out mirrorY)) { symmetrySameColor = false; } if (!MirrorCheckSameColor(grid, 2, block.Position, paintMaterial, out mirrorZ)) { symmetrySameColor = false; } if (mirrorX.HasValue && grid.YSymmetryPlane.HasValue) // XY { if (!MirrorCheckSameColor(grid, 1, mirrorX.Value, paintMaterial, out mirrorX)) { symmetrySameColor = false; } } if (mirrorX.HasValue && grid.ZSymmetryPlane.HasValue) // XZ { if (!MirrorCheckSameColor(grid, 2, mirrorX.Value, paintMaterial, out mirrorX)) { symmetrySameColor = false; } } if (mirrorY.HasValue && grid.ZSymmetryPlane.HasValue) // YZ { if (!MirrorCheckSameColor(grid, 2, mirrorY.Value, paintMaterial, out mirrorYZ)) { symmetrySameColor = false; } } if (grid.XSymmetryPlane.HasValue && mirrorYZ.HasValue) // XYZ { if (!MirrorCheckSameColor(grid, 0, mirrorYZ.Value, paintMaterial, out mirrorX)) { symmetrySameColor = false; } } if (!symmetrySameColor) { AimedState = SelectionState.InvalidButMirrorValid; } } if (!symmetry || symmetrySameColor) { AimedState = SelectionState.Invalid; if (symmetry) { Main.SelectionGUI.SetGUIStatus(0, "All materials match.", "lime"); } else { Main.SelectionGUI.SetGUIStatus(0, "Materials match.", "lime"); } Main.SelectionGUI.SetGUIStatus(1, Main.SelectionGUI.SymmetryStatusText); return(false); } } if (!trigger) { if (symmetry && !symmetrySameColor) { Main.SelectionGUI.SetGUIStatus(0, "Click to update symmetry paint."); } else if (Main.InstantPaintAccess) { Main.SelectionGUI.SetGUIStatus(0, "Click to paint."); } else { Main.SelectionGUI.SetGUIStatus(0, "Hold click to paint."); } Main.SelectionGUI.SetGUIStatus(1, Main.SelectionGUI.SymmetryStatusText); } return(true); }
private void MoveToTarget() { m_logger.debugLog(m_stage != Stage.Approach && m_stage != Stage.Weld, "moving to target in wrong stage", Logger.severity.FATAL); if ((Globals.UpdateCount - m_lastWeld) > 1200ul) { m_logger.debugLog("failed to repair block"); EnableWelders(false); m_stage = Stage.Retreat; return; } if (m_weldProjection) { // check for slim being placed IMySlimBlock placed = m_realGrid.GetCubeBlock(m_targetCell); if (placed != null) { m_logger.debugLog("projected target placed", Logger.severity.DEBUG); m_weldProjection = false; m_targetSlim = placed; } } // check for weld float damage = m_targetSlim.Damage(); foreach (Vector3I cell in m_neighbours) { IMySlimBlock slim = m_realGrid.GetCubeBlock(cell); if (slim != null) damage += slim.Damage(); } if (damage < m_damage) m_lastWeld = Globals.UpdateCount; m_damage = damage; if (!m_weldProjection && m_targetSlim.Damage() == 0f && (Globals.UpdateCount - m_lastWeld) > 120ul) { m_logger.debugLog("target block repaired: " + m_targetSlim.getBestName(), Logger.severity.DEBUG); EnableWelders(false); m_stage = Stage.Retreat; return; } else { float offset = m_stage == Stage.Weld ? m_offset : m_offset + OffsetAdd; Vector3D welderFromTarget = m_controlBlock.CubeBlock.GetPosition() - m_targetWorld; welderFromTarget.Normalize(); m_mover.CalcMove(m_welder, m_targetWorld + welderFromTarget * offset, m_realGrid.Physics.LinearVelocity, true); } }
private bool AddPotentialBlock(IMySlimBlock block, bool remote = false, NaniteAreaBeacon beacon = null) { if (PotentialTargetList.Contains(block)) { return(false); } if (EntityHelper.GetDistanceBetweenBlockAndSlimblock((IMyCubeBlock)m_constructionBlock.ConstructionBlock, block) > m_maxDistance) { return(false); } if (!remote && block.FatBlock != null && block.FatBlock is IMyTerminalBlock && block.FatBlock.OwnerId != 0) { IMyTerminalBlock terminal = (IMyTerminalBlock)block.FatBlock; MyRelationsBetweenPlayerAndBlock relation = terminal.GetUserRelationToOwner(m_constructionBlock.ConstructionBlock.OwnerId); if (relation == MyRelationsBetweenPlayerAndBlock.Neutral || relation == MyRelationsBetweenPlayerAndBlock.Enemies) { return(false); } } else if (remote) { //if (block.CubeGrid.BigOwners.Count < 1) // return false; foreach (var item in block.CubeGrid.BigOwners) { MyRelationsBetweenPlayerAndBlock relation = m_constructionBlock.ConstructionBlock.GetUserRelationToOwner(item); if (relation == MyRelationsBetweenPlayerAndBlock.Neutral || relation == MyRelationsBetweenPlayerAndBlock.Enemies) { return(false); } } } if (!block.IsFullIntegrity || block.HasDeformation) { using (Lock.AcquireExclusiveUsing()) { if (beacon != null) { if (!m_areaTargetBlocks.ContainsKey(block)) { m_areaTargetBlocks.Add(block, beacon); } else { m_areaTargetBlocks[block] = beacon; } } PotentialTargetList.Add(block); return(true); } } return(false); }
/// <summary> /// if removed is a thruster, remove it from thrustersInDirection /// </summary> /// <remarks> /// if a working block is destroyed, block_IsWorkingChange() is called first /// </remarks> /// <param name="removed">block that was removed</param> private void grid_OnBlockRemoved(IMySlimBlock removed) { try { if (removed.FatBlock == null) return; MyThrust asThrust = removed.FatBlock as MyThrust; if (asThrust == null) return; using (lock_thrustersInDirection.AcquireExclusiveUsing()) thrustersInDirection[Base6Directions.GetFlippedDirection(asThrust.Orientation.Forward)].Remove(asThrust); myLogger.debugLog("removed thruster = " + removed.FatBlock.DefinitionDisplayNameText + "/" + asThrust.DisplayNameText, Logger.severity.DEBUG); m_primaryDirty = true; return; } catch (Exception e) { myLogger.alwaysLog("Exception: " + e, Logger.severity.ERROR); } }
internal void AddShieldHit(long attackerId, float amount, MyStringHash damageType, IMySlimBlock block, bool reset, Vector3D?hitPos = null) { lock (ShieldHit) { ShieldHit.Amount += amount; ShieldHit.DamageType = damageType.String; if (block != null && !hitPos.HasValue && ShieldHit.HitPos == Vector3D.Zero) { if (block.FatBlock != null) { ShieldHit.HitPos = block.FatBlock.PositionComp.WorldAABB.Center; } else { block.ComputeWorldCenter(out ShieldHit.HitPos); } } else if (hitPos.HasValue) { ShieldHit.HitPos = hitPos.Value; } if (attackerId != 0) { ShieldHit.AttackerId = attackerId; } if (amount > 0) { _lastSendDamageTick = _tick; } if (reset) { ShieldHitReset(true); } } }
/// <summary> /// Colours a block according to its integrity. /// </summary> private static void ColourBlock(IMySlimBlock realBlock, IMyCubeGrid holoGrid) { Static.logger.debugLog(realBlock == null, "realBlock == null", Logger.severity.FATAL); float integrityRatio = (realBlock.BuildIntegrity - realBlock.CurrentDamage) / realBlock.MaxIntegrity; float criticalRatio = ((MyCubeBlockDefinition)realBlock.BlockDefinition).CriticalIntegrityRatio; float scaledRatio; Color blockColour; Static.logger.debugLog(integrityRatio != 1f, "integrityRatio: " + integrityRatio + ", criticalRatio: " + criticalRatio + ", fatblock: " + realBlock.FatBlock.getBestName() + ", functional: " + (realBlock.FatBlock != null && realBlock.FatBlock.IsFunctional)); if (integrityRatio > criticalRatio && (realBlock.FatBlock == null || realBlock.FatBlock.IsFunctional)) { scaledRatio = (integrityRatio - criticalRatio) / (1f - criticalRatio); blockColour = IntegrityFull * scaledRatio + IntegrityFunctional * (1f - scaledRatio); } else { scaledRatio = integrityRatio / criticalRatio; blockColour = IntegrityDamaged * scaledRatio + IntegrityZero * (1f - scaledRatio); } holoGrid.ColorBlocks(realBlock.Position, realBlock.Position, blockColour.ColorToHSVDX11()); }
private void Actual_OnBlockRemoved(IMySlimBlock obj) { SeenHolo sh; if (!m_holoEntities.TryGetValue(obj.CubeGrid.EntityId, out sh)) { m_logger.debugLog("failed lookup of grid: " + obj.CubeGrid.DisplayName, Logger.severity.ERROR); obj.CubeGrid.OnBlockAdded -= Actual_OnBlockAdded; obj.CubeGrid.OnBlockRemoved -= Actual_OnBlockRemoved; return; } Vector3I position = obj.Position; IMyCubeGrid holo = (IMyCubeGrid)sh.Holo; holo.RemoveBlock(holo.GetCubeBlock(position)); }
private void Actual_OnBlockAdded(IMySlimBlock obj) { SeenHolo sh; if (!m_holoEntities.TryGetValue(obj.CubeGrid.EntityId, out sh)) { m_logger.debugLog("failed lookup of grid: " + obj.CubeGrid.DisplayName, Logger.severity.ERROR); obj.CubeGrid.OnBlockAdded -= Actual_OnBlockAdded; obj.CubeGrid.OnBlockRemoved -= Actual_OnBlockRemoved; return; } IMyCubeGrid holo = (IMyCubeGrid)sh.Holo; MyObjectBuilder_CubeBlock objBuilder = obj.GetObjectBuilder(); objBuilder.EntityId = 0L; holo.AddBlock(objBuilder, false); IMyCubeBlock cubeBlock = holo.GetCubeBlock(obj.Position).FatBlock; if (cubeBlock != null) SetupProjection(cubeBlock); }
/// <summary> /// if necessary, builds script for a block /// </summary> private void AddBlock(IMySlimBlock block) { IMyCubeBlock fatblock = block.FatBlock; if (fatblock != null) { if (!CubeBlocks.Add(fatblock.EntityId)) return; fatblock.OnClosing += alsoFatblock => { if (CubeBlocks != null) CubeBlocks.Remove(alsoFatblock.EntityId); }; MyObjectBuilderType typeId = fatblock.BlockDefinition.TypeId; //myLogger.debugLog("block definition: " + fatblock.DefinitionDisplayNameText + ", typeId: " + typeId, "AddBlock()"); // used to find which builder is associated with a block if (AllBlockScriptConstructors.ContainsKey(typeId)) foreach (Action<IMyCubeBlock> constructor in BlockScriptConstructor(typeId)) try { constructor.Invoke(fatblock); } catch (Exception ex) { myLogger.alwaysLog("Exception in " + typeId + " constructor: " + ex, Logger.severity.ERROR); Logger.debugNotify("Exception in " + typeId + " constructor", 10000, Logger.severity.ERROR); } if (EveryBlockScriptConstructors.Count > 0) foreach (Action<IMyCubeBlock> constructor in EveryBlockScriptConstructors) try { constructor.Invoke(fatblock); } catch (Exception ex) { myLogger.alwaysLog("Exception in every block constructor: " + ex, Logger.severity.ERROR); Logger.debugNotify("Exception in every block constructor", 10000, Logger.severity.ERROR); } return; } }
private void OnBlockIntegrityChanged(IMySlimBlock block) { SeenHolo sh; if (!m_holoEntities.TryGetValue(block.CubeGrid.EntityId, out sh)) { m_logger.debugLog("grid entity id lookup failed", Logger.severity.ERROR); ((MyCubeGrid)block.CubeGrid).OnBlockIntegrityChanged -= OnBlockIntegrityChanged; return; } IMyCubeGrid grid = (IMyCubeGrid)sh.Holo; if (sh.ColouredByIntegrity) ColourBlock(block, grid); UpdateBlockModel(block, grid); }
private void Handler(object target, ref MyDamageInformation info) { IMySlimBlock block = target as IMySlimBlock; if (block == null) { return; // End: Only reduce damage to blocks } IMyEntity ent = MyAPIGateway.Entities.GetEntityById(info.AttackerId); if (ent == null) { return; // End: Must be a player character } IMyHandheldGunObject <MyToolBase> tool = null; IMyHandheldGunObject <MyGunBase> gun = null; if (info.Type == MyDamageType.Grind) { tool = ent as IMyAngleGrinder; } else if (info.Type == MyDamageType.Drill) { tool = ent as IMyHandDrill; } else { gun = ent as IMyAutomaticRifleGun; } if (tool == null && gun == null) { return; // End: damage must be done by tool or hand weapon } bool isTool = tool != null; long identity = (isTool) ? tool.OwnerIdentityId : gun.OwnerIdentityId; List <IMyPlayer> players = new List <IMyPlayer>(); MyAPIGateway.Players.GetPlayers(players, p => p.IdentityId == identity); if (players.Count == 0 || // End: Player not found. this can happen if the character is an NPC block.CubeGrid.BigOwners.Count == 0) { return; // End: Unowned structures take full damage } MyRelationsBetweenPlayerAndBlock relation = players[0].GetRelationTo(block.CubeGrid.BigOwners[0]); if (!(relation == MyRelationsBetweenPlayerAndBlock.Enemies || relation == MyRelationsBetweenPlayerAndBlock.Neutral)) { return; // End: Friendly and unowned structures take full damage } if (block.FatBlock != null && block.FatBlock is IMyTerminalBlock) { if (block.FatBlock.OwnerId != 0) { info.Amount = info.Amount * (1 + (1 - MyAPIGateway.Session.HackSpeedMultiplier)) * GetTerminalBlockHackSpeedAboveFunctional(isTool); } else { info.Amount = info.Amount * GetTerminalBlockHackSpeedBelowFunctional(isTool); } } else { info.Amount = info.Amount * GetNonTerminalBlockHackSpeed(isTool); } }
private void Grid_OnBlockAdded(IMySlimBlock block) { AddRemoveActions.Enqueue(() => { AddBlock(block); }); }
private int GetMissingComponentCount(NaniteConstructionInventory inventoryManager, IMySlimBlock block) { Dictionary <string, int> missing = new Dictionary <string, int>(); block.GetMissingComponents(missing); if (missing.Count == 0) { return(0); } Dictionary <string, int> available = new Dictionary <string, int>(); inventoryManager.GetAvailableComponents(ref available); for (int r = missing.Count - 1; r >= 0; r--) { var item = missing.ElementAt(r); if (available.ContainsKey(item.Key)) { int amount = Math.Min(item.Value, available[item.Key]); available[item.Key] -= amount; missing[item.Key] -= amount; } } return(missing.Sum(x => x.Value)); }
public static void EnqueueRemoveBlock(IMySlimBlock block) { queueRemoveBlocks.Add(block); }
private void ProcessConstructionItem(IMySlimBlock target) { if (Sync.IsServer) { if (!IsEnabled()) { Logging.Instance.WriteLine("CANCELLING Construction/Repair Target due to being disabled"); CancelTarget(target); return; } if (!NaniteConstructionPower.HasRequiredPowerForCurrentTarget((IMyFunctionalBlock)m_constructionBlock.ConstructionBlock)) { Logging.Instance.WriteLine("CANCELLING Construction/Repair Target due to power shortage"); CancelTarget(target); return; } if (m_constructionBlock.FactoryState != NaniteConstructionBlock.FactoryStates.Active) { return; } if (!m_targetBlocks.ContainsKey(target)) { m_targetBlocks.Add(target, 0); } NaniteWelder welder = (NaniteWelder)m_constructionBlock.ToolManager.Tools.FirstOrDefault(x => x.TargetBlock == target && x is NaniteWelder); if (welder == null) { double distance = EntityHelper.GetDistanceBetweenBlockAndSlimblock((IMyCubeBlock)m_constructionBlock.ConstructionBlock, target); int time = (int)Math.Max(GetMinTravelTime() * 1000f, (distance / GetSpeed()) * 1000f); welder = new NaniteWelder(m_constructionBlock, target, (int)(time / 2.5f), false); m_constructionBlock.ToolManager.Tools.Add(welder); m_constructionBlock.SendAddTarget(target, TargetTypes.Construction); } if (target.IsFullIntegrity && !target.HasDeformation) { CompleteTarget(target); return; } if (m_areaTargetBlocks.ContainsKey(target)) { BoundingBoxD bb; target.GetWorldBoundingBox(out bb, true); if (!m_areaTargetBlocks[target].IsInsideBox(bb)) { CancelTarget(target); return; } } if (target.IsDestroyed || target.IsFullyDismounted || (target.FatBlock != null && target.FatBlock.Closed)) { Logging.Instance.WriteLine("CANCELLING Construction/Repair Target due to target being destroyed"); CancelTarget(target); return; } if (welder != null && MyAPIGateway.Session.ElapsedPlayTime.TotalMilliseconds - welder.StartTime >= welder.WaitTime) { target.MoveItemsToConstructionStockpile(((MyEntity)m_constructionBlock.ConstructionBlock).GetInventory()); Dictionary <string, int> missing = new Dictionary <string, int>(); target.GetMissingComponents(missing); if (!target.HasDeformation && !target.CanContinueBuild(((MyEntity)m_constructionBlock.ConstructionBlock).GetInventory())) { if (!MyAPIGateway.Session.CreativeMode) { Logging.Instance.WriteLine("CANCELLING Construction/Repair Target due to missing components"); foreach (var item in missing) { Logging.Instance.WriteLine(string.Format("Missing component: {0} - {1}", item.Value, item.Key)); } CancelTarget(target); } } return; } bool isRemote = false; using (m_remoteLock.AcquireExclusiveUsing()) { isRemote = m_remoteTargets.Contains(target); } if (isRemote && EntityHelper.GetDistanceBetweenBlockAndSlimblock((IMyCubeBlock)m_constructionBlock.ConstructionBlock, target) > m_maxDistance) { Logging.Instance.WriteLine("CANCELLING Repair Target due to target being out of range"); CancelTarget(target); return; } } CreateConstructionParticle(target); }