public static List <GridEnforcer.GridData> deserialize(VRage.ByteStream stream) { List <GridEnforcer.GridData> result = new List <GridEnforcer.GridData>(); ushort count = stream.getUShort(); for (int i = 0; i < count; ++i) { GridEnforcer.GridData incomingData = GridEnforcer.deserialize(stream); result.Add(incomingData); } return(result); }
public void Close() { log("", "Close"); try { m_Fleet.remove(m_Class, m_Enforcer); StateTracker.getInstance().removeFleetIfEmpty(m_FleetID, m_OwnerType); } catch (NullReferenceException e) { log("Error: " + e, "Close", Logger.severity.ERROR); } m_Fleet = null; m_Enforcer = null; m_Logger = null; }
public GridOwner(GridEnforcer ge) { m_Enforcer = ge; m_Logger = new Logger(m_Enforcer.Grid.EntityId.ToString(), "GridOwner"); log("Loaded into new grid", "ctr"); // the grid will update ownership later b/c this is initialized with the grid, // and the grid doesn't have any blocks yet m_OwnerType = OWNER_TYPE.UNOWNED; m_FleetID = getFleetID(); m_Class = ge.Class; m_Fleet = getFleet(); m_Fleet.add(m_Class, ge); }
private void beforeMerge() { GridEnforcer ge = Grid.Components.Get <MyGameLogicComponent>() as GridEnforcer; if (ge != null) { log("Merge about to occur. Marking grid " + ge.Entity.EntityId.ToString(), "beforeMerge"); ge.markForMerge(); } else { log("GridEnforcer is null", "beforeMerge", Logger.severity.ERROR); } }
/// <summary> /// Increments the class count for a given class /// </summary> /// <param name="c">Class to increment</param> public void add(HullClass.CLASS c, GridEnforcer ge) { log("adding class " + ge.Class, "add", Logger.severity.TRACE); int classID = (int)ge.Class; //log("m_Counts[classID] is " + m_Counts[classID], "add", Logger.severity.TRACE); updateSupportAdded(ge); m_Counts[classID] += 1; m_TotalCount++; //log("m_Counts[classID] is " + m_Counts[classID], "add", Logger.severity.TRACE); //debugPrint("add"); }
/// <summary> /// Determines whether this fleet is allowed to support this class /// Alerts the grid and updates tracking /// Returns true if it was supported /// </summary> private bool updateSupportAdded(GridEnforcer ge) { HullClass.CLASS hc = ge.Class; uint c = (uint)hc; long eID = ge.Container.Entity.EntityId; //log("adding " + eID + " as " + c, "updateSupportAdded"); // if we have enough room, support it if (canSupportAnother(hc)) { log("we have enough room, supporting", "updateSupportAdded"); m_SupportedGrids[c][eID] = ge; ge.markSupported(m_FactionId); return(true); } // if we don't, see if it's bigger than one of the supported ones foreach (KeyValuePair <long, GridEnforcer> pair in m_SupportedGrids[c]) { GridEnforcer supported = pair.Value; // it is! if (ge.BlockCount > supported.BlockCount) { log("it's larger than one of our supported, supporting", "updateSupportAdded"); // remove support from the old supported one log("removing support from " + pair.Key, "updateSupportAdded"); m_SupportedGrids[c].Remove(pair.Key); m_UnsupportedGrids[c][pair.Key] = supported; supported.markUnsupported(m_FactionId); // add support to the new log("supporting " + eID, "updateSupportAdded"); m_SupportedGrids[c][eID] = ge; ge.markSupported(m_FactionId); return(true); } } // if not, mark as unsupported log("can't support, marking grid as unsupported", "updateSupportAdded"); m_UnsupportedGrids[c][eID] = ge; ge.markUnsupported(m_FactionId); return(false); }
/// <summary> /// Decrements the class count for a given class /// </summary> /// <param name="c">Class to decrement</param> public void remove(HullClass.CLASS c, GridEnforcer ge) { int classID = (int)c; if (m_Counts[classID] > 0) { m_Counts[classID] -= 1; m_TotalCount--; } else { log("Error: Decrementing class " + classID + " count, but already 0", "removeClass", Logger.severity.ERROR); } updateSupportRemoved(classID, ge); //debugPrint("remove"); }
/// <summary> /// Removes support from a grid given the class it was stored with /// </summary> private void updateSupportRemoved(int classID, GridEnforcer ge) { //log("start", "updateSupportRemoved", Logger.severity.TRACE); uint c = (uint)classID; long eID = ge.Container.Entity.EntityId; //log("checking where to remove it from", "updateSupportRemoved", Logger.severity.TRACE); if (m_SupportedGrids[c].ContainsKey(eID)) { m_SupportedGrids[c].Remove(eID); log(String.Format("Removing {0} from supported grids, count now {1}", eID, m_SupportedGrids[c].Count), "updateSupportRemoved", Logger.severity.TRACE); // See if there's an unsupported grid. If there's more than 1, select the // grid with the highest block count if (m_UnsupportedGrids[c].Count > 0) { int highestBlockCount = 0; long highestBlockCountID = 0; foreach (KeyValuePair <long, GridEnforcer> pair in m_UnsupportedGrids[c]) { long gridID = pair.Key; GridEnforcer grid = pair.Value; if (grid.BlockCount > highestBlockCount) { highestBlockCount = grid.BlockCount; highestBlockCountID = grid.Container.Entity.EntityId; } } m_SupportedGrids[c][highestBlockCountID] = m_UnsupportedGrids[c][highestBlockCountID]; m_SupportedGrids[c][highestBlockCountID].markSupported(m_FactionId); m_UnsupportedGrids[c].Remove(highestBlockCountID); } } else if (m_UnsupportedGrids[c].ContainsKey(eID)) { m_UnsupportedGrids[c].Remove(eID); log(String.Format("Removing {0} from unsupported grids, count now {1}", eID, m_UnsupportedGrids[c].Count), "updateSupportRemoved", Logger.severity.TRACE); } }
/// <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); }
public void eventCleanupTimerEnd(GridEnforcer ge, DerelictTimer.COMPLETION c) { //log("start", "eventCleanupTimerEnd", Logger.severity.TRACE); if (ge == null) { return; } //log("grid exists, getting owner", "eventCleanupTimerEnd", Logger.severity.TRACE); GridOwner owner = ge.Owner; //log("grid exists, getting owner type", "eventCleanupTimerEnd", Logger.severity.TRACE); GridOwner.OWNER_TYPE owner_type = owner.OwnerType; //log("grid exists, getting faction", "eventCleanupTimerEnd", Logger.severity.TRACE); long gridFactionID = ge.Owner.FactionID; //log("determining destinations", "eventCleanupTimerEnd", Logger.severity.TRACE); BaseResponse.DEST_TYPE destType = BaseResponse.DEST_TYPE.NONE; List <long> Destinations = new List <long>(); string message = ""; if (owner_type == GridOwner.OWNER_TYPE.FACTION) { destType = BaseResponse.DEST_TYPE.FACTION; Destinations.Add(gridFactionID); message += "Your faction's "; } else if (owner_type == GridOwner.OWNER_TYPE.PLAYER) { destType = BaseResponse.DEST_TYPE.PLAYER; Destinations.Add(ge.Owner.PlayerID); message += "Your "; } else { List <long> nearbyPlayers = ge.Grid.getPlayerIDsWithinPlacementRadius(); if (nearbyPlayers.Count > 0) { destType = BaseResponse.DEST_TYPE.PLAYER; Destinations = nearbyPlayers; message += "Nearby "; } else { return; } } log("building message", "eventCleanupTimerEnd", Logger.severity.TRACE); MyFontEnum font = MyFontEnum.Red; if (c == DerelictTimer.COMPLETION.CANCELLED) { message += "grid " + ge.Grid.DisplayName + " is now within limits."; font = MyFontEnum.Green; } else if (c == DerelictTimer.COMPLETION.ELAPSED) { message += "grid " + ge.Grid.DisplayName + " had some of its offending blocks removed."; font = MyFontEnum.Red; } log("Sending message", "eventDerelictEnd"); NotificationResponse noti = new NotificationResponse() { NotificationText = message, Time = Constants.NotificationMillis, Font = font, Destination = Destinations, DestType = destType }; m_MailMan.send(noti); }
public void eventCleanupTimerStart(GridEnforcer ge, int secondsRemaining) { if (ge == null) { return; } GridOwner owner = ge.Owner; GridOwner.OWNER_TYPE owner_type = owner.OwnerType; long gridFactionID = ge.Owner.FactionID; BaseResponse.DEST_TYPE destType = BaseResponse.DEST_TYPE.NONE; List <long> Destinations = new List <long>(); string message = ""; if (owner_type == GridOwner.OWNER_TYPE.FACTION) { destType = BaseResponse.DEST_TYPE.FACTION; Destinations.Add(gridFactionID); message += "Your faction's "; } else if (owner_type == GridOwner.OWNER_TYPE.PLAYER) { destType = BaseResponse.DEST_TYPE.PLAYER; Destinations.Add(ge.Owner.PlayerID); message += "Your "; } else { List <long> nearbyPlayers = ge.Grid.getPlayerIDsWithinPlacementRadius(); if (nearbyPlayers.Count > 0) { destType = BaseResponse.DEST_TYPE.PLAYER; Destinations = nearbyPlayers; message += "Nearby "; } else { return; } } log("msg details built", "eventCleanupTimerStart", Logger.severity.TRACE); // build notification message += "grid " + ge.Grid.DisplayName + " will have some of its offending blocks removed in " + Utility.prettySeconds(secondsRemaining); log("msg built, building noti", "eventDerelictStart"); NotificationResponse noti = new NotificationResponse() { NotificationText = message, Time = Constants.NotificationMillis, Font = MyFontEnum.Red, Destination = Destinations, DestType = destType }; log("notification built, sending message", "eventDerelictStart"); m_MailMan.send(noti); log("Msg sent", "eventDerelictStart"); }
public void eventCleanupViolation(GridEnforcer ge, List <GridEnforcer.VIOLATION> violations) { log("Start", "eventCleanupViolation"); if (ge == null) { return; } log("Determine destination", "eventCleanupViolation"); GridOwner owner = ge.Owner; GridOwner.OWNER_TYPE owner_type = owner.OwnerType; long gridFactionID = ge.Owner.FactionID; BaseResponse.DEST_TYPE destType = BaseResponse.DEST_TYPE.NONE; List <long> Destinations = new List <long>(); string message = ""; if (owner_type == GridOwner.OWNER_TYPE.FACTION) { destType = BaseResponse.DEST_TYPE.FACTION; Destinations.Add(gridFactionID); message += "Your faction's "; } else if (owner_type == GridOwner.OWNER_TYPE.PLAYER) { destType = BaseResponse.DEST_TYPE.PLAYER; Destinations.Add(ge.Owner.PlayerID); message += "Your "; } else { List <long> nearbyPlayers = ge.Grid.getPlayerIDsWithinPlacementRadius(); if (nearbyPlayers.Count > 0) { destType = BaseResponse.DEST_TYPE.PLAYER; Destinations = nearbyPlayers; message += "Nearby unowned "; } else { return; } } message += "grid '" + ge.Grid.DisplayName + "' "; log("Build violations message", "eventCleanupViolation"); if (violations != null) { message += "is violating: "; foreach (GridEnforcer.VIOLATION violation in violations) { message += violation.Name + ": " + violation.Count + "/" + violation.Limit + " "; } message += " and "; } log("Build time message", "eventCleanupViolation"); int secondsUntilCleanup = ge.TimeUntilCleanup; message += "will have some blocks removed in " + Utility.prettySeconds(secondsUntilCleanup); // send log("Sending message", "eventDerelictStart"); NotificationResponse noti = new NotificationResponse() { NotificationText = message, Time = Constants.NotificationMillis, Font = MyFontEnum.Red, Destination = Destinations, DestType = destType }; m_MailMan.send(noti); }
public void eventPlacementViolation(GridEnforcer ge, GridEnforcer.VIOLATION_TYPE v) { log("hit", "eventGridViolation"); // Check for players within the vicinity of the grid, since there's no // built-in way to tell who just placed the block List <long> players = ge.Grid.getPlayerIDsWithinPlacementRadius(); if (players.Count <= 0) { return; } string message = ""; if (v == GridEnforcer.VIOLATION_TYPE.TOTAL_BLOCKS) { message = "No more blocks allowed for this Class"; } else if (v == GridEnforcer.VIOLATION_TYPE.BLOCK_TYPE) { message = "No more blocks of this type allowed for this Class"; } else if (v == GridEnforcer.VIOLATION_TYPE.TOO_MANY_CLASSIFIERS) { message = "Only one Hull Classifier allowed"; } else if (v == GridEnforcer.VIOLATION_TYPE.SHOULD_BE_STATIC) { message = "This classifier is only allowed on Stations"; } else if (v == GridEnforcer.VIOLATION_TYPE.TOO_MANY_OF_CLASS) { // Hopefully the first person in the immediate vicinity is the // same ownertype as the person trying to place the block. // We could pass the owner of the block up with the violation, // but it would required more sophistication in the way we pass // violations in BlockAdded GridOwner.OWNER localOwner = GridOwner.ownerFromPlayerID(players[0]); GridOwner.OWNER_TYPE owner_type = localOwner.OwnerType; if (owner_type == GridOwner.OWNER_TYPE.UNOWNED) { message = "Take ownership of this grid or it will eventually be removed."; } else if (owner_type == GridOwner.OWNER_TYPE.PLAYER) { message = "No more ships of this class allowed in this player's fleet. " + "Try joining a faction."; } else if (owner_type == GridOwner.OWNER_TYPE.FACTION) { message = "No more ships of this class allowed in this faction's fleet. "; } } log("Sending message", "eventPlacementViolation"); NotificationResponse noti = new NotificationResponse() { NotificationText = message, Time = Constants.NotificationMillis, Font = MyFontEnum.Red, Destination = players, DestType = BaseResponse.DEST_TYPE.PLAYER }; m_MailMan.send(noti); }
/// <summary> /// Returns true if the support has changed /// </summary> /// <remarks> /// We should eventually call this every so often after adding blocks, /// perhaps before a GE Violations check, since competition for support is /// dependent on block count. Right now it's not called at all. /// </remarks> /// <param name="ge"></param> /// <returns></returns> public bool updateSupport(GridEnforcer ge) { uint c = (uint)ge.Class; long eID = ge.Container.Entity.EntityId; Dictionary <long, GridEnforcer> supportedGrids = m_SupportedGrids[c]; Dictionary <long, GridEnforcer> unsupportedGrids = m_UnsupportedGrids[c]; // if it's a supported if (supportedGrids.ContainsKey(eID)) { // if we're out of room and there's unsupported grids if ((m_Counts[c] > m_Maximums[c]) && unsupportedGrids.Count > 0) { // for any of the unsupported foreach (long unsupportedID in unsupportedGrids.Keys) { GridEnforcer unsupported = unsupportedGrids[unsupportedID]; // see it this is smaller if (ge.BlockCount < unsupported.BlockCount) { // change unsupported to supported unsupportedGrids.Remove(unsupportedID); supportedGrids[unsupportedID] = unsupported; unsupported.markSupported(m_FactionId); // change this to unsupported supportedGrids.Remove(eID); unsupportedGrids[eID] = ge; ge.markUnsupported(m_FactionId); return(true); } } // if it's a unsupported } else if (unsupportedGrids.ContainsKey(eID)) { // if we have enough room, support it if (m_Counts[c] < m_Maximums[c]) { unsupportedGrids.Remove(eID); supportedGrids[eID] = ge; ge.markSupported(m_FactionId); return(true); } // for any of the unsupported foreach (long supportedID in supportedGrids.Keys) { GridEnforcer supported = supportedGrids[supportedID]; // see if it's bigger if (ge.BlockCount > supported.BlockCount) { // remove support from the old supportedGrids.Remove(supportedID); unsupportedGrids[supportedID] = supported; supported.markUnsupported(m_FactionId); // add support to the existing unsupportedGrids.Remove(eID); supportedGrids[eID] = ge; ge.markSupported(m_FactionId); return(true); } } } } return(false); }