1- using System ;
21using System . Collections . Generic ;
32using UnityEngine ;
3+ using SentinelMission ;
44
55namespace 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 }
0 commit comments