/// <summary> /// TODO: refineing rates should also limit the amount that can be refined for a specific mat each tick. /// </summary> internal static void RefineMaterials(Entity colony, Game game) { CargoStorageDB stockpiles = colony.GetDataBlob <CargoStorageDB>(); ColonyRefiningDB refiningDB = colony.GetDataBlob <ColonyRefiningDB>(); int RefineryPoints = refiningDB.PointsPerTick; for (int jobIndex = 0; jobIndex < refiningDB.JobBatchList.Count; jobIndex++) { if (RefineryPoints > 0) { var job = refiningDB.JobBatchList[jobIndex]; ProcessedMaterialSD material = game.StaticData.ProcessedMaterials[job.ItemGuid]; Dictionary <Guid, int> costs = new Dictionary <Guid, int>(material.RawMineralCosts); if (material.RefinedMateraialsCosts != null) { costs.Concat(new Dictionary <Guid, int>(material.RefinedMateraialsCosts)); } while (job.NumberCompleted < job.NumberOrdered && job.PointsLeft > 0) { if (job.PointsLeft == material.RefineryPointCost) { //consume all ingredients for this job on the first point use. if (StorageSpaceProcessor.HasReqiredItems(stockpiles, costs)) { StorageSpaceProcessor.RemoveResources(stockpiles, costs); } else { break; } } //use Refinery points ushort pointsUsed = (ushort)Math.Min(job.PointsLeft, material.RefineryPointCost); job.PointsLeft -= pointsUsed; RefineryPoints -= pointsUsed; //if job is complete if (job.PointsLeft == 0) { job.NumberCompleted++; //complete job, StorageSpaceProcessor.AddItemToCargo(stockpiles, material.ID, material.OutputAmount); //and add the product to the stockpile job.PointsLeft = material.RefineryPointCost; //and reset the points left for the next job in the batch. } } //if the whole batch is completed if (job.NumberCompleted == job.NumberOrdered) { //remove it from the list refiningDB.JobBatchList.RemoveAt(jobIndex); if (job.Auto) //but if it's set to auto, re-add it. { job.PointsLeft = material.RefineryPointCost; job.NumberCompleted = 0; refiningDB.JobBatchList.Add(job); } } } } }
/// <summary> /// process PropulsionDB movement for a single system /// </summary> /// <param name="manager">the system to process</param> /// <param name="deltaSeconds">amount of time in seconds</param> internal static void Process(EntityManager manager, int deltaSeconds) { OrderProcessor.ProcessSystem(manager); foreach (Entity shipEntity in manager.GetAllEntitiesWithDataBlob <PropulsionDB>()) { PositionDB positionDB = shipEntity.GetDataBlob <PositionDB>(); PropulsionDB propulsionDB = shipEntity.GetDataBlob <PropulsionDB>(); Queue <BaseOrder> orders = shipEntity.GetDataBlob <ShipInfoDB>().Orders; if (orders.Count > 0) { if (orders.Peek().OrderType == orderType.MOVETO) { // Check to see if we will overtake the target MoveOrder order = (MoveOrder)orders.Peek(); Vector4 shipPos = positionDB.AbsolutePosition; Vector4 targetPos; Vector4 currentSpeed = shipEntity.GetDataBlob <PropulsionDB>().CurrentSpeed; Vector4 nextTPos = shipPos + (currentSpeed * deltaSeconds); Vector4 newPos = shipPos; Vector4 deltaVecToTarget; Vector4 deltaVecToNextT; double distanceToTarget; double distanceToNextTPos; double speedDelta; double distanceDelta; double newDistanceDelta; double fuelMaxDistanceAU; double currentSpeedLength = currentSpeed.Length(); CargoStorageDB storedResources = shipEntity.GetDataBlob <CargoStorageDB>(); Dictionary <Guid, double> fuelUsePerMeter = propulsionDB.FuelUsePerKM; int maxKMeters = CalcMaxFuelDistance(shipEntity); if (order.PositionTarget == null) { targetPos = order.Target.GetDataBlob <PositionDB>().AbsolutePosition; } else { targetPos = order.PositionTarget.AbsolutePosition; } deltaVecToTarget = shipPos - targetPos; distanceToTarget = deltaVecToTarget.Length(); //in au deltaVecToNextT = shipPos - nextTPos; fuelMaxDistanceAU = GameConstants.Units.KmPerAu * maxKMeters; distanceToNextTPos = deltaVecToNextT.Length(); if (fuelMaxDistanceAU < distanceToNextTPos) { newDistanceDelta = fuelMaxDistanceAU; double percent = fuelMaxDistanceAU / distanceToNextTPos; newPos = nextTPos + deltaVecToNextT * percent; Event usedAllFuel = new Event(manager.ManagerSubpulses.SystemLocalDateTime, "Used all Fuel", shipEntity.GetDataBlob <OwnedDB>().ObjectOwner, shipEntity); usedAllFuel.EventType = EventType.FuelExhausted; manager.Game.EventLog.AddEvent(usedAllFuel); } else { newDistanceDelta = distanceToNextTPos; newPos = nextTPos; } if (distanceToTarget < newDistanceDelta) // moving would overtake target, just go directly to target { newDistanceDelta = distanceToTarget; propulsionDB.CurrentSpeed = new Vector4(0, 0, 0, 0); newPos = targetPos; if (order.Target != null && order.Target.HasDataBlob <SystemBodyInfoDB>()) { positionDB.SetParent(order.Target); } if (order.Target != null) { if (order.Target.HasDataBlob <SystemBodyInfoDB>()) // Set position to the target body { positionDB.SetParent(order.Target); } } else // We arrived, get rid of the order { shipEntity.GetDataBlob <ShipInfoDB>().Orders.Dequeue(); } } positionDB.AbsolutePosition = newPos; int kMetersMoved = (int)(newDistanceDelta * GameConstants.Units.KmPerAu); Dictionary <Guid, int> fuelAmounts = new Dictionary <Guid, int>(); foreach (var item in propulsionDB.FuelUsePerKM) { fuelAmounts.Add(item.Key, (int)item.Value * kMetersMoved); } StorageSpaceProcessor.RemoveResources(storedResources, fuelAmounts); } } } }