/// <summary> /// Called at the end of a round. Distributes rewards to winning factions. /// </summary> public void distributeRewards() { if (!Utility.isServer()) { return; } log("Distributing rewards for CP " + Name, "distributeRewards"); // group nearby grids into their corresponding fleets Dictionary <long, Subfleet> subfleets = nearbySubfleets(); // if there are no grids, nothing to do if (subfleets.Keys.Count == 0) { return; } // determine which subfleet won List <long> winningSubfleets = winningSubfleetIDs(subfleets); log("Winning fleets: " + String.Join(",", winningSubfleets.ToArray()), "distributeRewards"); // distribute rewards int remainingReward = TokensPerPeriod; //var rewardsByFleet = new Dictionary<long, int>(); if (winningSubfleets.Count == 1) { long winningFleetID = winningSubfleets.First(); Subfleet winningFleet = subfleets[winningFleetID]; // Place them in grids in order of decreasing multiplier winningFleet.Enforcers.Sort((a, b) => (int)a.CaptureMultiplier.CompareTo((int)b.CaptureMultiplier)); foreach (GridEnforcer ge in winningFleet.Enforcers) { if (remainingReward > 0) { log(String.Format("Attempting to place {0} licenses in {1}", remainingReward, ge.Grid.DisplayName), "distributeRewards"); remainingReward = ge.Grid.placeInCargo( ShipLicense.Definition, ShipLicense.Builder, remainingReward); } else { break; } } } log("Unplaced reward: " + remainingReward, "distributeRewards"); // notify players notifyRewardsDistributed(TokensPerPeriod - remainingReward, winningSubfleets, nearbyPlayers(), this); }
/// <summary> /// Group grids in the CP into subfleets /// </summary> private Dictionary <long, Subfleet> nearbySubfleets() { var foundSubfleets = new Dictionary <long, Subfleet>(); log("Grouping nearby grids into Subfleets.", "nearbySubfleets"); VRageMath.BoundingSphereD bounds = new VRageMath.BoundingSphereD(Position, (double)Radius); List <IMyEntity> entitiesInBounds = MyAPIGateway.Entities.GetEntitiesInSphere(ref bounds); foreach (IMyEntity e in entitiesInBounds) { // Is it a grid? IMyCubeGrid grid = e as IMyCubeGrid; if (grid == null) { continue; } // does it have a GE? GridEnforcer ge = grid.Components.Get <MyGameLogicComponent>() as GridEnforcer; if (ge == null) { log("Failed to retrieve GridEnforcer for grid " + grid.EntityId, "nearbySubfleets", Logger.severity.ERROR); continue; } // Is it classified? if (ge.Class == HullClass.CLASS.UNCLASSIFIED) { continue; } // There are no hooks to check if someone changed factions, // so reevaluate here to make sure info is up to date for fleet groups ge.reevaluateOwnership(); /* * if (ge.Owner.OwnerType == GridOwner.OWNER_TYPE.UNOWNED) { * log("Grid " + grid.EntityId + " is unowned, skipping", * "nearbySubfleets"); * continue; * } */ // We could check here if the grid is supported by its fleet, // or more generally if it's violation any rules // But we should notify players, b/c that could be confusing /* * if (!ge.SupportedByFleet) { * log("Grid " + grid.DisplayName + " is unsupported by its fleet, skipping.", * "getRoundWinner"); * continue; * } */ // Is its Hull Classifier broadcasting far enough? HullClassifier classifier = ge.Classifier; if (classifier == null) { log("Grid has no classifier but was classified", "nearbySubfleets", Logger.severity.ERROR); continue; } IMyCubeBlock fatblock = classifier.FatBlock; if (fatblock == null) { log("Classifier could not be referenced as fatblock", "nearbySubfleets", Logger.severity.ERROR); continue; } if (!fatblock.IsWorking) { log("Classifier not working but grid was classified", "nearbySubfleets", Logger.severity.ERROR); continue; } InGame.IMyBeacon beacon = fatblock as InGame.IMyBeacon; InGame.IMyRadioAntenna antenna = fatblock as InGame.IMyRadioAntenna; if (beacon == null && antenna == null) { log("Classifier not a beacon or antennae, no broadcast radius", "nearbySubfleets", Logger.severity.ERROR); continue; } if (beacon != null && beacon.Radius < VRageMath.Vector3.Distance(Position, grid.GetPosition())) { log("Classifier range too small, skipping", "nearbySubfleets"); // TODO notify pilot continue; } if (antenna != null && antenna.Radius < VRageMath.Vector3.Distance(Position, grid.GetPosition())) { log("Classifier range too small, skipping", "nearbySubfleets"); // TODO notify pilot continue; } // Grid passed all tests! long fleetID = ge.Owner.FleetID; log("Grid '" + ge.Grid.DisplayName + "'passed all tests, including in fleet " + fleetID, "nearbySubfleets"); if (!foundSubfleets.ContainsKey(fleetID)) { foundSubfleets[fleetID] = new Subfleet { ID = fleetID, Enforcers = new List <GridEnforcer>() { ge }, TotalValue = ge.CaptureMultiplier, }; } else { foundSubfleets[fleetID].Enforcers.Add(ge); foundSubfleets[fleetID].TotalValue += ge.CaptureMultiplier; } } return(foundSubfleets); }
/// <summary> /// Group grids in the CP into subfleets /// </summary> private Dictionary<long, Subfleet> nearbySubfleets() { var foundSubfleets = new Dictionary<long, Subfleet>(); log("Grouping nearby grids into Subfleets.", "nearbySubfleets"); VRageMath.BoundingSphereD bounds = new VRageMath.BoundingSphereD(Position, (double)Radius); List<IMyEntity> entitiesInBounds = MyAPIGateway.Entities.GetEntitiesInSphere(ref bounds); foreach (IMyEntity e in entitiesInBounds) { // Is it a grid? IMyCubeGrid grid = e as IMyCubeGrid; if (grid == null) continue; // does it have a GE? GridEnforcer ge = grid.Components.Get<MyGameLogicComponent>() as GridEnforcer; if (ge == null) { log("Failed to retrieve GridEnforcer for grid " + grid.EntityId, "nearbySubfleets", Logger.severity.ERROR); continue; } // Is it classified? if (ge.Class == HullClass.CLASS.UNCLASSIFIED) { continue; } // There are no hooks to check if someone changed factions, // so reevaluate here to make sure info is up to date for fleet groups ge.reevaluateOwnership(); /* if (ge.Owner.OwnerType == GridOwner.OWNER_TYPE.UNOWNED) { log("Grid " + grid.EntityId + " is unowned, skipping", "nearbySubfleets"); continue; } */ // We could check here if the grid is supported by its fleet, // or more generally if it's violation any rules // But we should notify players, b/c that could be confusing /* if (!ge.SupportedByFleet) { log("Grid " + grid.DisplayName + " is unsupported by its fleet, skipping.", "getRoundWinner"); continue; } */ // Is its Hull Classifier broadcasting far enough? HullClassifier classifier = ge.Classifier; if (classifier == null) { log("Grid has no classifier but was classified", "nearbySubfleets", Logger.severity.ERROR); continue; } InGame.IMyBeacon beacon = classifier.FatBlock as InGame.IMyBeacon; if (beacon == null) { log("Classifier could not be referenced as beacon", "nearbySubfleets", Logger.severity.ERROR); continue; } if (!beacon.IsWorking) { log("Classifier beacon not working but grid was classified", "nearbySubfleets", Logger.severity.ERROR); continue; } if (beacon.Radius < VRageMath.Vector3.Distance(Position, grid.GetPosition())) { log("Classifier range too small, skipping", "nearbySubfleets"); // TODO notify pilot continue; } // Grid passed all tests! long fleetID = ge.Owner.FleetID; log("Grid '" + ge.Grid.DisplayName + "'passed all tests, including in fleet " + fleetID, "nearbySubfleets"); if (!foundSubfleets.ContainsKey(fleetID)) { foundSubfleets[fleetID] = new Subfleet { ID = fleetID, Enforcers = new List<GridEnforcer>() { ge }, TotalValue = ge.CaptureMultiplier, }; } else { foundSubfleets[fleetID].Enforcers.Add(ge); foundSubfleets[fleetID].TotalValue += ge.CaptureMultiplier; } } return foundSubfleets; }