internal void Update() { if (!RemoteControl.IsControlledByFaction("GCORP")) { // V26 if (!bLostProcessed) { // first time processing bLostProcessed = true; // TODO: maybe do something else. // maybe turn OFF all turrets // explode all warheads? // if base is 'lost' increase heat level heatSystem.BaseCaptured(); // ?play audio (from mabel?) announcing base captured. } return; // Maybe remove from list of bases? } // TODO: get this value from base itself instead of hard-coding? var player = DuckUtils.GetNearestPlayerToPosition(RemoteControl.GetPosition(), 1300); // turn turrets off on bases if no player is nearby to save simspeed hits if (player != null) { foreach (var turret in turrets) { turret.Enabled = true; } } else { foreach (var turret in turrets) { turret.Enabled = false; } } int nPlayers = 0; // number of players in range var playerClose1 = DuckUtils.GetNearestPlayerToPosition(RemoteControl.GetPosition(), 1200, out nPlayers); if (!DebugStopBackupGroups && playerClose1 != null) { if (lastBackupRespondTime + BackupTimeDelay < MyAPIGateway.Session.GameDateTime) { // ModLog.Info("Heat Difficulty: " + heatSystem.HeatDifficulty); // TODO: if player is INSIDE base, then do something else? // V26: If player is underground, then do something else? var players = new List <IMyPlayer>(); MyAPIGateway.Players.GetPlayers(players); foreach (var aplayer in players) { // check each player var controlled = aplayer.Controller.ControlledEntity; if (controlled == null) { continue; } var distSq = Vector3D.DistanceSquared(RemoteControl.GetPosition(), controlled.Entity.GetPosition()); if (distSq < 100 * 100) //V29 { if (DuckUtils.IsPlayerUnderCover(aplayer)) { // player is under cover 'near' the base.. } } else if (distSq < 1000 * 1000) { // betwee 100->1000 if (DuckUtils.IsPlayerUnderground(aplayer)) { // player is underground if (heatSystem.HeatDifficulty > 1) { // only if difficulty is above default // ModLog.Info("Spawning Bomber"); SpawnUndergroundDefense(aplayer); // on top of player // if we do this, then ground has lost integrity.. make it into an air base if (RemoteControl.CustomName.Contains("GROUND")) { RemoteControl.CustomName.Replace("GROUND", "AIR"); } } } } } // ModLog.Info("Backup Player Close 1"); SpawnHelperPatrol(playerClose1); // if higher difficulty and player(s) get closer, then spawn more backup per backup event if (heatSystem.HeatDifficulty > 1 || (heatSystem.MultiplayerScaling && nPlayers > 1)) { var playerClose2 = DuckUtils.GetNearestPlayerToPosition(RemoteControl.GetPosition(), 800); if (playerClose2 != null) { SpawnHelperPatrol(playerClose2); // ModLog.Info("Backup Player Close 2"); } } if (heatSystem.HeatDifficulty > 3 || (heatSystem.MultiplayerScaling && nPlayers > 3)) { var playerClose3 = DuckUtils.GetNearestPlayerToPosition(RemoteControl.GetPosition(), 300); if (playerClose3 != null) { SpawnHelperPatrol(playerClose3); // ModLog.Info("Backup Player Close 4"); } } lastBackupRespondTime = MyAPIGateway.Session.GameDateTime; audioSystem.PlayAudio(AudioClip.FacilityDetectedHostile, AudioClip.GCorpFacilityThreatened); waitingOnBackup = true; } } }
internal override void Update() { if (!leader.IsControlledByFaction("GCORP")) { leader = null; GroupState = NpcGroupState.Disbanded; return; } // ModLog.Info("Backup:" + leader.EntityId.ToString() + " " + GroupState.ToString()); if ((GroupState == NpcGroupState.Travelling || GroupState == NpcGroupState.ReturningForRepairs) && Vector3D.DistanceSquared(Destination, leader.GetPosition()) < 40.0 * 40.0) { // it arrives at destination. and nothing... get rid of it. // ModLog.Info(" Backup arrived at base/target and nothing found. Disbanding"); GroupState = NpcGroupState.Disbanding; } if (GroupState == NpcGroupState.Disbanding) { var isArmed = leader.HasUsableGun(); if (AttemptDespawn(leader, 200)) //V26 { leader = null; GroupState = NpcGroupState.Disbanded; if (isArmed) { ArrivalObserver.GroupArrivedIntact(); } } return; } if (DuckUtils.IsAnyPlayerNearPosition(leader.GetPosition(), 2000) && //V29 1000->2000 Backups were getting disbanded when player between 1000 and max spawn distance. (GroupState == NpcGroupState.Travelling || GroupState == NpcGroupState.Disbanding)) { GroupState = NpcGroupState.InCombat; // ModLog.Info("Backup:" + leader.EntityId.ToString() + " Found Target:" + GroupState.ToString()); leader.SetLightingColors(Color.Red); leader.RemoveFromFirstBeaconName(ReturningToBase); leader.AppendToFirstBeaconName(InterceptingBeaconSuffix); audioSystem.PlayAudio(AudioClip.TargetFoundDronesAttack, AudioClip.TargetIdentifiedUnitsConverge); } // todo: if no player nearby go searching for player vehicles near base/convoy // todo: if can't target player after a delay (or player under cover?), search for player vehicles near current location if (GroupState == NpcGroupState.InCombat) { if (!leader.HasUsableGun()) { // GroupState = NpcGroupState.Disbanding; GroupState = NpcGroupState.ReturningForRepairs; //V29 // ModLog.Info("Backup:" + leader.EntityId.ToString() + " No Gun." + GroupState.ToString()); leader.SetLightingColors(GcorpBlue); leader.RemoveFromFirstBeaconName(" Investigating Backup Call"); // match text in NpcGroupManager leader.RemoveFromFirstBeaconName(InterceptingBeaconSuffix); leader.AppendToFirstBeaconName(ReturningToBase); leader.SendToPosition(Destination); audioSystem.PlayAudio(AudioClip.DroneDisarmed); // disbanding, but for backups we want to extra penalize for killing unit heat.BackupDisabled(); } else { var player = DuckUtils.GetNearestPlayerToPosition(leader.GetPosition(), 2000); //V29 1250->2000 if (player == null) { GroupState = NpcGroupState.Disbanding; // Return to normal, cowardly players have run off or died // ModLog.Info("Backup:" + leader.EntityId.ToString() + " No Players in range after Combat mode." + GroupState.ToString()); leader.SetLightingColors(GcorpBlue); leader.RemoveFromFirstBeaconName(InterceptingBeaconSuffix); leader.AppendToFirstBeaconName(ReturningToBase); leader.SendToPosition(Destination); audioSystem.PlayAudio(AudioClip.HostileDisappeared, AudioClip.TargetFleeingPursuit); } else { float heightModifier = 15; // Change from 2 pre V26 // Added V26 if (DuckUtils.IsPlayerUnderCover(player)) { heightModifier = 300; } leader.SendToPosition(player.GetPosition(), heightModifier); } } } }
private void MessageEntered(string msg, ref bool visible) { if (msg.Equals("/efm", StringComparison.InvariantCultureIgnoreCase)) { MyAPIGateway.Utilities.ShowMessage("EFM", "Valid Commands \n/efm heat\n/efm difficulty #"); visible = false; return; } if (!msg.StartsWith("/efm", StringComparison.InvariantCultureIgnoreCase)) { return; } visible = false; string[] args = msg.Split(' '); if (args.Length <= 1) { MyAPIGateway.Utilities.ShowMessage("EFM", "Valid Commands \n/efm heat\n/efm difficulty #\n/efm scale [true|false]"); return; } if (args[1].ToLower() == "heat") { if (args.Length > 2) { int iParam = 0; bool bOk = int.TryParse(args[2], out iParam); if (bOk && iParam >= 0) { heatSystem.HeatLevel += iParam; } } string sHeat = "EFM\n Heat=" + heatSystem.HeatLevel.ToString() + "\n Difficulty=" + heatSystem.HeatDifficulty.ToString() + "\n MultiplayerScaling=" + heatSystem.MultiplayerScaling.ToString() ; MyVisualScriptLogicProvider.SendChatMessage(sHeat, "Wicorel", 0, MyFontEnum.DarkBlue); } if (args[1].ToLower() == "difficulty") { if (args.Length < 3) { MyVisualScriptLogicProvider.SendChatMessage("syntax: /efm difficulty #", "Wicorel", 0, MyFontEnum.DarkBlue); visible = true; return; } int iParam = 0; bool bOk = int.TryParse(args[2], out iParam); if (bOk && iParam >= 0) { heatSystem.HeatDifficulty = iParam; MyVisualScriptLogicProvider.SendChatMessage("Difficulty set to " + heatSystem.HeatDifficulty.ToString(), "Wicorel", 0, MyFontEnum.DarkBlue); if (heatSystem.HeatDifficulty > 3) { GCorpBase.SetFastBackupDelay(); } else { GCorpBase.SetNormalBackupDelay(); } } else { MyVisualScriptLogicProvider.SendChatMessage("syntax: /efm difficulty #", "Wicorel", 0, MyFontEnum.DarkBlue); } } if (args[1].ToLower() == "scale") { if (args.Length < 3) { MyVisualScriptLogicProvider.SendChatMessage("syntax: /efm scale [true|false]", "Wicorel", 0, MyFontEnum.DarkBlue); visible = true; return; } bool bParam = false; bool bOk = bool.TryParse(args[2], out bParam); if (bOk) { heatSystem.MultiplayerScaling = bParam; MyVisualScriptLogicProvider.SendChatMessage("MultiplayerScaling set to " + heatSystem.MultiplayerScaling.ToString(), "Wicorel", 0, MyFontEnum.DarkBlue); } else { MyVisualScriptLogicProvider.SendChatMessage("syntax: /efm scale [true|false]", "Wicorel", 0, MyFontEnum.DarkBlue); } } if (args[1].ToLower() == "convoy") { string sMsg = npcGroupManager.NpcGroupInfo(NpcGroupType.Convoy); MyVisualScriptLogicProvider.SendChatMessage(sMsg, "Wicorel", 0, MyFontEnum.DarkBlue); } if (args[1].ToLower() == "backup") { string sMsg = npcGroupManager.NpcGroupInfo(NpcGroupType.Backup); MyVisualScriptLogicProvider.SendChatMessage(sMsg, "Wicorel", 0, MyFontEnum.DarkBlue); } if (args[1].ToLower() == "base") { string sMsg = baseManager.BaseInfo(); MyVisualScriptLogicProvider.SendChatMessage(sMsg, "Wicorel", 0, MyFontEnum.DarkBlue); } if (args[1].ToLower() == "players") { var players = new List <IMyPlayer>(); MyAPIGateway.Players.GetPlayers(players); string sMsg = "#Players=" + players.Count; MyVisualScriptLogicProvider.SendChatMessage(sMsg, "Wicorel", 0, MyFontEnum.DarkBlue); foreach (var player in players) { sMsg = " " + player.DisplayName; var ident = player.Identity; //ident.IdentityId; var chara = player.Character; if (chara != null) { bool bUnderCover = DuckUtils.IsPlayerUnderCover(player); if (bUnderCover) { sMsg += " IS under cover\n"; } bool bIsUnderground = DuckUtils.IsPlayerUnderground(player); if (bIsUnderground) { sMsg += " IS underground\n"; } float health = chara.Integrity; bool isDead = chara.IsDead; float EnergyLevel = chara.SuitEnergyLevel; float physicalMass = chara.CurrentMass; bool thrustEnabled = chara.EnabledThrusts; float hLevel = chara.GetSuitGasFillLevel(hydrogenDefId); float o2Level = chara.GetSuitGasFillLevel(oxygenDefId); sMsg += " H=" + health.ToString("0.00") + " E=" + EnergyLevel.ToString("0.00"); sMsg += "\n Mass=" + physicalMass.ToString("0.00") + " Thrust=" + thrustEnabled.ToString(); sMsg += "\n H=" + hLevel.ToString("0.00") + " O2=" + o2Level.ToString("0.00"); } else { sMsg += " No character loaded yet"; } MyVisualScriptLogicProvider.SendChatMessage(sMsg, "Wicorel", 0, MyFontEnum.DarkBlue); } } }