gardenbase.c 21 KB

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