public override void UpdateAfterSimulation100() { base.UpdateAfterSimulation100(); // Will not consume anything when disabled. int timeDelta = 100 * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_MILLISECONDS; if (Enabled && !MySession.Static.CreativeMode) { ProfilerShort.Begin("ConsumeCondition"); if ((Sync.IsServer && IsWorking && !CubeGrid.GridSystems.ControlSystem.IsControlled) || CubeGrid.GridSystems.ControlSystem.IsLocallyControlled) { ProfilerShort.Begin("ConsumeFuel"); ConsumeFuel(timeDelta); ProfilerShort.End(); } ProfilerShort.End(); } if (Sync.IsServer && IsFunctional && m_useConveyorSystem && this.GetInventory().VolumeFillFactor < 0.6f) { float consumptionPerSecond = m_reactorDefinition.MaxPowerOutput / SourceComp.ProductionToCapacityMultiplier; var consumedUranium = (60 * consumptionPerSecond); // Take enough uranium for one minute of operation consumedUranium /= m_reactorDefinition.FuelDefinition.Mass; // Convert weight to number of items ProfilerShort.Begin("PullRequest"); MyGridConveyorSystem.ItemPullRequest(this, this.GetInventory(), OwnerId, m_reactorDefinition.FuelId, (MyFixedPoint)consumedUranium); ProfilerShort.End(); } }
public override void UpdateBeforeSimulation100() { base.UpdateBeforeSimulation100(); if (Sync.IsServer && IsFunctional && (this as IMyInventoryOwner).UseConveyorSystem) { if (MySession.Static.SurvivalMode && m_ammoInventory.VolumeFillFactor < 0.5f) { MyGridConveyorSystem.ItemPullRequest(this, m_ammoInventory, OwnerId, m_gunBase.CurrentAmmoMagazineId, 1); } } }
public override void UpdateBeforeSimulation100() { base.UpdateBeforeSimulation100(); if (m_useConveyorSystem) { if (MySession.Static.SurvivalMode && Sync.IsServer && IsWorking && this.GetInventory().VolumeFillFactor < 0.5f) { MyGridConveyorSystem.ItemPullRequest(this, this.GetInventory(), OwnerId, m_gunBase.CurrentAmmoMagazineId, 1); } } }
public override void UpdateAfterSimulation100() { base.UpdateAfterSimulation100(); /*if (MyFakes.SHOW_DAMAGE_EFFECTS) * { * if (SlimBlock.ComponentStack.IsFunctional && m_damageEffect != null) * { * m_damageEffect.Stop(); * m_damageEffect = null; * NeedsUpdate &= ~MyEntityUpdateEnum.EACH_FRAME; * } * * if (!SlimBlock.ComponentStack.IsFunctional && m_damageEffect == null) * { * if (MyParticlesManager.TryCreateParticleEffect((int)MyParticleEffectsIDEnum.Prefab_LeakingSteamWhite, out m_damageEffect)) * { * m_damageEffect.UserScale = 0.2f; * m_damageEffect.WorldMatrix = WorldMatrix; * m_damageEffect.OnDelete += damageEffect_OnDelete; * } * NeedsUpdate |= MyEntityUpdateEnum.EACH_FRAME; * } * }*/ // Will not consume anything when disabled. int timeDelta = 100 * MyEngineConstants.UPDATE_STEP_SIZE_IN_MILLISECONDS; if (Enabled && !MySession.Static.CreativeMode) { ProfilerShort.Begin("ConsumeCondition"); if ((Sync.IsServer && IsWorking && !CubeGrid.GridSystems.ControlSystem.IsControlled) || CubeGrid.GridSystems.ControlSystem.IsLocallyControlled) { ProfilerShort.Begin("ConsumeFuel"); ConsumeFuel(timeDelta); ProfilerShort.End(); } ProfilerShort.End(); } if (Sync.IsServer && IsFunctional && m_useConveyorSystem && m_inventory.VolumeFillFactor < 0.6f) { float consumptionPerSecond = m_reactorDefinition.MaxPowerOutput / (60 * 60); var consumedUranium = (60 * consumptionPerSecond); // Take enough uranium for one minute of operation consumedUranium /= m_reactorDefinition.FuelDefinition.Mass; // Convert weight to number of items ProfilerShort.Begin("PullRequest"); MyGridConveyorSystem.ItemPullRequest(this, m_inventory, OwnerId, m_reactorDefinition.FuelId, (MyFixedPoint)consumedUranium); ProfilerShort.End(); } }
public override void UpdateAfterSimulation10() { base.UpdateAfterSimulation10(); if (MySession.Static.SurvivalMode && Sync.IsServer && IsWorking && m_useConveyorSystem && m_ammoInventory.VolumeFillFactor < 0.6f) { var definition = m_gunBase.CurrentAmmoMagazineDefinition; //MyDefinitionManager.Static.GetPhysicalItemDefinition(m_currentAmmoMagazineId); if (definition != null) { var maxNum = MyFixedPoint.Floor((m_ammoInventory.MaxVolume - m_ammoInventory.CurrentVolume) * (1.0f / definition.Volume)); if (maxNum == 0) { return; } MyGridConveyorSystem.ItemPullRequest(this, m_ammoInventory, OwnerId, m_gunBase.CurrentAmmoMagazineId, maxNum); } } }
private void TakeMaterialsFromBuilder(MyEntity builder) { // CH: TODO: Please refactor this to not be so ugly. Especially, calling the Solve function multiple times on the component combiner is bad... if (builder == null) { return; } var inventory = GetBuilderInventory(builder); if (inventory == null) { return; } MyInventory shipInventory = null; MyCockpit cockpit = null; long identityId = long.MaxValue; if (builder is MyCharacter) {//construction cockpit? cockpit = (builder as MyCharacter).IsUsing as MyCockpit; if (cockpit != null) { shipInventory = cockpit.GetInventory(); identityId = cockpit.ControllerInfo.ControllingIdentityId; } else if ((builder as MyCharacter).ControllerInfo != null) { identityId = (builder as MyCharacter).ControllerInfo.ControllingIdentityId; } else { Debug.Fail("failed to get identityId"); } } VRage.MyFixedPoint hasAmount, hasAmountCockpit; foreach (var entry in m_materialList.RequiredMaterials) { VRage.MyFixedPoint toRemove = entry.Value; hasAmount = inventory.GetItemAmount(entry.Key); if (hasAmount > entry.Value) { inventory.RemoveItemsOfType(toRemove, entry.Key); continue; } if (hasAmount > 0) { inventory.RemoveItemsOfType(hasAmount, entry.Key); toRemove -= hasAmount; } if (shipInventory != null) { hasAmountCockpit = shipInventory.GetItemAmount(entry.Key); if (hasAmountCockpit >= toRemove) { shipInventory.RemoveItemsOfType(toRemove, entry.Key); continue; } if (hasAmountCockpit > 0) { shipInventory.RemoveItemsOfType(hasAmountCockpit, entry.Key); toRemove -= hasAmountCockpit; } var transferred = MyGridConveyorSystem.ItemPullRequest(cockpit, shipInventory, identityId, entry.Key, toRemove, true); Debug.Assert(transferred == toRemove, "Cannot pull enough materials to build, " + transferred + "!=" + toRemove); } else { Debug.Assert(toRemove == 0, "Needs more materials and ship inventory is null"); } } }
public override void UpdateBeforeSimulation100() { base.UpdateBeforeSimulation100(); if (m_inventoryOwnersDirty) { GetCoveyorInventoryOwners(); } if (Sync.IsServer && IsWorking && m_useConveyorSystem) { if (DisassembleEnabled) // Dissasembling { if (OutputInventory.VolumeFillFactor < 0.99f) { //MyGridConveyorSystem.PullAllRequest(this, OutputInventory, OwnerId, OutputInventory.Constraint); var item = TryGetFirstQueueItem(); if (item != null) { if (!OutputInventory.ContainItems(null, item.Value.Blueprint.Results[0].Id)) { MyGridConveyorSystem.ItemPullRequest(this, OutputInventory, OwnerId, item.Value.Blueprint.Results[0].Id, item.Value.Amount); } } } if (InputInventory.VolumeFillFactor > 0.75f) { Debug.Assert(InputInventory.GetItems().Count > 0); MyGridConveyorSystem.PushAnyRequest(this, InputInventory, OwnerId); } } else // Assembling { if (IsSlave && m_queue.Count < 1 && MyFakes.ENABLE_ASSEMBLER_COOPERATION && !RepeatEnabled) { GetItemFromOtherAssemblers(); } if (InputInventory.VolumeFillFactor < 0.99f) { var next = false; int i = 0; var time = 0f; do { var item = TryGetQueueItem(i); if (item.HasValue) { var factor = MySession.Static.AssemblerSpeedMultiplier / MySession.Static.AssemblerEfficiencyMultiplier; var itemAmount = 1; var remainingTime = TIME_IN_ADVANCE - time; if (item.Value.Blueprint.BaseProductionTimeInSeconds < remainingTime) { itemAmount = Math.Min((int)item.Value.Amount, Convert.ToInt32(Math.Floor(remainingTime / (item.Value.Blueprint.BaseProductionTimeInSeconds / factor)))); time += itemAmount * item.Value.Blueprint.BaseProductionTimeInSeconds / MySession.Static.AssemblerSpeedMultiplier; if (time < TIME_IN_ADVANCE) { next = true; } } foreach (var component in item.Value.Blueprint.Prerequisites) { var availableAmount = InputInventory.GetItemAmount(component.Id); if (i > 0) { availableAmount = 0; } var neededAmount = component.Amount * itemAmount - availableAmount; if (neededAmount <= 0) { continue; } MyGridConveyorSystem.ItemPullRequest(this, InputInventory, OwnerId, component.Id, neededAmount); } } if (i > 0) { next = false; } i++; } while (next); } if (OutputInventory.VolumeFillFactor > 0.75f) { Debug.Assert(OutputInventory.GetItems().Count > 0); MyGridConveyorSystem.PushAnyRequest(this, OutputInventory, OwnerId); } } } }
protected override bool Activate(HashSet <MySlimBlock> targets) { bool welding = false; bool unweldedBlocksDetected = false; int targetCount = targets.Count; m_missingComponents.Clear(); foreach (var block in targets) { if (block.BuildLevelRatio == 1.0f || block == SlimBlock) { targetCount--; continue; } block.GetMissingComponents(m_missingComponents); } foreach (var component in m_missingComponents) { var componentId = new MyDefinitionId(typeof(MyObjectBuilder_Component), component.Key); int amount = Math.Max(component.Value - (int)this.GetInventory().GetItemAmount(componentId), 0); if (amount == 0) { continue; } if (Sync.IsServer && UseConveyorSystem) { var group = MyDefinitionManager.Static.GetGroupForComponent(componentId, out amount); if (group == null) { MyComponentSubstitutionDefinition substitutions; if (MyDefinitionManager.Static.TryGetComponentSubstitutionDefinition(componentId, out substitutions)) { foreach (var providingComponent in substitutions.ProvidingComponents) { MyFixedPoint substituionAmount = (int)component.Value / providingComponent.Value; MyGridConveyorSystem.ItemPullRequest(this, this.GetInventory(), OwnerId, providingComponent.Key, substituionAmount); } } else { MyGridConveyorSystem.ItemPullRequest(this, this.GetInventory(), OwnerId, componentId, component.Value); } } else { MyGridConveyorSystem.ItemPullRequest(this, this.GetInventory(), OwnerId, componentId, component.Value); } } } if (Sync.IsServer) { float coefficient = (MyShipGrinderConstants.GRINDER_COOLDOWN_IN_MILISECONDS * 0.001f) / (targetCount > 0?targetCount:1); foreach (var block in targets) { // Don't weld yourself if (block == SlimBlock) { continue; } if (!block.IsFullIntegrity) { unweldedBlocksDetected = true; } if (block.CanContinueBuild(this.GetInventory())) { welding = true; } block.MoveItemsToConstructionStockpile(this.GetInventory()); // Allow welding only for blocks with deformations or unfinished/damaged blocks if ((block.HasDeformation || block.MaxDeformation > 0.0001f) || !block.IsFullIntegrity) { float maxAllowedBoneMovement = WELDER_MAX_REPAIR_BONE_MOVEMENT_SPEED * MyShipGrinderConstants.GRINDER_COOLDOWN_IN_MILISECONDS * 0.001f; block.IncreaseMountLevel(MySession.Static.WelderSpeedMultiplier * WELDER_AMOUNT_PER_SECOND * coefficient, OwnerId, this.GetInventory(), maxAllowedBoneMovement, m_helpOthers, IDModule.ShareMode); } } } else { foreach (var block in targets) { // Don't weld yourself if (block == SlimBlock) { continue; } if (block.CanContinueBuild(this.GetInventory())) { welding = true; } } } m_missingComponents.Clear(); if (!unweldedBlocksDetected && Sync.IsServer) { //Try to build blocks for projections var blocks = FindProjectedBlocks(); //Try to acquire materials first, but only if it uses the conveyor system if (UseConveyorSystem) { foreach (var info in blocks) { var components = info.hitCube.BlockDefinition.Components; if (components == null || components.Length == 0) { continue; } var componentId = components[0].Definition.Id; MyGridConveyorSystem.ItemPullRequest(this, this.GetInventory(), OwnerId, componentId, 1); } } var locations = new HashSet <MyCubeGrid.MyBlockLocation>(); foreach (var info in blocks) { if (MySession.Static.CreativeMode || this.GetInventory().ContainItems(1, info.hitCube.BlockDefinition.Components[0].Definition.Id)) { info.cubeProjector.Build(info.hitCube, OwnerId, EntityId); welding = true; } } } if (welding) { SetBuildingMusic(150); } return(welding); }
private static bool StepWeld(ShipyardItem shipyardItem) { HashSet <long> stalledWelders = new HashSet <long>(); var missingComponents = new Dictionary <string, int>(); var random = new Random(); float weldAmount = Server.Instance.Config.WelderSpeedMultiplier * PluginSettings.Instance.WeldMultiplier; float boneAmount = weldAmount * .1f; //shorten this to grid for convenience MyCubeGrid grid = shipyardItem.Grid; if (grid?.Physics == null || grid.Closed) { return(false); } var weldBlocks = new HashSet <MySlimBlock>(); foreach (MySlimBlock block in grid.CubeBlocks.Where(block => !block.IsFullIntegrity || (block.HasDeformation || block.MaxDeformation > 0.0001f))) { weldBlocks.Add(block); } //if we have no blocks to weld, return false so we know we're done if (weldBlocks.Count == 0) { if (shipyardItem.GridProjector == null) { foreach (var block in shipyardItem.Grid.GetFatBlocks()) { MyProjectorBase projector = block as MyProjectorBase; if (projector?.Clipboard.PreviewGrids.Count > 0) { /* * bool canBuild = false; * Wrapper.GameAction( () => canBuild = projector.Clipboard.PreviewGrids[0].CubeBlocks.All(x => projector.CanBuild(x, true) != MyProjectorBase.BuildCheckResult.OK)); * if ( !canBuild) * continue; */ shipyardItem.GridProjector = projector; break; } } } } if (weldBlocks.Count < 8 && shipyardItem.GridProjector?.Clipboard.PreviewGrids.Count > 0) { int neededBlocks = 8 - weldBlocks.Count; //shipyardItem.ProcessBlocks.Clear(); for (int b = 0; b < neededBlocks; b++) { var welder = shipyardItem.Tools[b]; var projector = shipyardItem.GridProjector; var projectedGrid = projector.Clipboard.PreviewGrids[0]; MySlimBlock buildBlock = null; Wrapper.GameAction(() => { //buildBlock = projectedGrid.CubeBlocks.First( x => projector.CanBuild( x, true ) == MyProjectorBase.BuildCheckResult.OK ); foreach (var block in projectedGrid.CubeBlocks) { if (projector.CanBuild(block, true) == MyProjectorBase.BuildCheckResult.OK) { buildBlock = block; break; } } if (buildBlock == null) { return; } var welderInventory = (MyInventory)((IMyShipWelder)welder).GetInventory(0); var components = buildBlock.BlockDefinition.Components; if (components == null || components.Length == 0) { return; } var componentId = components[0].Definition.Id; MyGridConveyorSystem.ItemPullRequest((IMyConveyorEndpointBlock)welder, welderInventory, welder.OwnerId, componentId, 1); if (welderInventory.ContainItems(1, buildBlock.BlockDefinition.Components[0].Definition.Id)) { projector.Build(buildBlock, welder.OwnerId, welder.EntityId); } }); /* * Communication.MessageStruct message = new Communication.MessageStruct() * { * toolId=welder.EntityId, * gridId=buildBlock.CubeGrid.EntityId, * blockPos=buildBlock.Position, * packedColor = Color.LightGreen.PackedValue, * pulse=false * }; * Communication.SendLine( message ); */ //if (buildBlock!=null) //weldBlocks.Add( buildBlock ); } } if (shipyardItem.GridProjector?.Clipboard.PreviewGrids.Count == 0) { shipyardItem.GridProjector = null; return(false); } foreach (IMyCubeBlock welder in shipyardItem.Tools) { if (!shipyardItem.ProcessBlocks.ContainsKey(welder.EntityId)) { MySlimBlock nextBlock = null; var tryCount = 0; while (tryCount < 20) { //limit the number of tries so we don't get stuck in a loop forever tryCount++; //pick a random block. we don't really care if two welders hit the same block, so don't check if (weldBlocks.Count > 1) { nextBlock = weldBlocks.ElementAt(random.Next(0, weldBlocks.Count - 1)); } else { nextBlock = weldBlocks.FirstElement(); } if (nextBlock == null) { continue; } if (!nextBlock.IsFullIntegrity || (nextBlock.HasDeformation || nextBlock.MaxDeformation > 0.0001f)) { break; } } //we weren't able to find a suitable block somehow, so skip this welder for now if (nextBlock == null) { continue; } //we found a block to pair with our welder, add it to the dictionary and carry on with destruction shipyardItem.ProcessBlocks.Add(welder.EntityId, nextBlock); } } if (shipyardItem.ProcessBlocks.Count < 1) { //No more blocks to weld return(false); } Wrapper.GameAction(() => { foreach (IMyCubeBlock welderBlock in shipyardItem.Tools) { var welder = (IMyShipWelder)welderBlock; var welderInventory = (MyInventory)welder.GetInventory(0); MySlimBlock block; shipyardItem.ProcessBlocks.TryGetValue(welderBlock.EntityId, out block); if (block?.CubeGrid?.Physics == null) { continue; } if (!(!block.IsFullIntegrity || (block.HasDeformation || block.MaxDeformation > 0.0001f))) { shipyardItem.ProcessBlocks.Remove(welder.EntityId); continue; } block.GetMissingComponents(missingComponents); foreach (KeyValuePair <string, int> component in missingComponents) { var componentId = new MyDefinitionId(typeof(MyObjectBuilder_Component), component.Key); int amount = Math.Max(component.Value - (int)welderInventory.GetItemAmount(componentId), 0); if (amount == 0) { continue; } if (welder.UseConveyorSystem) { MyGridConveyorSystem.ItemPullRequest((IMyConveyorEndpointBlock)welder, welderInventory, welder.OwnerId, componentId, component.Value); } } block.MoveItemsToConstructionStockpile((MyInventory)welder.GetInventory(0)); block.IncreaseMountLevel(weldAmount, 0, null, boneAmount, true); if (!block.CanContinueBuild((MyInventory)welder.GetInventory(0)) && !block.IsFullIntegrity) { stalledWelders.Add(welder.EntityId); } } }); foreach (var tool in shipyardItem.Tools) { MySlimBlock targetBlock; Communication.MessageStruct message = new Communication.MessageStruct() { toolId = tool.EntityId, gridId = 0, blockPos = new SerializableVector3I(), packedColor = 0 }; if (!shipyardItem.ProcessBlocks.TryGetValue(tool.EntityId, out targetBlock)) { Communication.SendLine(message); continue; } message.gridId = targetBlock.CubeGrid.EntityId; message.blockPos = targetBlock.Position; if (stalledWelders.Contains(tool.EntityId)) { message.packedColor = Color.Purple.PackedValue; message.pulse = true; } else { message.packedColor = Color.DarkCyan.PackedValue; message.pulse = false; } Communication.SendLine(message); } return(true); }
public override void UpdateBeforeSimulation100() { base.UpdateBeforeSimulation100(); if (m_inventoryOwnersDirty) { GetCoveyorInventoryOwners(); } if (Sync.IsServer && IsWorking && m_useConveyorSystem) { if (DisassembleEnabled) // Dissasembling { if (OutputInventory.VolumeFillFactor < 0.99f) { //MyGridConveyorSystem.PullAllRequest(this, OutputInventory, OwnerId, OutputInventory.Constraint); var item = TryGetFirstQueueItem(); if (item != null) { if (!OutputInventory.ContainItems(null, item.Value.Blueprint.Results[0].Id)) { MyGridConveyorSystem.ItemPullRequest(this, OutputInventory, OwnerId, item.Value.Blueprint.Results[0].Id, item.Value.Amount); } } } if (InputInventory.VolumeFillFactor > 0.75f) { Debug.Assert(InputInventory.GetItems().Count > 0); MyGridConveyorSystem.PushAnyRequest(this, InputInventory, OwnerId); } } else // Assembling { //if (IsSlave && m_queue.Count < 1 && MyFakes.ENABLE_ASSEMBLER_COOPERATION && !RepeatEnabled) //{ // GetItemFromOtherAssemblers(TIME_IN_ADVANCE); //} if (InputInventory.VolumeFillFactor < 0.99f) { m_requiredComponents.Clear(); var next = false; int i = 0; var time = 0f; do { var item = TryGetQueueItem(i); var remainingTime = TIME_IN_ADVANCE - time; if (item.HasValue) { var productivity = (((MyAssemblerDefinition)BlockDefinition).AssemblySpeed + UpgradeValues["Productivity"]); var factor = MySession.Static.AssemblerSpeedMultiplier * productivity; var itemAmount = 1; if (item.Value.Blueprint.BaseProductionTimeInSeconds / factor < remainingTime) { itemAmount = Math.Min((int)item.Value.Amount, Convert.ToInt32(Math.Ceiling(remainingTime / (item.Value.Blueprint.BaseProductionTimeInSeconds / factor)))); } time += itemAmount * item.Value.Blueprint.BaseProductionTimeInSeconds / factor; if (time < TIME_IN_ADVANCE) { next = true; } var amountMult = (MyFixedPoint)(1.0f / MySession.Static.AssemblerEfficiencyMultiplier); foreach (var component in item.Value.Blueprint.Prerequisites) { var requiredAmount = component.Amount * itemAmount * amountMult; bool found = false; for (int j = 0; j < m_requiredComponents.Count; j++) { if (m_requiredComponents[j].Id == component.Id) { m_requiredComponents[j] = new MyBlueprintDefinitionBase.Item { Amount = m_requiredComponents[j].Amount + requiredAmount, Id = component.Id }; found = true; break; } } if (!found) { m_requiredComponents.Add(new MyBlueprintDefinitionBase.Item { Amount = requiredAmount, Id = component.Id }); } } } i++; if (i >= m_queue.Count) { next = false; } } while (next); foreach (var component in m_requiredComponents) { var availableAmount = InputInventory.GetItemAmount(component.Id); var neededAmount = component.Amount - availableAmount; if (neededAmount <= 0) { continue; } MyGridConveyorSystem.ItemPullRequest(this, InputInventory, OwnerId, component.Id, neededAmount); } if (IsSlave && !RepeatEnabled) { var remainingTime = TIME_IN_ADVANCE - time; if (remainingTime > 0) { GetItemFromOtherAssemblers(remainingTime); } } } if (OutputInventory.VolumeFillFactor > 0.75f) { Debug.Assert(OutputInventory.GetItems().Count > 0); MyGridConveyorSystem.PushAnyRequest(this, OutputInventory, OwnerId); } } } }