plantbase.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813
  1. enum EPlantState
  2. {
  3. PAUSED = 0,
  4. GROWING,
  5. MATURE,
  6. SPOILED,
  7. DRY
  8. }
  9. class PlantBase extends ItemBase
  10. {
  11. private float m_SprayUsage; // How much spray is needed to stop infestation of plant
  12. private float m_InfestationChance;
  13. private int m_GrowthStagesCount;
  14. private int m_CropsCount;
  15. private bool m_HasCrops;
  16. private string m_CropsType;
  17. private float m_PlantMaterialMultiplier;
  18. private int m_PlantStateIndex;
  19. private float m_CurrentPlantMaterialQuantity;
  20. protected EPlantState m_PlantState;
  21. private bool m_IsInfested;
  22. private float m_SprayQuantity;
  23. bool m_MarkForDeletion = false;
  24. int m_DeleteDryPlantTime; // For how long in seconds can an unwatered plant exist before it disappears
  25. int m_SpoiledRemoveTime; // For how long in seconds a spoiled plant will exist
  26. int m_FullMaturityTime; // How much time needs plant to be full grown in seconds
  27. int m_SpoilAfterFullMaturityTime; // How long in seconds it takes for plant to be spoiled after it is full grown
  28. float m_StateChangeTime; // For how long in seconds will plant stay in one state before its going to next state
  29. protected ref Timer m_TimeTicker;
  30. protected float m_TimeTracker;
  31. private GardenBase m_GardenBase = NULL;
  32. private ref Slot m_Slot = NULL;
  33. private PluginHorticulture m_ModuleHorticulture;
  34. private const float SPOIL_AFTER_MATURITY_TIME = 14400; //The time it takes for a fully grown plant to spoil, in seconds
  35. private const int TICK_FREQUENCY = 1; // seconds
  36. // debug
  37. static int m_DebugFullMaturityTime;
  38. static int m_DebugSpoilTime;
  39. static int m_DebugSpoilRemoveTime;
  40. static int m_DebugDeleteDryTime;
  41. static float m_DebugTickSpeedMultiplier = 1;
  42. void PlantBase()
  43. {
  44. m_ModuleHorticulture = PluginHorticulture.Cast( GetPlugin( PluginHorticulture ) );
  45. m_SprayUsage = 5;
  46. m_DeleteDryPlantTime = (60 * 10) + Math.RandomInt(0, 60 * 2);
  47. m_SpoiledRemoveTime = (60 * 20) + Math.RandomInt(0, 60 * 5);
  48. string plant_type = this.GetType();
  49. m_GrowthStagesCount = GetGame().ConfigGetInt( "cfgVehicles " + plant_type + " Horticulture GrowthStagesCount" );
  50. m_CropsCount = GetGame().ConfigGetInt( "cfgVehicles " + plant_type + " Horticulture CropsCount" );
  51. GetGame().ConfigGetText( "cfgVehicles " + plant_type + " Horticulture CropsType", m_CropsType );
  52. if (m_GrowthStagesCount == 0)
  53. m_GrowthStagesCount = 1;
  54. m_InfestationChance = 0.2 / m_GrowthStagesCount; //Must be between 0 and 1
  55. m_PlantStateIndex = -1;
  56. m_CurrentPlantMaterialQuantity = 0;
  57. m_IsInfested = false;
  58. m_SprayQuantity = 0.0;
  59. m_HasCrops = true;
  60. SetTakeable( false );
  61. RegisterNetSyncVariableBool("m_HasCrops");
  62. RegisterNetSyncVariableInt("m_PlantState");
  63. RegisterNetSyncVariableInt("m_PlantStateIndex");
  64. if (GetGame().IsServer())
  65. {
  66. m_TimeTicker = new Timer( CALL_CATEGORY_SYSTEM );
  67. m_TimeTicker.Run(TICK_FREQUENCY, this, "Tick", NULL, true);
  68. }
  69. }
  70. void ~PlantBase()
  71. {
  72. if (m_TimeTicker)
  73. m_TimeTicker.Stop();
  74. if (!m_MarkForDeletion)
  75. {
  76. DestroyPlant();
  77. }
  78. }
  79. void Init( GardenBase garden_base, float fertility, float harvesting_efficiency, float water )
  80. {
  81. m_GardenBase = garden_base;
  82. if (m_DebugFullMaturityTime != 0)
  83. m_FullMaturityTime = m_DebugFullMaturityTime;
  84. else
  85. m_FullMaturityTime += Math.RandomInt(-60,180);
  86. if (m_DebugSpoilTime != 0)
  87. m_SpoilAfterFullMaturityTime = m_DebugSpoilTime;
  88. else
  89. m_SpoilAfterFullMaturityTime = SPOIL_AFTER_MATURITY_TIME;
  90. if (m_DebugSpoilRemoveTime != 0)
  91. m_SpoiledRemoveTime = m_DebugSpoilRemoveTime;
  92. if (m_DebugDeleteDryTime != 0)
  93. m_DeleteDryPlantTime = m_DebugDeleteDryTime;
  94. m_StateChangeTime = m_FullMaturityTime / (m_GrowthStagesCount - 2);
  95. float count = m_CropsCount * fertility * harvesting_efficiency;
  96. m_CropsCount = (int)Math.Ceil( count );
  97. m_PlantMaterialMultiplier = 0.1 * harvesting_efficiency;
  98. float rain_intensity = GetGame().GetWeather().GetRain().GetActual();
  99. if (m_PlantState < EPlantState.MATURE && !NeedsWater())
  100. {
  101. SetPlantState(EPlantState.GROWING);
  102. GrowthTimerTick(); // first tick happens straight away
  103. }
  104. if (rain_intensity <= 0.0)
  105. {
  106. if (NeedsWater())
  107. SetPlantState(EPlantState.PAUSED);
  108. }
  109. }
  110. void Tick()
  111. {
  112. m_TimeTracker += m_TimeTicker.GetDuration() * m_DebugTickSpeedMultiplier;
  113. switch (m_PlantState)
  114. {
  115. case (EPlantState.GROWING):
  116. if (m_TimeTracker >= m_StateChangeTime)
  117. GrowthTimerTick();
  118. break;
  119. case (EPlantState.MATURE):
  120. if (m_TimeTracker >= m_SpoilAfterFullMaturityTime)
  121. SetSpoiled();
  122. break;
  123. case (EPlantState.SPOILED):
  124. if (m_TimeTracker >= m_SpoiledRemoveTime)
  125. RemoveSlot();
  126. break;
  127. case (EPlantState.DRY):
  128. if (m_TimeTracker >= m_DeleteDryPlantTime)
  129. RemoveSlot();
  130. break;
  131. }
  132. }
  133. override bool OnStoreLoad( ParamsReadContext ctx, int version )
  134. {
  135. if ( !super.OnStoreLoad( ctx, version ) )
  136. return false;
  137. GardenBase garden = GardenBase.Cast( GetHierarchyParent() );
  138. int slot_index = -1;
  139. ctx.Read( slot_index );
  140. Slot slot = garden.GetSlotByIndex(slot_index);
  141. SetSlot(slot);
  142. if ( !OnStoreLoadCustom( ctx, version ) )
  143. return false;
  144. return true;
  145. }
  146. override void OnStoreSave( ParamsWriteContext ctx )
  147. {
  148. super.OnStoreSave( ctx );
  149. Slot slot = GetSlot();
  150. if (slot)
  151. {
  152. int slot_index = slot.GetSlotIndex();
  153. slot.SetPlant(this); // hack
  154. ctx.Write( slot_index );
  155. OnStoreSaveCustom( ctx );
  156. }
  157. else
  158. {
  159. GetGame().ObjectDelete(this); // Plants that exist without a garden must be deleted. Otherwise they might cause problems.
  160. Print("Warning! A plant existed without a garden. Therefore it was deleted from the world to prevent issues!");
  161. }
  162. }
  163. string GetCropsType()
  164. {
  165. return m_CropsType;
  166. }
  167. bool OnStoreLoadCustom( ParamsReadContext ctx, int version )
  168. {
  169. int loadInt;
  170. if ( !ctx.Read( loadInt ) )
  171. loadInt = 0;
  172. m_SprayUsage = loadInt;
  173. loadInt = 0;
  174. if ( !ctx.Read( loadInt ) )
  175. loadInt = 5;
  176. m_DeleteDryPlantTime = loadInt;
  177. loadInt = 0;
  178. if ( !ctx.Read( loadInt ) )
  179. loadInt = 5;
  180. m_SpoiledRemoveTime = loadInt;
  181. loadInt = 0;
  182. if ( !ctx.Read( loadInt ) )
  183. loadInt = 300;
  184. m_FullMaturityTime = loadInt;
  185. loadInt = 0;
  186. if ( !ctx.Read( loadInt ) )
  187. loadInt = 300;
  188. m_SpoilAfterFullMaturityTime = loadInt;
  189. loadInt = 0;
  190. if ( !ctx.Read( loadInt ) )
  191. return false;
  192. m_StateChangeTime = loadInt;
  193. float loadFloat = 0.0;
  194. if ( !ctx.Read( loadFloat ) )
  195. loadFloat = 0;
  196. m_InfestationChance = loadFloat;
  197. loadInt = 0;
  198. if ( !ctx.Read( loadInt ) )
  199. return false;
  200. m_GrowthStagesCount = loadInt;
  201. loadInt = 0;
  202. if ( !ctx.Read( loadInt ) )
  203. loadInt = 1;
  204. m_CropsCount = loadInt;
  205. string loadString = "";
  206. if ( !ctx.Read( loadString ) )
  207. return false;
  208. m_CropsType = loadString;
  209. loadFloat = 0.0;
  210. if ( !ctx.Read( loadFloat ) )
  211. loadFloat = 1;
  212. m_PlantMaterialMultiplier = loadFloat;
  213. loadInt = 0;
  214. if ( !ctx.Read( loadInt ) )
  215. loadInt = 1;
  216. m_PlantState = loadInt;
  217. loadInt = 0;
  218. if ( !ctx.Read( loadInt ) )
  219. loadInt = 0;
  220. m_PlantStateIndex = loadInt;
  221. loadFloat = 0.0;
  222. if ( !ctx.Read( loadFloat ) )
  223. loadFloat = 1;
  224. m_CurrentPlantMaterialQuantity = loadFloat;
  225. bool loadBool = false;
  226. if ( !ctx.Read( loadBool ) )
  227. loadBool = false;
  228. m_IsInfested = loadBool;
  229. loadFloat = 0.0;
  230. if ( !ctx.Read( loadFloat ) )
  231. loadFloat = 0;
  232. m_SprayQuantity = loadFloat;
  233. loadBool = false;
  234. if ( ctx.Read( loadBool ) )
  235. {
  236. if ( loadBool )
  237. {}
  238. }
  239. else
  240. {
  241. return false;
  242. }
  243. loadFloat = 0.0;
  244. if ( ctx.Read( loadFloat ) )
  245. {
  246. if ( loadFloat > 0.0 )
  247. {}
  248. }
  249. else
  250. {
  251. return false;
  252. }
  253. loadFloat = 0.0;
  254. if ( ctx.Read( loadFloat ) )
  255. {
  256. if ( loadFloat > 0.0 )
  257. m_TimeTracker = loadFloat; // spoil
  258. }
  259. else
  260. {
  261. return false;
  262. }
  263. loadFloat = 0.0;
  264. if ( ctx.Read( loadFloat ) )
  265. {
  266. if ( loadFloat > 0.0 )
  267. m_TimeTracker = loadFloat; // spoil delete
  268. }
  269. else
  270. {
  271. return false;
  272. }
  273. loadFloat = 0.0;
  274. if ( ctx.Read( loadFloat ) )
  275. {
  276. if ( loadFloat > 0.0 )
  277. m_TimeTracker = loadFloat; // dry delete
  278. }
  279. else
  280. {
  281. return false;
  282. }
  283. UpdatePlant();
  284. return true;
  285. }
  286. void OnStoreSaveCustom( ParamsWriteContext ctx )
  287. {
  288. ctx.Write( m_SprayUsage );
  289. ctx.Write( m_DeleteDryPlantTime );
  290. ctx.Write( m_SpoiledRemoveTime );
  291. ctx.Write( m_FullMaturityTime );
  292. ctx.Write( m_SpoilAfterFullMaturityTime );
  293. ctx.Write( m_StateChangeTime );
  294. ctx.Write( m_InfestationChance );
  295. ctx.Write( m_GrowthStagesCount );
  296. ctx.Write( m_CropsCount );
  297. ctx.Write( m_CropsType );
  298. ctx.Write( m_PlantMaterialMultiplier );
  299. ctx.Write( m_PlantState );
  300. ctx.Write( m_PlantStateIndex );
  301. ctx.Write( m_CurrentPlantMaterialQuantity );
  302. ctx.Write( m_IsInfested );
  303. ctx.Write( m_SprayQuantity );
  304. bool saveBool = false; // deprec
  305. ctx.Write( saveBool );
  306. float saveFloat = 0.0; // deprec
  307. ctx.Write( saveFloat );
  308. saveFloat = 0.0;
  309. if (m_PlantState == EPlantState.MATURE)
  310. {
  311. saveFloat = m_TimeTracker;
  312. }
  313. ctx.Write( saveFloat );
  314. saveFloat = 0.0;
  315. if (m_PlantState == EPlantState.SPOILED)
  316. {
  317. saveFloat = m_TimeTracker;
  318. }
  319. ctx.Write( saveFloat );
  320. saveFloat = 0.0;
  321. if (m_PlantState == EPlantState.DRY)
  322. {
  323. saveFloat = m_TimeTracker;
  324. }
  325. ctx.Write( saveFloat );
  326. }
  327. void PrintValues()
  328. {
  329. Print("PRINT ALL VALUES OF PLANT...");
  330. Print(this);
  331. Print(m_HasCrops);
  332. Print(m_PlantState);
  333. Print(m_PlantStateIndex);
  334. Print(m_CurrentPlantMaterialQuantity);
  335. Print(m_IsInfested);
  336. Print(m_SprayQuantity);
  337. Print(m_Slot);
  338. Print(m_GardenBase);
  339. Print("----------------------------------------------------------");
  340. }
  341. override bool CanPutInCargo( EntityAI parent )
  342. {
  343. return super.CanPutInCargo(parent);
  344. }
  345. override bool CanPutIntoHands( EntityAI parent )
  346. {
  347. return super.CanPutIntoHands(parent);
  348. }
  349. override bool CanRemoveFromHands( EntityAI parent )
  350. {
  351. return false;
  352. }
  353. void ChangeInfestation( bool is_infested )
  354. {
  355. m_IsInfested = is_infested;
  356. string plant_type = GetType();
  357. PlantMaterialHealth material = m_ModuleHorticulture.GetPlantMaterial( plant_type );
  358. if ( m_IsInfested )
  359. {
  360. if ( material.m_InfestedTex != "" )
  361. {
  362. SetObjectTexture( 0, material.m_InfestedTex );
  363. }
  364. if ( material.m_InfestedMat != "" )
  365. {
  366. SetObjectMaterial( 0, material.m_InfestedMat );
  367. }
  368. }
  369. else
  370. {
  371. if ( material.m_HealthyTex != "" )
  372. {
  373. SetObjectTexture( 0, material.m_HealthyTex );
  374. }
  375. if ( material.m_HealthyMat != "" )
  376. {
  377. SetObjectMaterial( 0, material.m_HealthyMat );
  378. }
  379. }
  380. }
  381. void UpdatePlant()
  382. {
  383. if ( m_PlantStateIndex > 0 )
  384. {
  385. string plant_state_index = m_PlantStateIndex.ToStringLen(2);
  386. string prev_plant_state_index = ( m_PlantStateIndex - 1 ).ToStringLen( 2 );
  387. // HIDING PREVIOUS PLANT STATE AND SHOWING THE CURRENT ONE
  388. ShowSelection( "plantStage_" + plant_state_index ); // SHOW!
  389. HideSelection( "plantStage_" + prev_plant_state_index ); // HIDE!
  390. // HIDING PREVIOUS CROPS STATE AND SHOWING THE CURRENT ONE
  391. if ( HasCrops() )
  392. {
  393. ShowSelection( "plantStage_" + plant_state_index + "_crops" ); // SHOW!
  394. HideSelection( "plantStage_" + prev_plant_state_index + "_crops" ); // HIDE!
  395. }
  396. else
  397. {
  398. HideSelection( "plantStage_" + plant_state_index + "_crops" ); // HIDE!
  399. HideSelection( "plantStage_" + prev_plant_state_index + "_crops" ); // HIDE!
  400. }
  401. // HIDING PREVIOUS SHADOW STATE AND SHOWING THE CURRENT ONE
  402. ShowSelection( "plantStage_" + plant_state_index + "_shadow" ); // SHOW!
  403. HideSelection( "plantStage_" + prev_plant_state_index + "_shadow" ); // HIDE!
  404. }
  405. float float_plant_state_index = (float)m_PlantStateIndex;
  406. m_CurrentPlantMaterialQuantity = m_PlantMaterialMultiplier * float_plant_state_index;
  407. }
  408. void GrowthTimerTick()
  409. {
  410. m_TimeTracker = 0;
  411. if ( m_PlantStateIndex < m_GrowthStagesCount - 2 )
  412. {
  413. m_PlantStateIndex++;
  414. UpdatePlant();
  415. SetSynchDirty();
  416. float infestation_rnd = Math.RandomFloat01();
  417. if ( m_InfestationChance > infestation_rnd )
  418. ChangeInfestation(true);
  419. if ( m_PlantStateIndex == m_GrowthStagesCount - 2 )
  420. {
  421. if (m_IsInfested)
  422. SetDry();
  423. else
  424. SetPlantState(EPlantState.MATURE);
  425. }
  426. }
  427. }
  428. void SetSpoiled()
  429. {
  430. if (m_PlantState != EPlantState.SPOILED)
  431. {
  432. m_PlantStateIndex++;
  433. UpdatePlant();
  434. SetPlantState(EPlantState.SPOILED);
  435. }
  436. }
  437. void SetDry()
  438. {
  439. if (m_PlantState != EPlantState.DRY)
  440. {
  441. m_PlantStateIndex++;
  442. UpdatePlant();
  443. SetPlantState(EPlantState.DRY);
  444. }
  445. }
  446. //NEW METHOD FOR PLANT SPRAYING
  447. void SprayPlant( float consumed_quantity )
  448. {
  449. //Rework this to have something smooth
  450. m_SprayQuantity += consumed_quantity;
  451. if (m_SprayQuantity >= m_SprayUsage)
  452. {
  453. m_IsInfested = false;
  454. m_InfestationChance = 0;
  455. ChangeInfestation( false );
  456. UpdatePlant();
  457. }
  458. }
  459. //DEPRECATED
  460. string StopInfestation( float consumed_quantity )
  461. {
  462. m_SprayQuantity += consumed_quantity;
  463. if (m_SprayQuantity >= m_SprayUsage)
  464. {
  465. m_IsInfested = false;
  466. m_InfestationChance = 0;
  467. ChangeInfestation( false );
  468. UpdatePlant();
  469. return "I've sprayed the plant a bit. Now it is enough spayed.";
  470. }
  471. else
  472. {
  473. return "I've sprayed the plant a bit.";
  474. }
  475. }
  476. void RemovePlantEx( vector pos )
  477. {
  478. if ( GetGame() && GetGame().IsServer() )
  479. {
  480. UnlockFromParent();
  481. if ( m_CurrentPlantMaterialQuantity > 0.0 )
  482. {
  483. ItemBase item = ItemBase.Cast( GetGame().CreateObjectEx( "PlantMaterial", pos, ECE_PLACE_ON_SURFACE ) );
  484. item.SetQuantity( m_CurrentPlantMaterialQuantity * 1000.0 );
  485. }
  486. RemoveSlot();
  487. }
  488. }
  489. void DestroyPlant()
  490. {
  491. if ( GetGame() && GetGame().IsServer() )
  492. {
  493. UnlockFromParent();
  494. RemoveSlot();
  495. }
  496. }
  497. void Harvest( PlayerBase player )
  498. {
  499. if (IsHarvestable())
  500. {
  501. for ( int i = 0; i < m_CropsCount; i++ )
  502. {
  503. vector pos = player.GetPosition();
  504. ItemBase item = ItemBase.Cast( GetGame().CreateObjectEx( m_CropsType, pos, ECE_PLACE_ON_SURFACE ) );
  505. item.SetQuantity( item.GetQuantityMax() );
  506. }
  507. }
  508. m_HasCrops = false;
  509. SetSynchDirty();
  510. UpdatePlant();
  511. }
  512. void SetPlantState(int state)
  513. {
  514. m_PlantState = state;
  515. m_TimeTracker = 0;
  516. SetSynchDirty();
  517. }
  518. EPlantState GetPlantState()
  519. {
  520. return m_PlantState;
  521. }
  522. int GetPlantStateIndex()
  523. {
  524. return m_PlantStateIndex;
  525. }
  526. float GetWater()
  527. {
  528. if ( GetSlot() )
  529. return GetSlot().GetWater();
  530. return 0;
  531. }
  532. float GetWaterMax()
  533. {
  534. if ( GetSlot() )
  535. return GetSlot().GetWaterUsage();
  536. return 0;
  537. }
  538. bool NeedsWater()
  539. {
  540. Slot slotPlant = m_Slot;
  541. if ( m_PlantState == EPlantState.PAUSED && slotPlant && slotPlant.GetWater() < slotPlant.GetWaterUsage() )
  542. return true;
  543. return false;
  544. }
  545. float GetSprayQuantity()
  546. {
  547. return m_SprayQuantity;
  548. }
  549. float GetSprayUsage()
  550. {
  551. return m_SprayUsage;
  552. }
  553. void RemoveSlot()
  554. {
  555. GardenBase garden = GardenBase.Cast( GetHierarchyParent() );
  556. if ( garden )
  557. garden.RemoveSlotPlant( this );
  558. }
  559. void SetSlot(Slot slot)
  560. {
  561. if ( slot )
  562. {
  563. m_Slot = slot;
  564. }
  565. }
  566. Slot GetSlot()
  567. {
  568. return m_Slot;
  569. }
  570. GardenBase GetGarden()
  571. {
  572. return m_GardenBase;
  573. }
  574. bool IsSprayable()
  575. {
  576. if (m_PlantState == EPlantState.GROWING && m_SprayQuantity < m_SprayUsage)
  577. return true;
  578. return false;
  579. }
  580. bool IsHarvestable()
  581. {
  582. if (m_PlantState == EPlantState.MATURE && m_HasCrops)
  583. return true;
  584. return false;
  585. }
  586. bool HasCrops()
  587. {
  588. return m_HasCrops;
  589. }
  590. override void SetActions()
  591. {
  592. super.SetActions();
  593. AddAction(ActionHarvestCrops);
  594. AddAction(ActionRemovePlant);
  595. }
  596. void DebugSetTimes(int maturity, int spoil, int spoilRemove, int dryDelete)
  597. {
  598. if (maturity != 0)
  599. {
  600. m_FullMaturityTime = maturity;
  601. m_StateChangeTime = m_FullMaturityTime / (m_GrowthStagesCount - 2);
  602. }
  603. if (spoil != 0)
  604. m_SpoilAfterFullMaturityTime = spoil;
  605. if (spoilRemove != 0)
  606. m_SpoiledRemoveTime = spoilRemove;
  607. if (dryDelete != 0)
  608. m_DeleteDryPlantTime = dryDelete;
  609. }
  610. static void DebugSetGlobalTimes(int maturity, int spoil, int spoilRemove, int dryDelete)
  611. {
  612. m_DebugFullMaturityTime = maturity;
  613. m_DebugSpoilTime = spoil;
  614. m_DebugSpoilRemoveTime = spoilRemove;
  615. m_DebugDeleteDryTime = dryDelete;
  616. }
  617. static void DebugSetTickSpeedMultiplier(float multiplier)
  618. {
  619. m_DebugTickSpeedMultiplier = multiplier;
  620. }
  621. // DEPRECATED
  622. static const int STATE_DRY = 0;
  623. static const int STATE_GROWING = 1;
  624. static const int STATE_MATURE = 2;
  625. static const int STATE_SPOILED = 3;
  626. ref Timer m_SpoiledRemoveTimer;
  627. ref Timer m_DeleteDryPlantTimer;
  628. ref Timer m_SpoilAfterFullMaturityTimer;
  629. ref Timer m_GrowthTimer;
  630. ref Timer m_InfestationTimer;
  631. void DeleteDryPlantTick();
  632. void SpoiledRemoveTimerTick();
  633. void InfestationTimerTick();
  634. void CheckWater();
  635. bool IsMature();
  636. bool IsSpoiled();
  637. bool IsDry();
  638. bool IsGrowing();
  639. bool NeedsSpraying();
  640. void RemovePlant();
  641. }