gardenbase.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
  1. class GardenBase extends ItemBase //BuildingSuper
  2. {
  3. // Paths to slot textures. Slots can have multiple states, so multiple textures must be generated
  4. static const string SLOT_TEXTURE_DIGGED_WET_LIME = "dz\\gear\\cultivation\\data\\soil_digged_wet_lime_CO.paa";
  5. static const string SLOT_TEXTURE_DIGGED_WET_PLANT = "dz\\gear\\cultivation\\data\\soil_digged_wet_plant_CO.paa";
  6. // Wet/dry material
  7. static const string SLOT_MATERIAL_WET = "dz\\gear\\cultivation\\data\\soil_cultivated_wet.rvmat";
  8. static const string SLOT_MATERIAL_DRY = "dz\\gear\\cultivation\\data\\soil_cultivated.rvmat";
  9. static const string SLOT_MATERIAL_LIMED_WET = "dz\\gear\\cultivation\\data\\soil_cultivated_limed_wet.rvmat";
  10. static const string SLOT_MATERIAL_LIMED_DRY = "dz\\gear\\cultivation\\data\\soil_cultivated_limed.rvmat";
  11. static const string SLOT_MATERIAL_COMPOST_WET = "dz\\gear\\cultivation\\data\\soil_cultivated_compost_wet.rvmat";
  12. static const string SLOT_MATERIAL_COMPOST_DRY = "dz\\gear\\cultivation\\data\\soil_cultivated_compost.rvmat";
  13. // slot names -> MUST BE LOWERCASE
  14. private static const string SLOT_SELECTION_DIGGED_PREFIX = "seedbase_";
  15. private static const string SLOT_SELECTION_COVERED_PREFIX = "slotCovered_";
  16. private static const string SLOT_MEMORY_POINT_PREFIX = "slot_";
  17. private static const string SLOT_SEEDBASE_PREFIX = "seedbase_";
  18. private static const int CHECK_RAIN_INTERVAL = 15;
  19. protected ref array<ref Slot> m_Slots;
  20. protected int m_SlotFertilityState = 0; //Used to store fertility state of all slots
  21. protected int m_SlotWateredState = 0; //Used to store fertility state of all slots
  22. protected int m_MaxWateredStateVal = 0; //Used to store fertility state of all slots
  23. protected float m_DefaultFertility = 1;
  24. ref Timer m_CheckRainTimer;
  25. private static ref map<string,string> m_map_slots; // For the 'attachment slot -> plant slot' conversion. It is possible that this will be removed later.
  26. void GardenBase()
  27. {
  28. RegisterNetSyncVariableInt("m_SlotFertilityState");
  29. RegisterNetSyncVariableInt("m_SlotWateredState");
  30. m_map_slots = new map<string,string>;
  31. SetEventMask(EntityEvent.INIT); // Enable EOnInit event
  32. // Prepare m_map_slots
  33. for (int i = 1; i <= GetGardenSlotsCount() ; ++i)
  34. {
  35. // m_map_slots is supposed to be: <input, output>
  36. string input = SLOT_SEEDBASE_PREFIX + i.ToString();
  37. string output = SLOT_MEMORY_POINT_PREFIX;
  38. if (i < 10)
  39. output = output + "0"; // Example: '1' changes to '01'
  40. output = output + i.ToString();
  41. m_map_slots.Set(input, output);
  42. }
  43. if ( GetGame().IsServer() )
  44. {
  45. CheckRainStart();
  46. }
  47. InitializeSlots();
  48. SetMaxWaterStateVal();
  49. }
  50. override void OnVariablesSynchronized()
  51. {
  52. super.OnVariablesSynchronized();
  53. SyncSlots();
  54. }
  55. override bool HasProxyParts()
  56. {
  57. return true;
  58. }
  59. override int GetHideIconMask()
  60. {
  61. return EInventoryIconVisibility.HIDE_VICINITY;
  62. }
  63. void SetBaseFertility(float value)
  64. {
  65. m_DefaultFertility = value;
  66. }
  67. float GetBaseFertility()
  68. {
  69. return m_DefaultFertility;
  70. }
  71. override void EOnInit(IEntity other, int extra)
  72. {
  73. CheckRainTick();
  74. UpdateTexturesOnAllSlots();
  75. }
  76. void InitializeSlots()
  77. {
  78. m_Slots = new array<ref Slot>;
  79. int slots_count = GetGardenSlotsCount();
  80. for ( int i = 0; i < slots_count; i++ )
  81. {
  82. Slot slot = new Slot(GetBaseFertility());
  83. slot.SetSlotIndex(i);
  84. int i1 = i + 1;
  85. string name = "SeedBase_" + i1;
  86. int slot_id = InventorySlots.GetSlotIdFromString(name);
  87. slot.SetSlotId(slot_id);
  88. slot.SetGarden(this);
  89. slot.m_State = Slot.STATE_DIGGED;
  90. slot.SetWateredState(eWateredState.DRY);
  91. slot.SetWater(0.0);
  92. m_Slots.Insert( slot );
  93. }
  94. }
  95. void SetMaxWaterStateVal()
  96. {
  97. int state = 0;
  98. for ( int i = 0; i < m_Slots.Count(); i++ )
  99. {
  100. state += 1 * Math.Pow( 2, i );
  101. }
  102. m_MaxWateredStateVal = state;
  103. }
  104. int GetMaxWaterStateVal()
  105. {
  106. return m_MaxWateredStateVal;
  107. }
  108. void UpdateTexturesOnAllSlots()
  109. {
  110. int slots_count = GetGardenSlotsCount();
  111. for ( int i = 0; i < slots_count; i++ )
  112. {
  113. UpdateSlotTexture(i);
  114. }
  115. }
  116. override bool OnStoreLoad( ParamsReadContext ctx, int version )
  117. {
  118. if ( version <= 118 )
  119. return true;
  120. if ( !super.OnStoreLoad( ctx, version ) )
  121. return false;
  122. if ( version < 102 )
  123. {
  124. float some_value;
  125. ctx.Read( some_value ); // compatibility check
  126. }
  127. int slots_count = GetGardenSlotsCount();
  128. for ( int i = 0; i < slots_count; i++ )
  129. {
  130. Slot slot = m_Slots.Get( i );
  131. if ( !slot.OnStoreLoadCustom( ctx, version ) )
  132. return false;
  133. }
  134. if ( version >= 119 )
  135. ctx.Read( m_SlotFertilityState );
  136. if ( version >= 120 )
  137. ctx.Read( m_SlotWateredState );
  138. return true;
  139. }
  140. override void AfterStoreLoad()
  141. {
  142. super.AfterStoreLoad();
  143. }
  144. override void EEOnAfterLoad()
  145. {
  146. GetGame().GetCallQueue( CALL_CATEGORY_GAMEPLAY ).CallLater( SyncSlots, 500, false, this );
  147. super.EEOnAfterLoad();
  148. }
  149. void SyncSlots()
  150. {
  151. for ( int i = 0; i < GetGardenSlotsCount(); i++ )
  152. {
  153. UpdateSlotTexture( i );
  154. }
  155. if ( GetGame().IsServer() )
  156. {
  157. SetSynchDirty();
  158. }
  159. }
  160. override void OnStoreSave( ParamsWriteContext ctx )
  161. {
  162. super.OnStoreSave( ctx );
  163. int slots_count = GetGardenSlotsCount();
  164. for ( int i = 0; i < slots_count; i++ )
  165. {
  166. Slot slot = m_Slots.Get( i );
  167. slot.OnStoreSaveCustom( ctx );
  168. }
  169. ctx.Write(m_SlotFertilityState);
  170. ctx.Write( m_SlotWateredState );
  171. }
  172. void PrintSlots()
  173. {
  174. Debug.Log("PRINT ALL SLOTS FROM...");
  175. Debug.Log("" + this);
  176. int slots = GetInventory().GetAttachmentSlotsCount();
  177. Debug.Log("Nb Slots : " + slots);
  178. for ( int i = 0; i < slots ; i++ )
  179. {
  180. Slot slot = m_Slots.Get(i);
  181. Debug.Log("i : " + i);
  182. Debug.Log("Slot : " + slot);
  183. float slot_fertility = slot.GetFertility();
  184. float slot_fertility_usage = slot.GetFertilityMax();
  185. string slot_fertility_type = slot.GetFertilityType();
  186. float slot_water = slot.GetWater();
  187. float slot_water_usage = slot.GetWaterUsage();
  188. ItemBase slot_seed = slot.GetSeed();
  189. ItemBase slot_plant = slot.GetPlant();
  190. float slot_state= slot.GetState();
  191. float slot_slot_Index = slot.GetSlotIndex();
  192. float slot_slot_ID = slot.GetSlotId();
  193. int slot_wateredState = slot.GetWateredState();
  194. int slot_FertilityState = slot.GetFertilityState();
  195. Debug.Log("Fertility : " + slot_fertility);
  196. Debug.Log("Fertility Usage : " + slot_fertility_usage);
  197. Debug.Log("Fertility Type : " + slot_fertility_type);
  198. Debug.Log("Fertility State : " + slot_FertilityState);
  199. Debug.Log("Water : " + slot_water);
  200. Debug.Log("Water Usage : " + slot_water_usage);
  201. Debug.Log("Watered State : " + slot_wateredState);
  202. Debug.Log("Seed : " + slot_seed);
  203. Debug.Log("Plant : " + slot_plant);
  204. Debug.Log("State : " + slot_state);
  205. Debug.Log("Slot Index : " + slot_slot_Index);
  206. Debug.Log("Slot ID : " + slot_slot_ID);
  207. Debug.Log("///////////////////////////");
  208. }
  209. Debug.Log("END OF ALL SLOTS FOR...");
  210. Debug.Log("" + this);
  211. }
  212. override bool CanPutInCargo( EntityAI parent )
  213. {
  214. if ( !super.CanPutInCargo(parent) ) {return false;}
  215. return false;
  216. }
  217. override bool CanPutIntoHands( EntityAI parent )
  218. {
  219. if ( !super.CanPutIntoHands( parent ) )
  220. {
  221. return false;
  222. }
  223. return false;
  224. }
  225. override bool CanRemoveFromHands( EntityAI parent )
  226. {
  227. return false;
  228. }
  229. int GetGardenSlotsCount()
  230. {
  231. return 0;
  232. }
  233. bool CanPlantSeed( string selection_component )
  234. {
  235. Slot slot = GetSlotBySelection( selection_component );
  236. if ( slot != NULL && slot.m_State == Slot.STATE_DIGGED )
  237. {
  238. return true;
  239. }
  240. else
  241. {
  242. return false;
  243. }
  244. }
  245. // Converts attachment slot name into plant slot name. Example: 'seedbase_1' -> 'component02'
  246. string ConvertAttSlotToPlantSlot(string attach_slot)
  247. {
  248. // Give result
  249. if ( m_map_slots.Contains(attach_slot) )
  250. {
  251. string return_value = m_map_slots.Get(attach_slot);
  252. return return_value;
  253. }
  254. return "";
  255. }
  256. override void EEItemAttached(EntityAI item, string slot_name)
  257. {
  258. super.EEItemAttached(item, slot_name);
  259. string path = string.Format("CfgVehicles %1 Horticulture PlantType", item.GetType());
  260. bool IsItemSeed = GetGame().ConfigIsExisting(path); // Is this item a seed?
  261. int slot_id = InventorySlots.GetSlotIdFromString(slot_name);
  262. if ( IsItemSeed )
  263. {
  264. string converted_slot_name;
  265. vector pos = GetPosition();
  266. int index = GetSlotIndexByAttachmentSlot( slot_name );
  267. if (index < 10)
  268. {
  269. converted_slot_name = SLOT_MEMORY_POINT_PREFIX + "0" + index.ToString();
  270. }
  271. else
  272. {
  273. converted_slot_name = SLOT_MEMORY_POINT_PREFIX + index.ToString();
  274. }
  275. PlantSeed( ItemBase.Cast( item ), converted_slot_name);
  276. }
  277. else if (g_Game.IsClient())
  278. {
  279. Slot slot = GetSlotByIndex(GetSlotIndexByAttachmentSlot( slot_name) - 1);
  280. if (slot)
  281. {
  282. slot.SetPlant(PlantBase.Cast( item ));
  283. slot.m_State = Slot.STATE_PLANTED;
  284. }
  285. }
  286. }
  287. override void EEItemDetached(EntityAI item, string slot_name)
  288. {
  289. super.EEItemDetached(item, slot_name);
  290. slot_name.ToLower();
  291. string path = string.Format("CfgVehicles %1 Horticulture PlantType", item.GetType());
  292. bool IsItemSeed = GetGame().ConfigIsExisting(path); // Is this item a seed?
  293. string converted_slot_name = ConvertAttSlotToPlantSlot(slot_name);
  294. Slot slot = GetSlotBySelection(converted_slot_name);
  295. if (slot)
  296. {
  297. if (IsItemSeed)
  298. {
  299. slot.SetSeed(NULL);
  300. }
  301. slot.SetState(Slot.STATE_DIGGED);
  302. }
  303. }
  304. // Plants the seed into slot (selection_component)
  305. void PlantSeed( ItemBase seed, string selection_component )
  306. {
  307. int slot_index = GetSlotIndexBySelection( selection_component );
  308. if ( slot_index != -1 )
  309. {
  310. PluginHorticulture module_horticulture = PluginHorticulture.Cast( GetPlugin( PluginHorticulture ) );
  311. string plant_type = module_horticulture.GetPlantType( seed );
  312. Slot slot = m_Slots.Get( slot_index );
  313. slot.SetState(Slot.STATE_PLANTED);
  314. slot.m_PlantType = plant_type;
  315. slot.SetSeed(seed);
  316. if ( !slot.NeedsWater() )
  317. {
  318. seed.LockToParent();
  319. //Take some small amount of time before making a plant out of seeds
  320. Timer growthTimer = NULL;
  321. growthTimer = new Timer( CALL_CATEGORY_SYSTEM );
  322. Param createPlantParam = new Param1<Slot>(slot);
  323. growthTimer.Run( 0.1, this, "CreatePlant", createPlantParam, false ); //Use a const for timer delay
  324. }
  325. }
  326. }
  327. // Creates a plant
  328. void CreatePlant(Slot slot )
  329. {
  330. if (g_Game.IsServer())
  331. {
  332. ItemBase seed = slot.GetSeed();
  333. seed.UnlockFromParent();
  334. GetGame().ObjectDelete(seed);
  335. PlantBase plant = PlantBase.Cast( GetInventory().CreateAttachmentEx( slot.m_PlantType, slot.GetSlotId()) );
  336. int slot_index = slot.GetSlotIndex();
  337. slot.SetPlant(plant);
  338. plant.Init( this, slot.GetFertility(), slot.m_HarvestingEfficiency, slot.GetWater() );
  339. //ShowSelection(SLOT_SELECTION_COVERED_PREFIX + (slot_index + 1).ToStringLen(2));
  340. plant.LockToParent();
  341. }
  342. }
  343. void Fertilize( PlayerBase player, ItemBase item, float consumed_quantity, string selection_component )
  344. {
  345. Slot slot = GetSlotBySelection( selection_component );
  346. if ( slot != NULL )
  347. {
  348. string item_type = item.GetType();
  349. if ( slot.GetFertilityType() == "" || slot.GetFertilityType() == item_type )
  350. {
  351. slot.SetFertilityType(item_type);
  352. float add_energy_to_slot = GetGame().ConfigGetFloat( string.Format("cfgVehicles %1 Horticulture AddEnergyToSlot", item_type) );
  353. slot.m_FertilizerUsage = GetGame().ConfigGetFloat( string.Format("cfgVehicles %1 Horticulture ConsumedQuantity", item_type) );
  354. float coef = Math.Clamp( consumed_quantity / slot.m_FertilizerUsage, 0.0, 1.0 );
  355. add_energy_to_slot = coef * add_energy_to_slot;
  356. slot.m_FertilizerQuantity += consumed_quantity;
  357. slot.m_Fertility += add_energy_to_slot;
  358. if ( slot.GetFertilizerQuantity() >= slot.GetFertilizerQuantityMax() )
  359. {
  360. int slot_index = slot.GetSlotIndex();
  361. if (slot_index > -1)
  362. {
  363. UpdateSlotTexture( slot_index );
  364. slot.SetFertilityState(eFertlityState.FERTILIZED);
  365. // Set relevant bit
  366. m_SlotFertilityState |= slot.GetFertilityState() << slot.GetSlotIndex();
  367. }
  368. }
  369. }
  370. else
  371. {
  372. slot.SetFertilizerQuantity(0);
  373. slot.SetFertilityType("");
  374. slot.SetFertilityState(eFertlityState.NONE);
  375. }
  376. SetSynchDirty();
  377. }
  378. }
  379. bool IsCorrectFertilizer( ItemBase item, string selection_component )
  380. {
  381. Slot slot = GetSlotBySelection( selection_component );
  382. if ( slot != NULL )
  383. {
  384. string item_type = item.GetType();
  385. if ( slot.GetFertilityType() == "" || slot.GetFertilityType() == item_type )
  386. {
  387. return true;
  388. }
  389. }
  390. return false;
  391. }
  392. bool NeedsFertilization( string selection_component )
  393. {
  394. Slot slot = GetSlotBySelection( selection_component );
  395. if ( slot )
  396. {
  397. if ( slot.GetFertilityState() == eFertlityState.NONE )
  398. {
  399. return true;
  400. }
  401. }
  402. return false;
  403. }
  404. void SlotWaterStateUpdate( Slot slot )
  405. {
  406. // Set relevant bit
  407. m_SlotWateredState |= slot.GetWateredState() << slot.GetSlotIndex();
  408. SetSynchDirty();
  409. }
  410. void UpdateSlotTexture( int slot_index )
  411. {
  412. Slot slot = m_Slots.Get( slot_index );
  413. // Show / Hide selections according to DIGGED or COVERED states.
  414. if ( slot.IsDigged() || slot.IsPlanted() )
  415. {
  416. string str_hide = SLOT_SELECTION_COVERED_PREFIX + (slot_index + 1).ToStringLen(2);
  417. string str_show = SLOT_SELECTION_DIGGED_PREFIX + (slot_index + 1).ToStringLen(1);
  418. HideSelection( str_hide );
  419. ShowSelection( str_show );
  420. }
  421. if ( slot.GetFertilityState() == eFertlityState.FERTILIZED && slot.GetFertilityType() != "" )
  422. {
  423. SetSlotTextureFertilized( slot_index, slot.GetFertilityType() );
  424. }
  425. else
  426. {
  427. SetSlotTextureDigged( slot_index );
  428. }
  429. }
  430. void SetSlotTextureDigged( int slot_index )
  431. {
  432. TStringArray textures = GetHiddenSelectionsTextures();
  433. string str_digged = SLOT_SELECTION_DIGGED_PREFIX + (slot_index + 1).ToStringLen(1);
  434. ShowSelection( str_digged );
  435. string texture = textures.Get(0);
  436. SetObjectTexture( slot_index, texture );
  437. Slot slot = m_Slots.Get( slot_index );
  438. if ( slot.GetWateredState() == 0 )
  439. {
  440. // Set dry material
  441. SetObjectMaterial( slot_index, SLOT_MATERIAL_DRY );
  442. }
  443. else
  444. {
  445. // Set wet material
  446. SetObjectMaterial( slot_index, SLOT_MATERIAL_WET );
  447. }
  448. }
  449. void SetSlotTextureFertilized( int slot_index, string item_type )
  450. {
  451. TStringArray textures = GetHiddenSelectionsTextures();
  452. int tex_id = GetGame().ConfigGetInt( string.Format("cfgVehicles %1 Horticulture TexId", item_type) );
  453. string str_show = SLOT_SELECTION_DIGGED_PREFIX + (slot_index + 1).ToStringLen(2);
  454. ShowSelection( str_show );
  455. SetObjectTexture( slot_index, textures.Get(tex_id) );
  456. Slot slot = m_Slots.Get( slot_index );
  457. int slot_index_offset = 0;
  458. // Set material according to dry / wet states
  459. if ( slot.GetWateredState() == 0 )
  460. {
  461. // Set dry material for garden lime
  462. if ( slot.GetFertilityType() == "GardenLime" )
  463. {
  464. SetObjectMaterial( slot_index + slot_index_offset, SLOT_MATERIAL_LIMED_DRY );
  465. }
  466. else if ( slot.GetFertilityType() == "PlantMaterial" )
  467. {
  468. SetObjectMaterial( slot_index + slot_index_offset, SLOT_MATERIAL_COMPOST_DRY );
  469. }
  470. }
  471. else
  472. {
  473. // Set dry material for compost
  474. if ( slot.GetFertilityType() == "GardenLime" )
  475. {
  476. SetObjectMaterial( slot_index + slot_index_offset, SLOT_MATERIAL_LIMED_WET );
  477. }
  478. else if ( slot.GetFertilityType() == "PlantMaterial" )
  479. {
  480. SetObjectMaterial( slot_index + slot_index_offset, SLOT_MATERIAL_COMPOST_WET );
  481. }
  482. }
  483. }
  484. void RemoveSlot( int index )
  485. {
  486. if ( m_Slots != NULL )
  487. {
  488. Slot slot = m_Slots.Get( index );
  489. PlantBase plant = slot.GetPlant();
  490. if ( plant )
  491. {
  492. plant.UnlockFromParent();
  493. plant.m_MarkForDeletion = true;
  494. GetGame().ObjectDelete( plant );
  495. }
  496. slot.Init( GetBaseFertility() );
  497. // Clear relevant bit
  498. slot.SetFertilityState(eFertlityState.NONE);
  499. m_SlotFertilityState &= ~(1 << slot.GetSlotIndex());
  500. slot.SetFertilityType(string.Empty);
  501. slot.SetFertilizerQuantity(0);
  502. slot.SetWateredState( eWateredState.DRY );
  503. m_SlotWateredState &= ~(1 << slot.GetSlotIndex());
  504. slot.SetWater(0);
  505. SetSynchDirty();
  506. HideSelection( SLOT_SELECTION_COVERED_PREFIX + (index + 1).ToStringLen(2) );
  507. UpdateSlotTexture( index );
  508. }
  509. }
  510. void RemoveSlotPlant( Object plant )
  511. {
  512. int index = GetSlotIndexByPlant( plant );
  513. if ( index >= 0 )
  514. {
  515. RemoveSlot( index );
  516. }
  517. }
  518. Slot GetSlotBySelection( string selection_component )
  519. {
  520. int slot_index = GetSlotIndexBySelection( selection_component );
  521. if ( slot_index > -1 )
  522. {
  523. return m_Slots.Get( slot_index );
  524. }
  525. else
  526. {
  527. return NULL;
  528. }
  529. }
  530. // Returns slot array index by selection, starting from 0 as the first one.
  531. int GetSlotIndexBySelection( string selection_component )
  532. {
  533. int slot_index = -1;
  534. if ( m_Slots != NULL )
  535. {
  536. string selection_component_lower = selection_component;
  537. selection_component_lower.ToLower();
  538. int start = selection_component_lower.IndexOf( SLOT_MEMORY_POINT_PREFIX );
  539. if ( start > -1 )
  540. {
  541. start += SLOT_MEMORY_POINT_PREFIX.Length();
  542. int end = start + 2;
  543. int length = selection_component.Length();
  544. if ( length >= end )
  545. {
  546. int length_add = length - end; // Hack-fix for inconsistent component names in p3d
  547. int length_from_end = 2 + length_add;
  548. string num_str = selection_component.Substring( start, length_from_end );
  549. slot_index = num_str.ToInt();
  550. slot_index = slot_index - 1;
  551. }
  552. }
  553. }
  554. return slot_index;
  555. }
  556. int GetSlotIndexByAttachmentSlot( string att_slot )
  557. {
  558. int slot_index = -1;
  559. int start = "SeedBase_".Length();
  560. int end = att_slot.Length();//start + 2;
  561. int len = end - start;
  562. string num_str = att_slot.Substring( start, len );
  563. slot_index = num_str.ToInt();
  564. return slot_index;
  565. }
  566. int GetSlotIndexByPlant( Object plant )
  567. {
  568. if ( m_Slots != NULL )
  569. {
  570. for ( int i = 0; i < m_Slots.Count(); i++ )
  571. {
  572. PlantBase found_plant = m_Slots.Get(i).GetPlant();
  573. if ( found_plant == plant )
  574. {
  575. return i;
  576. }
  577. }
  578. }
  579. return -1;
  580. }
  581. int GetNearestSlotIDByState( vector position, int slot_state)
  582. {
  583. float nearest_distance = 1000.0;
  584. int nearest_slot_index = -1;
  585. int slots_count = GetGardenSlotsCount();
  586. for ( int i = 0; i < slots_count; i++ )
  587. {
  588. Slot slot = m_Slots.Get(i); // Move this line by a scope higher in this function after debugging
  589. vector slot_pos = GetSlotPosition( i );
  590. float current_distance = vector.Distance( position, slot_pos );
  591. if ( current_distance < nearest_distance )
  592. {
  593. if ( slot != NULL && slot.m_State == slot_state )
  594. {
  595. nearest_distance = current_distance;
  596. nearest_slot_index = i;
  597. }
  598. }
  599. }
  600. return nearest_slot_index;
  601. }
  602. vector GetSlotPosition( int index )
  603. {
  604. string memory_point = SLOT_MEMORY_POINT_PREFIX + (index + 1).ToStringLen(2);
  605. vector pos = this.GetSelectionPositionMS( memory_point );
  606. return this.ModelToWorld( pos );
  607. }
  608. void CheckRainStart()
  609. {
  610. if ( !m_CheckRainTimer )
  611. m_CheckRainTimer = new Timer( CALL_CATEGORY_SYSTEM );
  612. m_CheckRainTimer.Run( CHECK_RAIN_INTERVAL, this, "CheckRainTick", NULL, true );
  613. }
  614. void CheckRainTick()
  615. {
  616. float rain_intensity = GetGame().GetWeather().GetRain().GetActual();
  617. float wetness = rain_intensity * 20 * CHECK_RAIN_INTERVAL;
  618. if (rain_intensity > 1 || rain_intensity < 0)
  619. wetness = 0; // hackfix for weird values returned by weather system
  620. if (wetness == 0)
  621. wetness = -0.1 * CHECK_RAIN_INTERVAL;
  622. int slots_count = GetGardenSlotsCount();
  623. if ( rain_intensity > 0 )
  624. {
  625. WaterAllSlots();
  626. SetSynchDirty();
  627. }
  628. for ( int i = 0; i < slots_count; i++ )
  629. {
  630. if ( m_Slots )
  631. {
  632. Slot slot = m_Slots.Get( i );
  633. if ( slot )
  634. {
  635. slot.GiveWater( wetness * Math.RandomFloat01() );
  636. }
  637. }
  638. }
  639. }
  640. //Used to update
  641. void WaterAllSlots()
  642. {
  643. int state = 0;
  644. for ( int i = 0; i < m_Slots.Count(); i++ )
  645. {
  646. state += 1 * Math.Pow( 2, i );
  647. }
  648. SetSlotWateredState( state );
  649. }
  650. array<ref Slot> GetSlots()
  651. {
  652. return m_Slots;
  653. }
  654. Slot GetSlotByIndex( int index )
  655. {
  656. return m_Slots.Get(index);
  657. }
  658. int GetSlotWateredState()
  659. {
  660. return m_SlotWateredState;
  661. }
  662. void SetSlotWateredState( int newState )
  663. {
  664. m_SlotWateredState = newState;
  665. }
  666. override void SetActions()
  667. {
  668. AddAction(ActionHarvestCrops);
  669. AddAction(ActionRemovePlant);
  670. AddAction(ActionRemoveSeed);
  671. }
  672. }