Dayz Explorer 1.28.160049
Loading...
Searching...
No Matches
gardenbase.c
Go to the documentation of this file.
1class 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
7 // Wet/dry material
8 static const string SLOT_MATERIAL_WET = "dz\\gear\\cultivation\\data\\soil_cultivated_wet.rvmat";
9 static const string SLOT_MATERIAL_DRY = "dz\\gear\\cultivation\\data\\soil_cultivated.rvmat";
10
11 static const string SLOT_MATERIAL_LIMED_WET = "dz\\gear\\cultivation\\data\\soil_cultivated_limed_wet.rvmat";
12 static const string SLOT_MATERIAL_LIMED_DRY = "dz\\gear\\cultivation\\data\\soil_cultivated_limed.rvmat";
13 static const string SLOT_MATERIAL_COMPOST_WET = "dz\\gear\\cultivation\\data\\soil_cultivated_compost_wet.rvmat";
14 static const string SLOT_MATERIAL_COMPOST_DRY = "dz\\gear\\cultivation\\data\\soil_cultivated_compost.rvmat";
15
16 // slot names -> MUST BE LOWERCASE
17 private static const string SLOT_SELECTION_DIGGED_PREFIX = "seedbase_";
18 private static const string SLOT_SELECTION_COVERED_PREFIX = "slotCovered_";
19 private static const string SLOT_MEMORY_POINT_PREFIX = "slot_";
20 private static const string SLOT_SEEDBASE_PREFIX = "seedbase_";
21
22 private static const int CHECK_RAIN_INTERVAL = 15;
23 private static const float CREATE_PLANT_DELAY = 1000.0;
24 private static const float RAIN_INTENSITY_THRESHOLD = 0.05;
25
26 protected ref array<ref Slot> m_Slots;
27 protected int m_SlotFertilityState = 0; //Used to store fertility state of all slots
28 protected int m_SlotWateredState = 0; //Used to store watered state of all slots
29 protected int m_MaxWateredStateVal = 0; //Used to store water max state of all slots
30
31 protected int m_SlotState = 0; //Used to handle and sync slot states
32
33 protected int m_SlotWaterBitmap0; // Slots 1–4
34 protected int m_SlotWaterBitmap1; // Slots 5–8
35 protected int m_SlotWaterBitmap2; // Slot 9 (and could hold up to 3 more if needed)
36
37 protected int m_SlotFertilizerBitmap0; // Slots 1–4
38 protected int m_SlotFertilizerBitmap1; // Slots 5–8
39 protected int m_SlotFertilizerBitmap2; // Slot 9 (and could hold up to 3 more if needed)
40
41 protected float m_DefaultFertility = 1;
43
44 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.
45
46 void GardenBase()
47 {
48 RegisterNetSyncVariableInt("m_SlotState");
49 RegisterNetSyncVariableInt("m_SlotFertilityState");
50 RegisterNetSyncVariableInt("m_SlotWateredState");
51
52 RegisterNetSyncVariableInt("m_SlotWaterBitmap0");
53 RegisterNetSyncVariableInt("m_SlotWaterBitmap1");
54 RegisterNetSyncVariableInt("m_SlotWaterBitmap2");
55
56 RegisterNetSyncVariableInt("m_SlotFertilizerBitmap0");
57 RegisterNetSyncVariableInt("m_SlotFertilizerBitmap1");
58 RegisterNetSyncVariableInt("m_SlotFertilizerBitmap2");
59
60 m_map_slots = new map<string,string>;
61
62 SetEventMask(EntityEvent.INIT); // Enable EOnInit event
63
64 // Prepare m_map_slots
65 for (int i = 1; i <= GetGardenSlotsCount(); ++i)
66 {
67 // m_map_slots is supposed to be: <input, output>
68 string input = SLOT_SEEDBASE_PREFIX + i.ToString();
69 string output = SLOT_MEMORY_POINT_PREFIX;
70
71 if (i < 10)
72 output = output + "0"; // Example: '1' changes to '01'
73
74 output = output + i.ToString();
75
76 m_map_slots.Set(input, output);
77 }
78
79 InitializeSlots();
80 SetMaxWaterStateVal();
81
82 if (GetGame().IsServer())
83 {
84 CheckRainStart();
85 }
86 }
87
88 void ~GardenBase()
89 {
90 if (GetGame() && m_CheckRainTimer)
91 {
92 m_CheckRainTimer.Stop();
93 m_CheckRainTimer = null;
94 }
95 }
96
97 override void OnVariablesSynchronized()
98 {
99 super.OnVariablesSynchronized();
100
101 UpdateSlots();
102 }
103
104 void UpdateSlots()
105 {
106 if (!m_Slots || m_Slots.Count() == 0)
107 return;
108
110 int slotsCount = GetGardenSlotsCount();
111 for (int i = 0; i < slotsCount; i++)
112 {
113 Slot slot = m_Slots.Get(i);
114
115 // Read relevant bits and set the synced values on the slots
116 int fertilityState = (m_SlotFertilityState >> i) & 1;
117 slot.SetFertilityState(fertilityState);
118
119 int wateredState = (m_SlotWateredState >> i) & 1;
120 slot.SetWateredState(wateredState);
121
122 int waterQuantity = GetWaterQuantity(i);
123 slot.SetWater(waterQuantity);
124
125 int fertilizerQuantity = GetFertilizerQuantity(i);
126 slot.SetFertilizerQuantity(fertilizerQuantity);
127
128 int slotState = GetSlotState(i);
129 slot.SetState(slotState);
130 }
131 }
132
133 override bool HasProxyParts()
134 {
135 return true;
136 }
137
138 override int GetHideIconMask()
139 {
140 return EInventoryIconVisibility.HIDE_VICINITY;
141 }
142
143 void SetBaseFertility(float value)
144 {
145 m_DefaultFertility = value;
146 }
147
148 float GetBaseFertility()
149 {
150 return m_DefaultFertility;
151 }
152
153 override void EOnInit(IEntity other, int extra)
154 {
155 CheckRainTick();
156 }
157
158 void InitializeSlots()
159 {
160 m_Slots = new array<ref Slot>;
161 int slots_count = GetGardenSlotsCount();
162
163 for (int i = 0; i < slots_count; i++)
164 {
165 Slot slot = new Slot(GetBaseFertility());
166 slot.SetSlotIndex(i);
167 int i1 = i + 1;
168 string name = "SeedBase_" + i1;
169 int slotID = InventorySlots.GetSlotIdFromString(name);
170 slot.SetSlotId(slotID);
171 slot.SetGarden(this);
172 slot.SetState(eGardenSlotState.STATE_DIGGED);
173 m_Slots.Insert(slot);
174
175 SetWaterQuantity(i, 0);
176 SetFertilizerQuantity(i, 0);
177 }
178
179 UpdateSlots();
180 }
181
182 void SetMaxWaterStateVal()
183 {
184 int state = 0;
185
186 for ( int i = 0; i < m_Slots.Count(); i++ )
187 {
188 state += 1 * Math.Pow( 2, i );
189 }
190
191 m_MaxWateredStateVal = state;
192 }
193
194 int GetMaxWaterStateVal()
195 {
196 return m_MaxWateredStateVal;
197 }
198
199 override bool OnStoreLoad(ParamsReadContext ctx, int version)
200 {
201 if (version <= 118)
202 return true;
203
204 if (!super.OnStoreLoad(ctx, version))
205 return false;
206
207 if (version < 102)
208 {
209 float some_value;
210 ctx.Read(some_value); // compatibility check
211 }
212
213 int slots_count = GetGardenSlotsCount();
214 for (int i = 0; i < slots_count; i++)
215 {
216 Slot slot = m_Slots.Get(i);
217 if (!slot.OnStoreLoadCustom(ctx, version))
218 return false;
219
220 float waterQuantity = slot.GetWater();
221 SetWaterQuantity(i, waterQuantity);
222
223 float fertilizerQuantity = slot.GetFertilizerQuantity();
224 SetFertilizerQuantity(i, fertilizerQuantity);
225 }
226
227 if ( version >= 119 )
228 {
229 if(!ctx.Read( m_SlotFertilityState ))
230 return false;
231 }
232
233 if ( version >= 120 )
234 {
235 if (!ctx.Read( m_SlotWateredState ))
236 return false;
237 }
238
239 return true;
240 }
241
242 override void EEOnAfterLoad()
243 {
244 super.EEOnAfterLoad();
245
246 GetGame().GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(SyncSlots, 500, false, this);
247 }
248
249 void SyncSlots()
250 {
251 if (g_Game.IsServer() || !g_Game.IsMultiplayer())
252 {
253 UpdateSlots();
254
255 int slotsCount = GetGardenSlotsCount();
256 for (int i = 0; i < slotsCount; ++i)
257 {
258 UpdateSlotTexture(i);
259 }
260
261 if (g_Game.IsDedicatedServer())
262 SetSynchDirty();
263 }
264 }
265
266 override void OnStoreSave( ParamsWriteContext ctx )
267 {
268 super.OnStoreSave( ctx );
269
270 int slots_count = GetGardenSlotsCount();
271
272 for ( int i = 0; i < slots_count; i++ )
273 {
274 Slot slot = m_Slots.Get( i );
275
276 slot.OnStoreSaveCustom( ctx );
277 }
278
279 ctx.Write(m_SlotFertilityState);
280
281 ctx.Write( m_SlotWateredState );
282 }
283
284 void PrintSlots()
285 {
286 Debug.Log("PRINT ALL SLOTS FROM...");
287 Debug.Log("" + this + " | Position: " + GetPosition());
288 int slots = GetInventory().GetAttachmentSlotsCount();
289 Debug.Log("Nb Slots : " + slots);
290
291 for ( int i = 0; i < slots ; i++ )
292 {
293 Slot slot = m_Slots.Get(i);
294 Debug.Log("i : " + i);
295 Debug.Log("Slot : " + slot);
296
297 float slot_fertility = slot.GetFertility();
298 float slot_fertility_usage = slot.GetFertilityMax();
299 string slot_fertility_type = slot.GetFertilityType();
300 float slot_water = slot.GetWater();
301 float slot_water_usage = slot.GetWaterUsage();
302 ItemBase slot_seed = slot.GetSeed();
303 ItemBase slot_plant = slot.GetPlant();
304 float slot_state= slot.GetState();
305 float slot_slot_Index = slot.GetSlotIndex();
306 int slot_slot_ID = slot.GetSlotId();
307 int slot_wateredState = slot.GetWateredState();
308 int slot_FertilityState = slot.GetFertilityState();
309
310 Debug.Log("Fertility : " + slot_fertility);
311 Debug.Log("Fertility Usage : " + slot_fertility_usage);
312 Debug.Log("Fertility Type : " + slot_fertility_type);
313 Debug.Log("Fertility State : " + slot_FertilityState);
314 Debug.Log("Water : " + slot_water);
315 Debug.Log("Water Usage : " + slot_water_usage);
316 Debug.Log("Watered State : " + typename.EnumToString(eWateredState, slot_wateredState));
317 Debug.Log("Seed : " + slot_seed);
318 Debug.Log("Plant : " + slot_plant);
319 if (slot_plant && PlantBase.Cast(slot_plant))
320 PlantBase.Cast(slot_plant).PrintValues();
321 Debug.Log("State : " + slot_state);
322 Debug.Log("Slot Index : " + slot_slot_Index);
323 Debug.Log("Slot ID : " + slot_slot_ID);
324 Debug.Log("///////////////////////////");
325 }
326
327 Debug.Log("END OF ALL SLOTS FOR...");
328 Debug.Log("" + this);
329 }
330
331 override bool CanPutInCargo( EntityAI parent )
332 {
333 if ( !super.CanPutInCargo(parent) ) {return false;}
334 return false;
335 }
336
337 override bool CanPutIntoHands( EntityAI parent )
338 {
339 if ( !super.CanPutIntoHands( parent ) )
340 {
341 return false;
342 }
343 return false;
344 }
345
346 override bool CanRemoveFromHands( EntityAI parent )
347 {
348 return false;
349 }
350
351 int GetGardenSlotsCount()
352 {
353 return 0;
354 }
355
356 bool CanPlantSeed(string selection_component)
357 {
358 Slot slot = GetSlotBySelection(selection_component);
359 if (slot != NULL && slot.GetState() == eGardenSlotState.STATE_DIGGED)
360 {
361 return true;
362 }
363 else
364 {
365 return false;
366 }
367 }
368
369 // Converts attachment slot name into plant slot name. Example: 'seedbase_1' -> 'component02'
370 string ConvertAttSlotToPlantSlot(string attach_slot)
371 {
372 // Give result
373 if ( m_map_slots.Contains(attach_slot) )
374 {
375 string return_value = m_map_slots.Get(attach_slot);
376 return return_value;
377 }
378
379 return "";
380 }
381
382 override void EEItemAttached(EntityAI item, string slot_name)
383 {
384 super.EEItemAttached(item, slot_name);
385
386 string path = string.Format("CfgVehicles %1 Horticulture PlantType", item.GetType());
387 bool IsItemSeed = GetGame().ConfigIsExisting(path); // Is this item a seed?
388
389 if (IsItemSeed)
390 {
391 string converted_slot_name;
392
393 vector pos = GetPosition();
394 int index = GetSlotIndexByAttachmentSlot(slot_name);
395
396 if (index < 10)
397 {
398 converted_slot_name = SLOT_MEMORY_POINT_PREFIX + "0" + index.ToString();
399 }
400 else
401 {
402 converted_slot_name = SLOT_MEMORY_POINT_PREFIX + index.ToString();
403 }
404
405 if (g_Game.IsServer() || !g_Game.IsMultiplayer())
406 PlantSeed(ItemBase.Cast(item), converted_slot_name);
407 }
408 else if (g_Game.IsClient())
409 {
410 Slot slot = GetSlotByIndex(GetSlotIndexByAttachmentSlot(slot_name) - 1);
411 if (slot)
412 {
413 slot.SetPlant(PlantBase.Cast(item));
414 slot.SetState(eGardenSlotState.STATE_PLANTED);
415 }
416 }
417 }
418
419 override void EEItemDetached(EntityAI item, string slot_name)
420 {
421 super.EEItemDetached(item, slot_name);
422
423 slot_name.ToLower();
424
425 string path = string.Format("CfgVehicles %1 Horticulture PlantType", item.GetType());
426 bool IsItemSeed = GetGame().ConfigIsExisting(path); // Is this item a seed?
427
428 string converted_slot_name = ConvertAttSlotToPlantSlot(slot_name);
429 Slot slot = GetSlotBySelection(converted_slot_name);
430
431 if (slot)
432 {
433 if (IsItemSeed)
434 {
435 slot.SetSeed(NULL);
436 }
437
438 slot.SetState(eGardenSlotState.STATE_DIGGED);
439 }
440 }
441
442 // Plants the seed into slot (selection_component)
443 void PlantSeed( ItemBase seed, string selection_component )
444 {
445 int slot_index = GetSlotIndexBySelection( selection_component );
446
447 if ( slot_index != -1 )
448 {
449 PluginHorticulture module_horticulture = PluginHorticulture.Cast( GetPlugin( PluginHorticulture ) );
450 string plant_type = module_horticulture.GetPlantType( seed );
451
452 Slot slot = m_Slots.Get( slot_index );
453 slot.SetState(eGardenSlotState.STATE_PLANTED);
454 slot.m_PlantType = plant_type;
455 slot.SetSeed(seed);
456
457 if ( !slot.NeedsWater() || slot.GetWateredState() == eWateredState.WET)
458 {
460 if (slot.GetWateredState() == eWateredState.WET && slot.NeedsWater())
461 {
462 int waterMax = slot.GetWaterMax();
463 slot.SetWater(waterMax);
464 }
465
466 seed.LockToParent();
467 //Take some small amount of time before making a plant out of seeds
468 GetGame().GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(CreatePlant, CREATE_PLANT_DELAY, false, slot);
469 }
470 }
471 }
472
473 // Creates a plant
474 void CreatePlant(Slot slot)
475 {
476 if (g_Game.IsServer() || !g_Game.IsMultiplayer())
477 {
478 ItemBase seed = slot.GetSeed();
479 if (seed)
480 {
481 seed.UnlockFromParent();
482 GetGame().ObjectDelete(seed);
483
484 PlantBase plant = PlantBase.Cast( GetInventory().CreateAttachmentEx(slot.m_PlantType, slot.GetSlotId()));
485 int slot_index = slot.GetSlotIndex();
486 slot.SetPlant(plant);
487 slot.SetState(eGardenSlotState.STATE_PLANTED);
488 plant.Init(this, slot.GetFertility(), slot.m_HarvestingEfficiency, slot.GetWater());
489 plant.LockToParent();
490 }
491 }
492 }
493
494 void SetSlotState(int slotIndex, int value)
495 {
496 // value should be 1 or 2
497 int shift = slotIndex * 2;
498 int mask = 3 << shift;
499 int currentState = (m_SlotState & mask) >> shift;
500
501 // Clear out the bits for this slot
502 m_SlotState &= ~mask;
503
504 // Set the new value
505 m_SlotState |= (value << shift);
506
507 if (g_Game.IsServer() && currentState != value)
508 SetSynchDirty();
509 }
510
511 int GetSlotState(int slotIndex)
512 {
513 int shift = slotIndex * 2;
514 int mask = 3 << shift;
515 int value = (m_SlotState & mask) >> shift;
516 return value; // Will be 0, 1, or 2
517 }
518
519 void SlotWaterStateUpdate( Slot slot )
520 {
521 int idx = slot.GetSlotIndex();
522 int mask = 1 << idx;
523 int currentState = (m_SlotWateredState >> idx) & 1;
524 int newState = slot.GetWateredState();
525 // Clear the relevant bit first
526 m_SlotWateredState &= ~mask;
527
528 // Set the bit state (1 for WET, 0 for DRY)
529 m_SlotWateredState |= (newState << idx);
530
531 if ((g_Game.IsServer() || !g_Game.IsMultiplayer()) && currentState != newState)
532 {
533 UpdateSlotTexture(slot.GetSlotIndex());
534
535 if (g_Game.IsServer())
536 SetSynchDirty();
537 }
538 }
539
540 void SlotFertilityStateUpdate(Slot slot)
541 {
542 int idx = slot.GetSlotIndex();
543 int mask = 1 << idx;
544 int currentState = (m_SlotFertilityState >> idx) & 1;
545 int newState = slot.GetFertilityState();
546
547 // Clear the relevant bit first
548 m_SlotFertilityState &= ~mask;
549
550 // Set the bit state (1 for FERTILIZED, 0 for NONE)
551 m_SlotFertilityState |= (newState << idx);
552
553 if ((g_Game.IsServer() || !g_Game.IsMultiplayer()) && currentState != newState)
554 {
555 UpdateSlotTexture(slot.GetSlotIndex());
556
557 if (g_Game.IsServer())
558 SetSynchDirty();
559 }
560 }
561
563 void UpdateSlotTexture( int slot_index )
564 {
565 if (!m_Slots || m_Slots.Count() - 1 < slot_index)
566 return;
567
568 Slot slot = m_Slots.Get( slot_index );
569
570 // Show / Hide selections according to DIGGED or COVERED states.
571 if ( slot.IsDigged() || slot.IsPlanted() )
572 {
573 string str_hide = SLOT_SELECTION_COVERED_PREFIX + (slot_index + 1).ToStringLen(2);
574 string str_show = SLOT_SELECTION_DIGGED_PREFIX + (slot_index + 1).ToStringLen(1);
575
576 HideSelection( str_hide );
577 ShowSelection( str_show );
578 }
579
580 if ( slot.GetFertilityState() == eFertlityState.FERTILIZED && slot.GetFertilityType() != "" )
581 {
582 SetSlotTextureFertilized( slot_index, slot.GetFertilityType() );
583 }
584 else
585 {
586 SetSlotTextureDigged( slot_index );
587 }
588 }
589
590 void SetSlotTextureDigged( int slot_index )
591 {
592 TStringArray textures = GetHiddenSelectionsTextures();
593
594 string str_digged = SLOT_SELECTION_DIGGED_PREFIX + (slot_index + 1).ToStringLen(1);
595
596 ShowSelection( str_digged );
597 string texture = textures.Get(0);
598 SetObjectTexture( slot_index, texture );
599
600 Slot slot = m_Slots.Get( slot_index );
601
602 if ( slot.GetWateredState() == 0 )
603 {
604 // Set dry material
605 SetObjectMaterial( slot_index, SLOT_MATERIAL_DRY );
606 }
607 else
608 {
609 // Set wet material
610 SetObjectMaterial( slot_index, SLOT_MATERIAL_WET );
611 }
612 }
613
614 void SetSlotTextureFertilized( int slot_index, string item_type )
615 {
616 TStringArray textures = GetHiddenSelectionsTextures();
617
618 int tex_id = GetGame().ConfigGetInt( string.Format("cfgVehicles %1 Horticulture TexId", item_type) );
619
620 string str_show = SLOT_SELECTION_DIGGED_PREFIX + (slot_index + 1).ToStringLen(2);
621
622 ShowSelection( str_show );
623 SetObjectTexture( slot_index, textures.Get(tex_id) );
624
625 Slot slot = m_Slots.Get( slot_index );
626
627 int slot_index_offset = 0;
628
629 // Set material according to dry / wet states
630 if ( slot.GetWateredState() == 0 )
631 {
632 // Set dry material for garden lime
633 if ( slot.GetFertilityType() == "GardenLime" )
634 {
635 SetObjectMaterial( slot_index + slot_index_offset, SLOT_MATERIAL_LIMED_DRY );
636 }
637 else if ( slot.GetFertilityType() == "PlantMaterial" )
638 {
639 SetObjectMaterial( slot_index + slot_index_offset, SLOT_MATERIAL_COMPOST_DRY );
640 }
641 }
642 else
643 {
644 // Set dry material for compost
645 if ( slot.GetFertilityType() == "GardenLime" )
646 {
647 SetObjectMaterial( slot_index + slot_index_offset, SLOT_MATERIAL_LIMED_WET );
648 }
649 else if ( slot.GetFertilityType() == "PlantMaterial" )
650 {
651 SetObjectMaterial( slot_index + slot_index_offset, SLOT_MATERIAL_COMPOST_WET );
652 }
653 }
654 }
655
656 void RemoveSlot(int index)
657 {
658 if (m_Slots)
659 {
660 Slot slot = m_Slots.Get(index);
661 PlantBase plant = slot.GetPlant();
662
663 if (plant && !plant.IsPendingDeletion())
664 {
665 plant.UnlockFromParent();
666 plant.m_MarkForDeletion = true;
667 plant.Delete();
668 }
669
670 slot.Init(GetBaseFertility());
671
672 int idx = slot.GetSlotIndex();
673 int mask = 1 << idx;
674
675 // Clear the relevant bits from bitmaps
676 m_SlotFertilityState &= ~mask;
677 m_SlotWateredState &= ~mask;
678
679 // Reset states
680 m_SlotFertilityState |= (slot.GetFertilityState() << idx);
681 m_SlotWateredState |= (slot.GetWateredState() << idx);
682
683 // Reset stol quantities
684 SetWaterQuantity(index, 0);
685 SetFertilizerQuantity(index, 0);
686
687 UpdateSlots();
688
689 HideSelection(SLOT_SELECTION_COVERED_PREFIX + (index + 1).ToStringLen(2));
690 UpdateSlotTexture(idx);
691
692 SetSynchDirty();
693 }
694 }
695
696 void RemoveSlotPlant( Object plant )
697 {
698 int index = GetSlotIndexByPlant( plant );
699 if ( index >= 0 )
700 {
701 RemoveSlot( index );
702 }
703 }
704
705 Slot GetSlotBySelection( string selection_component )
706 {
707 int slot_index = GetSlotIndexBySelection( selection_component );
708
709 if ( slot_index > -1 )
710 {
711 return m_Slots.Get( slot_index );
712 }
713 else
714 {
715 return NULL;
716 }
717 }
718
719 // Returns slot array index by selection, starting from 0 as the first one.
720 int GetSlotIndexBySelection( string selection_component )
721 {
722 int slot_index = -1;
723
724 if ( m_Slots != NULL )
725 {
726 string selection_component_lower = selection_component;
727 selection_component_lower.ToLower();
728
729 int start = selection_component_lower.IndexOf( SLOT_MEMORY_POINT_PREFIX );
730
731 if ( start > -1 )
732 {
733 start += SLOT_MEMORY_POINT_PREFIX.Length();
734 int end = start + 2;
735 int length = selection_component.Length();
736
737 if ( length >= end )
738 {
739 int length_add = length - end; // Hack-fix for inconsistent component names in p3d
740 int length_from_end = 2 + length_add;
741 string num_str = selection_component.Substring( start, length_from_end );
742 slot_index = num_str.ToInt();
743
744 slot_index = slot_index - 1;
745 }
746 }
747 }
748
749 return slot_index;
750 }
751
752 int GetSlotIndexByAttachmentSlot( string att_slot )
753 {
754 int slot_index = -1;
755
756 int start = "SeedBase_".Length();
757 int end = att_slot.Length();//start + 2;
758 int len = end - start;
759
760 string num_str = att_slot.Substring( start, len );
761 slot_index = num_str.ToInt();
762
763 return slot_index;
764 }
765
766 int GetSlotIndexByPlant( Object plant )
767 {
768 if ( m_Slots != NULL )
769 {
770 for ( int i = 0; i < m_Slots.Count(); i++ )
771 {
772 PlantBase found_plant = m_Slots.Get(i).GetPlant();
773
774 if ( found_plant == plant )
775 {
776 return i;
777 }
778 }
779 }
780
781 return -1;
782 }
783
784 int GetNearestSlotIDByState(vector position, int slot_state)
785 {
786 float nearest_distance = 1000.0;
787 int nearest_slot_index = -1;
788 int slots_count = GetGardenSlotsCount();
789 for (int i = 0; i < slots_count; i++)
790 {
791 Slot slot = m_Slots.Get(i); // Move this line by a scope higher in this function after debugging
792 vector slot_pos = GetSlotPosition(i);
793 float current_distance = vector.Distance(position, slot_pos);
794
795 if (current_distance < nearest_distance)
796 {
797 if (slot != NULL && slot.GetState() == slot_state)
798 {
799 nearest_distance = current_distance;
800 nearest_slot_index = i;
801 }
802 }
803 }
804
805 return nearest_slot_index;
806 }
807
808 vector GetSlotPosition( int index )
809 {
810 string memory_point = SLOT_MEMORY_POINT_PREFIX + (index + 1).ToStringLen(2);
811 vector pos = this.GetSelectionPositionMS( memory_point );
812
813 return this.ModelToWorld( pos );
814 }
815
816 void CheckRainStart()
817 {
818 if ( !m_CheckRainTimer )
819 m_CheckRainTimer = new Timer( CALL_CATEGORY_SYSTEM );
820
821 m_CheckRainTimer.Run( CHECK_RAIN_INTERVAL, this, "CheckRainTick", NULL, true );
822 }
823
824 void CheckRainTick()
825 {
826 float rainIntensity = GetGame().GetWeather().GetRain().GetActual();
827 float wetness = rainIntensity * 20 * CHECK_RAIN_INTERVAL;
828
829 if (rainIntensity > 1 || rainIntensity < 0)
830 wetness = 0; // hackfix for weird values returned by weather system
831
832 if (wetness == 0)
833 wetness = -0.1 * CHECK_RAIN_INTERVAL;
834
835 // At the moment we dont want to remove water from the slot when it is not raining so we check and manipulate water quantity only when we add to it
836 if (rainIntensity > RAIN_INTENSITY_THRESHOLD)
837 {
838 if (wetness != 0) // only change slot water quantity when wetness value can actually add/deduct something
839 {
840 int slotsCount = GetGardenSlotsCount();
841 for (int i = 0; i < slotsCount; i++)
842 {
843 if (m_Slots)
844 {
845 Slot slot = m_Slots.Get(i);
846 if (slot)
847 {
848 slot.GiveWater(wetness * Math.RandomFloat01());
849 }
850 }
851 }
852 }
853 }
854 }
855
856 array<ref Slot> GetSlots()
857 {
858 return m_Slots;
859 }
860
861 Slot GetSlotByIndex( int index )
862 {
863 return m_Slots.Get(index);
864 }
865
866 override void SetActions()
867 {
871 }
872
873 void SetFertilizerBitmapByIndex(int index, int value)
874 {
875 switch (index)
876 {
877 case 0:
878 m_SlotFertilizerBitmap0 = value;
879 break;
880 case 1:
881 m_SlotFertilizerBitmap1 = value;
882 break;
883 case 2:
884 m_SlotFertilizerBitmap2 = value;
885 break;
886 }
887 }
888
889 int GetFertilizerBitmapByIndex(int index)
890 {
891 switch (index)
892 {
893 case 0:
894 return m_SlotFertilizerBitmap0;
895 case 1:
896 return m_SlotFertilizerBitmap1;
897 case 2:
898 return m_SlotFertilizerBitmap2;
899 }
900 return 0;
901 }
902
903 void SetWaterBitmapByIndex(int index, int value)
904 {
905 switch (index)
906 {
907 case 0:
908 m_SlotWaterBitmap0 = value;
909 break;
910 case 1:
911 m_SlotWaterBitmap1 = value;
912 break;
913 case 2:
914 m_SlotWaterBitmap2 = value;
915 break;
916 }
917 }
918
919 int GetWaterBitmapByIndex(int index)
920 {
921 switch (index)
922 {
923 case 0:
924 return m_SlotWaterBitmap0;
925 case 1:
926 return m_SlotWaterBitmap1;
927 case 2:
928 return m_SlotWaterBitmap2;
929 }
930 return 0;
931 }
932
933 void SetWaterQuantity(int slotIndex, int value)
934 {
935 int bitsPerSlot = 8;
936 int slotsPerInt = 32 / bitsPerSlot;
937
938 int groupIndex = slotIndex / slotsPerInt;
939 int bitOffset = (slotIndex % slotsPerInt) * bitsPerSlot;
940
941 int mask = 255 << bitOffset;
942 value = Math.Clamp(value, 0, 200);
943
944 int temp = GetWaterBitmapByIndex(groupIndex);
945 temp &= ~mask;
946 temp |= (value << bitOffset);
947 SetWaterBitmapByIndex(groupIndex, temp);
948 }
949
950 int GetWaterQuantity(int slotIndex)
951 {
952 int bitsPerSlot = 8;
953 int slotsPerInt = 32 / bitsPerSlot;
954
955 int groupIndex = slotIndex / slotsPerInt;
956 int bitOffset = (slotIndex % slotsPerInt) * bitsPerSlot;
957
958 int value = GetWaterBitmapByIndex(groupIndex);
959 return (value >> bitOffset) & 255;
960 }
961
962 void SetFertilizerQuantity(int slotIndex, int value)
963 {
964 int bitsPerSlot = 8;
965 int slotsPerInt = 32 / bitsPerSlot;
966
967 int groupIndex = slotIndex / slotsPerInt;
968 int bitOffset = (slotIndex % slotsPerInt) * bitsPerSlot;
969
970 int mask = 255 << bitOffset;
971 value = Math.Clamp(value, 0, 200);
972
973 int temp = GetFertilizerBitmapByIndex(groupIndex);
974 temp &= ~mask;
975 temp |= (value << bitOffset);
976 SetFertilizerBitmapByIndex(groupIndex, temp);
977 }
978
979 int GetFertilizerQuantity(int slotIndex)
980 {
981 int bitsPerSlot = 8;
982 int slotsPerInt = 32 / bitsPerSlot;
983
984 int groupIndex = slotIndex / slotsPerInt;
985 int bitOffset = (slotIndex % slotsPerInt) * bitsPerSlot;
986
987 int value = GetFertilizerBitmapByIndex(groupIndex);
988 return (value >> bitOffset) & 255;
989 }
990
992 [Obsolete("No replacement")]
993 bool IsCorrectFertilizer( ItemBase item, string selection_component )
994 {
995 Slot slot = GetSlotBySelection( selection_component );
996
997 if ( slot != NULL )
998 {
999 string item_type = item.GetType();
1000
1001 if ( slot.GetFertilityType() == "" || slot.GetFertilityType() == item_type )
1002 {
1003 return true;
1004 }
1005 }
1006
1007 return false;
1008 }
1009
1010 [Obsolete("No replacement")]
1011 void UpdateTexturesOnAllSlots()
1012 {
1013 int slots_count = GetGardenSlotsCount();
1014 for (int i = 0; i < slots_count; ++i)
1015 {
1016 UpdateSlotTexture(i);
1017 }
1018 }
1019
1020 [Obsolete("No replacement")]
1021 bool NeedsFertilization(string selection_component)
1022 {
1023 Slot slot = GetSlotBySelection(selection_component);
1024 if (slot)
1025 {
1026 if (slot.GetFertilityState() == eFertlityState.NONE)
1027 {
1028 return true;
1029 }
1030 }
1031
1032 return false;
1033 }
1034
1035 [Obsolete("CAContinuousFertilizeGardenSlot::FertilizeSlot is used now instead.")]
1036 void Fertilize( PlayerBase player, ItemBase item, float consumed_quantity, string selection_component )
1037 {
1038 Slot slot = GetSlotBySelection( selection_component );
1039
1040 if ( slot != NULL )
1041 {
1042 string item_type = item.GetType();
1043
1044 if ( slot.GetFertilityType() == "" || slot.GetFertilityType() == item_type )
1045 {
1046 slot.SetFertilityType(item_type);
1047
1048 float add_energy_to_slot = GetGame().ConfigGetFloat( string.Format("cfgVehicles %1 Horticulture AddEnergyToSlot", item_type) );
1049 slot.m_FertilizerUsage = GetGame().ConfigGetFloat( string.Format("cfgVehicles %1 Horticulture ConsumedQuantity", item_type) );
1050
1051 float coef = Math.Clamp( consumed_quantity / slot.m_FertilizerUsage, 0.0, 1.0 );
1052 add_energy_to_slot = coef * add_energy_to_slot;
1053
1054 slot.m_FertilizerQuantity += consumed_quantity;
1055 slot.m_Fertility += add_energy_to_slot;
1056
1057 if ( slot.GetFertilizerQuantity() >= slot.GetFertilizerQuantityMax() )
1058 {
1059 int slot_index = slot.GetSlotIndex();
1060
1061 if (slot_index > -1)
1062 {
1063 UpdateSlotTexture( slot_index );
1064 slot.SetFertilityState(eFertlityState.FERTILIZED);
1065 // Set relevant bit
1066 m_SlotFertilityState |= slot.GetFertilityState() << slot.GetSlotIndex();
1067 }
1068 }
1069 }
1070 else
1071 {
1072 slot.SetFertilizerQuantity(0);
1073 slot.SetFertilityType("");
1074 slot.SetFertilityState(eFertlityState.NONE);
1075 }
1076 SetSynchDirty();
1077 }
1078 }
1079
1080 [Obsolete("No replacement")]
1081 void WaterAllSlots()
1082 {
1083 for (int i = 0; i < m_Slots.Count(); i++)
1084 {
1085 Slot slot = m_Slots[i];
1086 if (!slot)
1087 continue;
1088
1089 slot.SetWateredState(eWateredState.WET);
1090 UpdateSlotTexture(slot.GetSlotIndex());
1091 m_SlotWateredState |= eWateredState.WET << slot.GetSlotIndex();
1092 }
1093 }
1094}
void AddAction(typename actionName)
void SetActions()
override void EEItemDetached(EntityAI item, string slot_name)
override void EEItemAttached(EntityAI item, string slot_name)
PlayerSpawnPresetDiscreteItemSetSlotData name
one set for cargo
proto native Weather GetWeather()
Returns weather controller object.
Definition debug.c:2
provides access to slot configuration
ref array< ref Slot > m_Slots
Definition gardenbase.c:26
int m_SlotFertilizerBitmap1
Definition gardenbase.c:38
int m_SlotFertilizerBitmap0
Definition gardenbase.c:37
ref Timer m_CheckRainTimer
Definition gardenbase.c:42
int m_SlotWaterBitmap0
Definition gardenbase.c:33
int m_SlotFertilizerBitmap2
Definition gardenbase.c:39
int m_SlotWaterBitmap2
Definition gardenbase.c:35
int m_SlotWaterBitmap1
Definition gardenbase.c:34
int GetState()
Definition tentbase.c:438
Definition enmath.c:7
Serialization general interface. Serializer API works with:
Definition serializer.c:56
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
override void OnVariablesSynchronized()
DayZGame g_Game
Definition dayzgame.c:3868
override int GetHideIconMask()
string ToStringLen(int len)
Integer to string with fixed length, padded with zeroes.
Definition enconvert.c:59
override bool CanRemoveFromHands(EntityAI parent)
proto native CGame GetGame()
override void SyncSlots()
Definition gardenplot.c:184
GardenPlotGreenhouse GardenPlot EOnInit(IEntity other, int extra)
Definition gardenplot.c:182
void Obsolete(string msg="")
Definition enscript.c:371
EntityEvent
Entity events for event-mask, or throwing event from code.
Definition enentity.c:45
class JsonUndergroundAreaTriggerData GetPosition
const int CALL_CATEGORY_SYSTEM
Definition tools.c:8
override void EEOnAfterLoad()
Definition itembase.c:8077
void OnStoreSave(ParamsWriteContext ctx)
PluginBase GetPlugin(typename plugin_type)
eFertlityState
Definition slot.c:2