Skip to content

Commit 11c84d2

Browse files
81ninjaAlexandre Oliveira
authored andcommitted
Fix asteroid issues in 1.3
* Detect scenario DiscoverableObjects changed name in 1.3 * Shorten iterations over Vessel lists when counting asteroids * Compatibility with the new Sentinel mechanic in 1.3 * Set new asteroids lifetime = infinity
1 parent 99bca17 commit 11c84d2

File tree

2 files changed

+92
-102
lines changed

2 files changed

+92
-102
lines changed

Client/AsteroidWorker.cs

Lines changed: 90 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
using System;
21
using System.Collections.Generic;
32
using UnityEngine;
3+
using SentinelMission;
44

55
namespace DarkMultiPlayer
66
{
@@ -11,8 +11,9 @@ public class AsteroidWorker
1111
public bool workerEnabled;
1212
//private state variables
1313
private float lastAsteroidCheck;
14-
private const float ASTEROID_CHECK_INTERVAL = 5f;
15-
ScenarioDiscoverableObjects scenarioController;
14+
private const float ASTEROID_CHECK_INTERVAL = 60f; // 1 minute
15+
private ScenarioDiscoverableObjects scenario;
16+
private bool initialized;
1617
private List<string> serverAsteroids = new List<string>();
1718
private Dictionary<string, string> serverAsteroidTrackStatus = new Dictionary<string, string>();
1819
private object serverAsteroidListLock = new object();
@@ -29,81 +30,98 @@ public AsteroidWorker(DMPGame dmpGame, LockSystem lockSystem, NetworkWorker netw
2930
this.networkWorker = networkWorker;
3031
this.vesselWorker = vesselWorker;
3132
this.dmpGame.updateEvent.Add(Update);
32-
GameEvents.onGameSceneLoadRequested.Add(OnGameSceneLoadRequested);
3333
GameEvents.onVesselCreate.Add(OnVesselCreate);
3434
}
3535

36+
public void InitializeScenario()
37+
{
38+
foreach (ProtoScenarioModule psm in HighLogic.CurrentGame.scenarios)
39+
{
40+
if (psm != null && scenario == null && psm.moduleName.Contains("Discoverable"))
41+
{
42+
scenario = (ScenarioDiscoverableObjects)psm.moduleRef; // this is borked as of 1.3.0; maybe they'll fix it in the future?
43+
}
44+
}
45+
if (scenario != null) scenario.spawnInterval = float.MaxValue;
46+
47+
// Disable the new Sentinel mechanic in KSP 1.3.0
48+
SentinelUtilities.SpawnChance = 0f;
49+
50+
initialized = true;
51+
}
52+
53+
public IEnumerable<Vessel> SpawnAsteroids(int quantity = 1)
54+
{
55+
System.Random random = new System.Random();
56+
while (quantity-- > 0)
57+
{
58+
yield return SpawnAsteroid(random).vesselRef;
59+
}
60+
yield break;
61+
}
62+
63+
public ProtoVessel SpawnAsteroid(System.Random random)
64+
{
65+
double baseDays = 21 + random.NextDouble() * 360;
66+
Orbit orbit = Orbit.CreateRandomOrbitFlyBy(Planetarium.fetch.Home, baseDays);
67+
68+
ProtoVessel pv = DiscoverableObjectsUtil.SpawnAsteroid(
69+
DiscoverableObjectsUtil.GenerateAsteroidName(),
70+
orbit,
71+
(uint)SentinelUtilities.RandomRange(random),
72+
SentinelUtilities.WeightedAsteroidClass(random),
73+
double.PositiveInfinity, double.PositiveInfinity);
74+
return pv;
75+
}
76+
3677
private void Update()
3778
{
38-
if (workerEnabled)
79+
if (!workerEnabled) return;
80+
if (Client.realtimeSinceStartup - lastAsteroidCheck < ASTEROID_CHECK_INTERVAL) return;
81+
else lastAsteroidCheck = Client.realtimeSinceStartup;
82+
if (!initialized) InitializeScenario();
83+
84+
//Try to acquire the asteroid-spawning lock if nobody else has it.
85+
if (!lockSystem.LockExists("asteroid-spawning"))
3986
{
40-
if (scenarioController == null)
87+
lockSystem.AcquireLock("asteroid-spawning", false);
88+
}
89+
90+
//We have the spawn lock, lets do stuff.
91+
if (lockSystem.LockIsOurs("asteroid-spawning"))
92+
{
93+
if ((HighLogic.CurrentGame.flightState.protoVessels != null) && (FlightGlobals.fetch.vessels != null))
4194
{
42-
foreach (ProtoScenarioModule psm in HighLogic.CurrentGame.scenarios)
95+
if ((HighLogic.CurrentGame.flightState.protoVessels.Count == 0) || (FlightGlobals.fetch.vessels.Count > 0))
4396
{
44-
if (psm != null)
97+
int beforeSpawn = GetAsteroidCount();
98+
int asteroidsToSpawn = maxNumberOfUntrackedAsteroids - beforeSpawn;
99+
if (asteroidsToSpawn > 0)
45100
{
46-
if (psm.moduleName == "ScenarioDiscoverableObjects")
47-
{
48-
if (psm.moduleRef != null)
49-
{
50-
scenarioController = (ScenarioDiscoverableObjects)psm.moduleRef;
51-
scenarioController.spawnInterval = float.MaxValue;
52-
}
53-
}
101+
foreach (Vessel asty in SpawnAsteroids(1)) // spawn 1 every ASTEROID_CHECK_INTERVAL seconds
102+
DarkLog.Debug("Spawned asteroid " + asty.name + ", have " + (beforeSpawn) + ", need " + maxNumberOfUntrackedAsteroids);
54103
}
55104
}
56105
}
106+
}
57107

58-
if (scenarioController != null)
108+
//Check for changes to tracking
109+
foreach (Vessel asteroid in GetCurrentAsteroids())
110+
{
111+
if (asteroid.state != Vessel.State.DEAD)
59112
{
60-
if ((Client.realtimeSinceStartup - lastAsteroidCheck) > ASTEROID_CHECK_INTERVAL)
113+
if (!serverAsteroidTrackStatus.ContainsKey(asteroid.id.ToString()))
61114
{
62-
lastAsteroidCheck = Client.realtimeSinceStartup;
63-
//Try to acquire the asteroid-spawning lock if nobody else has it.
64-
if (!lockSystem.LockExists("asteroid-spawning"))
65-
{
66-
lockSystem.AcquireLock("asteroid-spawning", false);
67-
}
68-
69-
//We have the spawn lock, lets do stuff.
70-
if (lockSystem.LockIsOurs("asteroid-spawning"))
71-
{
72-
if ((HighLogic.CurrentGame.flightState.protoVessels != null) && (FlightGlobals.fetch.vessels != null))
73-
{
74-
if ((HighLogic.CurrentGame.flightState.protoVessels.Count == 0) || (FlightGlobals.fetch.vessels.Count > 0))
75-
{
76-
int beforeSpawn = GetAsteroidCount();
77-
int asteroidsToSpawn = maxNumberOfUntrackedAsteroids - beforeSpawn;
78-
for (int asteroidsSpawned = 0; asteroidsSpawned < asteroidsToSpawn; asteroidsSpawned++)
79-
{
80-
DarkLog.Debug("Spawning asteroid, have " + (beforeSpawn + asteroidsSpawned) + ", need " + maxNumberOfUntrackedAsteroids);
81-
scenarioController.SpawnAsteroid();
82-
}
83-
}
84-
}
85-
}
86-
87-
//Check for changes to tracking
88-
foreach (Vessel asteroid in GetCurrentAsteroids())
115+
serverAsteroidTrackStatus.Add(asteroid.id.ToString(), asteroid.DiscoveryInfo.trackingStatus.Value);
116+
}
117+
else
118+
{
119+
if (asteroid.DiscoveryInfo.trackingStatus.Value != serverAsteroidTrackStatus[asteroid.id.ToString()])
89120
{
90-
if (asteroid.state != Vessel.State.DEAD)
91-
{
92-
if (!serverAsteroidTrackStatus.ContainsKey(asteroid.id.ToString()))
93-
{
94-
serverAsteroidTrackStatus.Add(asteroid.id.ToString(), asteroid.DiscoveryInfo.trackingStatus.Value);
95-
}
96-
else
97-
{
98-
if (asteroid.DiscoveryInfo.trackingStatus.Value != serverAsteroidTrackStatus[asteroid.id.ToString()])
99-
{
100-
ProtoVessel pv = asteroid.BackupVessel();
101-
DarkLog.Debug("Sending changed asteroid, new state: " + asteroid.DiscoveryInfo.trackingStatus.Value + "!");
102-
serverAsteroidTrackStatus[asteroid.id.ToString()] = asteroid.DiscoveryInfo.trackingStatus.Value;
103-
networkWorker.SendVesselProtoMessage(pv, false, false);
104-
}
105-
}
106-
}
121+
ProtoVessel pv = asteroid.BackupVessel();
122+
DarkLog.Debug("Sending changed asteroid, new state: " + asteroid.DiscoveryInfo.trackingStatus.Value + "!");
123+
serverAsteroidTrackStatus[asteroid.id.ToString()] = asteroid.DiscoveryInfo.trackingStatus.Value;
124+
networkWorker.SendVesselProtoMessage(pv, false, false);
107125
}
108126
}
109127
}
@@ -181,17 +199,15 @@ public bool VesselIsAsteroid(Vessel checkVessel)
181199
/// <param name="checkVessel">The vessel to check</param>
182200
public bool VesselIsAsteroid(ProtoVessel checkVessel)
183201
{
184-
if (checkVessel != null)
185-
{
186-
if (checkVessel.protoPartSnapshots != null ? (checkVessel.protoPartSnapshots.Count == 1) : false)
187-
{
188-
if (checkVessel.protoPartSnapshots[0].partName == "PotatoRoid")
189-
{
190-
return true;
191-
}
192-
}
193-
}
194-
return false;
202+
// Short circuit evaluation = faster
203+
if (
204+
checkVessel != null
205+
&& checkVessel.protoPartSnapshots != null
206+
&& checkVessel.protoPartSnapshots.Count == 1
207+
&& checkVessel.protoPartSnapshots[0].partName == "PotatoRoid")
208+
return true;
209+
else
210+
return false;
195211
}
196212

197213
private Vessel[] GetCurrentAsteroids()
@@ -209,25 +225,7 @@ private Vessel[] GetCurrentAsteroids()
209225

210226
private int GetAsteroidCount()
211227
{
212-
List<string> seenAsteroids = new List<string>();
213-
foreach (Vessel checkAsteroid in GetCurrentAsteroids())
214-
{
215-
if (!seenAsteroids.Contains(checkAsteroid.id.ToString()))
216-
{
217-
seenAsteroids.Add(checkAsteroid.id.ToString());
218-
}
219-
}
220-
foreach (ProtoVessel checkAsteroid in HighLogic.CurrentGame.flightState.protoVessels)
221-
{
222-
if (VesselIsAsteroid(checkAsteroid))
223-
{
224-
if (!seenAsteroids.Contains(checkAsteroid.vesselID.ToString()))
225-
{
226-
seenAsteroids.Add(checkAsteroid.vesselID.ToString());
227-
}
228-
}
229-
}
230-
return seenAsteroids.Count;
228+
return GetCurrentAsteroids().Length;
231229
}
232230

233231
/// <summary>
@@ -250,16 +248,9 @@ public void RegisterServerAsteroid(string asteroidID)
250248
}
251249
}
252250

253-
private void OnGameSceneLoadRequested(GameScenes scene)
254-
{
255-
//Force the worker to find the scenario module again.
256-
scenarioController = null;
257-
}
258-
259251
public void Stop()
260252
{
261253
dmpGame.updateEvent.Remove(Update);
262-
GameEvents.onGameSceneLoadRequested.Remove(OnGameSceneLoadRequested);
263254
GameEvents.onVesselCreate.Remove(OnVesselCreate);
264255
}
265256
}

Client/ScenarioWorker.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ private void OnContractAccepted(Contract contract)
5858
if (contractNode.GetValue("type") == "RecoverAsset")
5959
{
6060
string kerbalName = contractNode.GetValue("kerbalName").Trim();
61-
int kerbalGender = int.Parse(contractNode.GetValue("gender"));
6261
uint partID = uint.Parse(contractNode.GetValue("partID"));
6362

6463
if (!string.IsNullOrEmpty(kerbalName))
@@ -67,7 +66,7 @@ private void OnContractAccepted(Contract contract)
6766
if (!HighLogic.CurrentGame.CrewRoster.Exists(kerbalName))
6867
{
6968
DarkLog.Debug("Generating missing kerbal " + kerbalName + " for rescue contract");
70-
69+
int kerbalGender = int.Parse(contractNode.GetValue("gender"));
7170
rescueKerbal = HighLogic.CurrentGame.CrewRoster.GetNewKerbal(ProtoCrewMember.KerbalType.Unowned);
7271
rescueKerbal.ChangeName(kerbalName);
7372
rescueKerbal.gender = (ProtoCrewMember.Gender)kerbalGender;
@@ -160,7 +159,7 @@ private bool IsScenarioModuleAllowed(string scenarioName)
160159
return false;
161160
}
162161
//Blacklist asteroid module from every game mode
163-
if (scenarioName == "ScenarioDiscoverableObjects")
162+
if (scenarioName == "DiscoverableObjects")
164163
{
165164
//We hijack this and enable / disable it if we need to.
166165
return false;

0 commit comments

Comments
 (0)