DayZ 1.30
DayZ Explorer by KGB
 
Загрузка...
Поиск...
Не найдено
ComponentEnergyManager.c
См. документацию.
1//-----------------------------
2// ENERGY MANAGER
3//-----------------------------
4/*
5Author: Boris Vacula
6
7Documentation can be found at DayZ Confluence >> Camping & Squatting >> Electricity >> Energy Manager functionalities
8
9This system controls storage, spending and sharing of energy between instances.
10
11Every EntityAI object which uses this API gains these functions:
12 -It can store some amout of energy
13 -It can use this amount of energy for any kind of functionality
14 -It can share this energy with other devices plugged into it
15 -It will have an ON/OFF switch
16*/
17
19{
20 protected const float DEFAULT_UPDATE_INTERVAL = 15;
21 protected static bool m_DebugPlugs = false; //true; // Use this to toggle visualisation of plug connections
23
24 protected bool m_IsSwichedOn;
25 protected bool m_IsSwichedOnPreviousState; // Necesarry due to synchronization of m_IsSwichedOn
26 protected bool m_IsPassiveDevice;
27 protected bool m_IsWorking;
28 protected bool m_CanWork;
29 protected bool m_CanStopWork;
30 protected bool m_RestorePlugState; // After server restart, this value reports if this device was plugged into something or not at the end of last session.
31 protected bool m_AutoSwitchOff;
33 protected bool m_HasElectricityIcon; // Electricity icon over the item in inventory
35 protected bool m_IsPlugged; // Synchronized variable
37
38 protected int m_MySocketID = -1;
39 protected int m_PlugType;
40 protected int m_EnergySourceStorageIDb1; // Storage persistence ID
41 protected int m_EnergySourceStorageIDb2; // Storage persistence ID
42 protected int m_EnergySourceStorageIDb3; // Storage persistence ID
43 protected int m_EnergySourceStorageIDb4; // Storage persistence ID
45 protected int m_EnergySourceNetworkIDLow = -1; // Network ID
46 protected int m_EnergySourceNetworkIDHigh = -1; // Network ID
47
48 protected float m_EnergyUsage;
49 protected float m_Energy;
50 protected float m_EnergyAtSpawn;
51 protected float m_EnergyStorageMax;
53 protected float m_SocketsCount;
54 protected float m_CordLength;
55 protected float m_LastUpdateTime;
56 protected float m_WetnessExposure;
57 protected float m_UpdateInterval; // Interval of OnWork(...) calls and device updates.
58
59 protected string m_CordTextureFile;
60
61 // Concatenated strings for p3d selections
62 protected static const string SOCKET_ = "socket_";
63 protected static const string _PLUGGED = "_plugged";
64 protected static const string _AVAILABLE = "_available";
65 static const string SEL_CORD_PLUGGED = "cord_plugged";
66 static const string SEL_CORD_FOLDED = "cord_folded";
67
69 EntityAI m_EnergySource; // Energy source can be any EntityAI object
72
73 const int MAX_SOCKETS_COUNT = 4;
75
76
77
78 // Constructor
80 {
81 // Disable debug arrows on public release, so that they don't use their timers.
82 #ifndef DEVELOPER
83 m_DebugPlugs = false;
84 #endif
85 }
86
88 {
90 {
91 m_DebugPlugArrow.Destroy();
92 m_DebugPlugArrow = NULL;
93 }
94 }
95
96 // Initialization. Energy Manager is ready.
97 override void Event_OnInit()
98 {
99 if (!m_ThisEntityAI)
100 return;
101
102 m_ThisEntityAI.m_EM = this;
103 g_Game.GameScript.CallFunction(m_ThisEntityAI, "OnInitEnergy", NULL, 0);
104 }
105
106 // Update debug arrows
108 {
109 if ( GetDebugPlugs() )
110 {
111 if (g_Game.IsMultiplayer() && g_Game.IsServer())
112 {
113 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).Remove(DebugUpdate);
114 return;
115 }
116
118 {
119 m_DebugPlugArrow.Destroy();
120 m_DebugPlugArrow = NULL;
121 }
122
124 {
125 vector from = GetEnergySource().GetPosition() + "0 0.1 0";
126 vector to = m_ThisEntityAI.GetPosition() + "0 0.1 0";
127
128 //No need to draw an arrow in this situation as it would not be visible
129 if ( vector.DistanceSq(from, to) == 0 )
130 return;
131
132 if ( m_ThisEntityAI.GetType() == "BarbedWire" ) // Special case for debugging of electric fences. Temporal code until offsets in fences are fixed.
133 {
134 EntityAI BBB = m_ThisEntityAI.GetHierarchyParent();
135
136 if ( BBB && BBB.GetType() == "Fence" )
137 {
138 to = to + "0 -1.3 0";
139 }
140 }
141
142 m_DebugPlugArrow = DrawArrow( from, to );
143 }
144 }
145 }
146
147 Shape DrawArrow(vector from, vector to, float size = 0.5, int color = 0xFFFFFFFF, float flags = 0)
148 {
149 vector dir = to - from;
150 dir.Normalize();
151 vector dir1 = dir * size;
152 size = size * 0.5;
153
154 vector dir2 = dir.Perpend() * size;
155
156 vector pts[5];
157 pts[0] = from;
158 pts[1] = to;
159 pts[2] = to - dir1 - dir2;
160 pts[3] = to - dir1 + dir2;
161 pts[4] = to;
162
163 return Shape.CreateLines(color, flags, pts, 5);
164 }
165
167 {
168 return m_ThisEntityAI;
169 }
170
171 // Prepare everything
172 override void Event_OnAwake()
173 {
174 if (!m_ThisEntityAI)
175 return;
176
177 string cfg_item = "CfgVehicles " + m_ThisEntityAI.GetType();
178 string cfg_energy_manager = cfg_item + " EnergyManager ";
179
180 // Read all config parameters
181 m_EnergyUsage = g_Game.ConfigGetFloat(cfg_energy_manager + "energyUsagePerSecond");
182 bool switch_on = g_Game.ConfigGetFloat(cfg_energy_manager + "switchOnAtSpawn");
183 m_AutoSwitchOff = g_Game.ConfigGetFloat(cfg_energy_manager + "autoSwitchOff");
184 m_HasElectricityIcon = g_Game.ConfigGetFloat(cfg_energy_manager + "hasIcon");
185 m_AutoSwitchOffWhenInCargo = g_Game.ConfigGetFloat(cfg_energy_manager + "autoSwitchOffWhenInCargo");
186
187 m_EnergyAtSpawn = g_Game.ConfigGetFloat(cfg_energy_manager + "energyAtSpawn");
189 m_EnergyStorageMax = g_Game.ConfigGetFloat(cfg_energy_manager + "energyStorageMax");
190 m_ReduceMaxEnergyByDamageCoef = g_Game.ConfigGetFloat(cfg_energy_manager + "reduceMaxEnergyByDamageCoef");
191 m_SocketsCount = g_Game.ConfigGetFloat(cfg_energy_manager + "powerSocketsCount");
192
193 m_IsPassiveDevice = g_Game.ConfigGetFloat(cfg_energy_manager + "isPassiveDevice");
194 m_CordLength = g_Game.ConfigGetFloat(cfg_energy_manager + "cordLength");
195 m_PlugType = g_Game.ConfigGetFloat(cfg_energy_manager + "plugType");
196
197 m_AttachmentActionType = g_Game.ConfigGetFloat(cfg_energy_manager + "attachmentAction");
198 m_WetnessExposure = g_Game.ConfigGetFloat(cfg_energy_manager + "wetnessExposure");
199
200 float update_interval = g_Game.ConfigGetFloat(cfg_energy_manager + "updateInterval");
201
202 m_ConvertEnergyToQuantity = g_Game.ConfigGetFloat(cfg_energy_manager + "convertEnergyToQuantity");
203
204
205 // Check if energy->quantity converion is configured properly
206 float cfg_max_quantity = g_Game.ConfigGetFloat (cfg_item + " varQuantityMax");
207
208 if (m_ConvertEnergyToQuantity && cfg_max_quantity <= 0)
209 {
210 string error = "Error! Item " + m_ThisEntityAI.GetType() + " has invalid configuration of the energy->quantity conversion feature. To fix this, add 'varQuantityMax' parameter with value higher than 0 to the item's config. Then make sure to re-build the PBO containing this item!";
211 Error(error);
213 }
214 else
215 {
217 {
218 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(OnEnergyAdded, 300);
219 }
220 }
221
222 // Set update interval
223 if ( update_interval <= 0 )
224 update_interval = DEFAULT_UPDATE_INTERVAL;
225
226 SetUpdateInterval( update_interval );
227
228 // If energyAtSpawn is present, then use its value for energyStorageMax if that cfg param is not present (for convenience's sake)
229 string cfg_check_energy_limit = cfg_energy_manager + "energyStorageMax";
230
231 if ( !g_Game.ConfigIsExisting (cfg_check_energy_limit) && m_Energy > 0 )
232 {
234 }
235
236 // Fill m_CompatiblePlugTypes
237 string cfg_check_plug_types = cfg_energy_manager + "compatiblePlugTypes";
238
239 if ( g_Game.ConfigIsExisting (cfg_check_plug_types) )
240 {
242 g_Game.ConfigGetIntArray(cfg_check_plug_types, m_CompatiblePlugTypes);
243 }
244
245 if (GetSocketsCount() > 0)
247
248 if ( m_CordLength < 0 )
249 {
250 m_CordLength = 0;
251 string error_message_cord = "Warning! " + m_ThisEntityAI.GetType() + ": config parameter 'cordLength' is less than 0! Cord length should not be negative!";
252 DPrint(error_message_cord);
253 }
254
255 if (GetSocketsCount() > 0)
256 {
258 // Prepare the m_DeviceByPlugSelection
259 string cfg_animation_sources = "cfgVehicles " + m_ThisEntityAI.GetType() + " " + "AnimationSources ";
260 int animation_sources_count = g_Game.ConfigGetChildrenCount(cfg_animation_sources);
261
262 for (int i_selection = 0; i_selection < animation_sources_count; i_selection++)
263 {
264 // TO DO: This could be optimized so not all selections on item are considered as plug/socket selections.
265 string selection;
266 g_Game.ConfigGetChildName(cfg_animation_sources, i_selection, selection);
267 m_DeviceByPlugSelection.Set(selection, NULL);
268 }
269 }
270
271
272
273 // Prepare sockets
275 {
277 string error_message_sockets = "Error! " + m_ThisEntityAI.GetType() + ": config parameter 'powerSocketsCount' is higher than the current limit (" + MAX_SOCKETS_COUNT.ToString() + ")! Raise the limit (constant MAX_SOCKETS_COUNT) or decrease the powerSocketsCount parameter for this device!";
278 DPrint(error_message_sockets);
279 }
280
281 m_Sockets[MAX_SOCKETS_COUNT]; // Handles selections for plugs in the sockets. Feel free to change the limit if needed.
282
283 g_Game.ConfigGetText(cfg_energy_manager + "cordTextureFile", m_CordTextureFile);
284
285 if ( switch_on )
286 {
287 SwitchOn();
288 }
289
290 for ( int i = 0; i <= GetSocketsCount(); ++i )
291 {
292 m_ThisEntityAI.HideSelection ( SOCKET_ + i.ToString() + _PLUGGED );
293 }
294
295 // Show/hide inventory sockets
297 if ( GetSocketsCount() > 0 && IsPlugCompatible(PLUG_COMMON_APPLIANCE) && m_ThisEntityAI.GetType() != "MetalWire" ) // metal wire filter is hopefully temporal.
298 {
300 }
301
303
304 m_ThisEntityAI.HideSelection( SEL_CORD_PLUGGED );
305
306
307 #ifdef DIAG_DEVELOPER
308 g_Game.m_EnergyManagerArray.Insert( this );
309 #endif
310 }
311
312 // Returns the type of this component
313 override int GetCompType()
314 {
316 }
317
318 // When the object is deleted
320 {
321 if (!m_ThisEntityAI)
322 return;
323
324 bool was_working = m_ThisEntityAI.GetCompEM().IsWorking();
325
326 SwitchOff();
328 UnplugThis();
329 SetPowered( false );
330
331 if ( was_working )
332 m_ThisEntityAI.OnWorkStop();
333 ;
334 }
335
336 //Restart the debug timer when relogging
338 {
339 if ( m_DebugPlugs )
340 {
341 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(DebugUpdate, 10, true);
342 }
343 else
344 {
345 if ( m_DebugPlugArrow )
346 {
347 m_DebugPlugArrow.Destroy();
348 m_DebugPlugArrow = NULL;
349 }
350 }
351 }
352
354 {
355 return m_DebugPlugs;
356 }
357
358 void SetDebugPlugs( bool newVal )
359 {
360 m_DebugPlugs = newVal;
361 RefreshDebug();
362 }
363
364 //======================================================================================
365 // PUBLIC FUNCTIONS
366 // Use these to control the Energy Manager
367 // Functions are in order of their return value: void, bool, int, float, string, array.
368 //======================================================================================
369
371 void SwitchOn()
372 {
374
375 if (g_Game.IsServer() || !g_Game.IsMultiplayer())
376 {
378 {
379 m_IsSwichedOn = true;
380 Synch();
381
382 DeviceUpdate(); // 'Wake up' this device now
383 StartUpdates();
384
385 // 'Wakes up' all connected devices
387
389
390 // Call event
391 g_Game.GameScript.CallFunction(m_ThisEntityAI, "OnSwitchOn", NULL, 0);
392 }
393 }
394
395 if ( !g_Game.IsServer() && g_Game.IsMultiplayer()/* && CanSwitchOn() */) // I want the CanSwitchOn() check, but when it's here, the OnSwitchOn() event is never called on client-side due to engine's synchronization system changing the m_IsSwichedOn to true without any specific event beign called. (Yes there is OnVariablesSynchronized() but that is called also when m_CanWork is synchronized, so I need to write a method of knowing when was this specific value changed.)
396 {
397 g_Game.GameScript.CallFunction(m_ThisEntityAI, "OnSwitchOn", NULL, 0);
398 }
399 }
400
403 {
405
406 if (g_Game.IsServer() || !g_Game.IsMultiplayer())
407 {
409 {
410 m_IsSwichedOn = false;
411 Synch();
412
413 if (IsWorking())
414 {
415 StopUpdates();
416 DeviceUpdate();
417 }
418
419 // 'Wakes up' all connected devices
421
423
424 // Call event
425 g_Game.GameScript.CallFunction(m_ThisEntityAI, "OnSwitchOff", NULL, 0);
426 }
427 }
428
429 if ( !g_Game.IsServer() && g_Game.IsMultiplayer() )
430 {
431 m_IsSwichedOn = false;
432 g_Game.GameScript.CallFunction(m_ThisEntityAI, "OnSwitchOff", NULL, 0);
433 }
434 }
435
437 void SetPassiveState(bool state = true)
438 {
439 m_IsPassiveDevice = state;
440 if ( !m_IsPassiveDevice )
441 {
442 DeviceUpdate();
443 }
444 }
445
447 void UnplugDevice(EntityAI device_to_unplug)
448 {
449 if (g_Game)
450 {
451 int indexStart = GetPluggedDevicesCount() - 1;
452 bool deviceFound = false;
453
454 for (int i = indexStart; i >= 0; --i)
455 {
456 EntityAI plugged_device = GetPluggedDevices().Get(i);
457
458 if (plugged_device == device_to_unplug)
459 {
460 GetPluggedDevices().Remove(i);
461 deviceFound = true;
462 break;
463 }
464 }
465
466 if (deviceFound && m_ThisEntityAI)
467 {
468 int socket_ID = device_to_unplug.GetCompEM().GetMySocketID();
469 UnplugCordFromSocket(socket_ID);
470 device_to_unplug.GetCompEM().SetEnergySource(null);
471 device_to_unplug.GetCompEM().DeviceUpdate();
472 device_to_unplug.GetCompEM().StartUpdates();
473 device_to_unplug.GetCompEM().WakeUpWholeBranch(m_ThisEntityAI);
474
476 {
477 m_DebugPlugArrow.Destroy();
478 m_DebugPlugArrow = null;
479 }
480
481 OnOwnSocketReleased(device_to_unplug);
482 device_to_unplug.GetCompEM().OnIsUnplugged(m_ThisEntityAI);
483 device_to_unplug.ShowSelection(SEL_CORD_FOLDED);
484 device_to_unplug.HideSelection(SEL_CORD_PLUGGED);
485 }
486 }
487 }
488
491 {
492 if (g_Game)
493 {
495 {
496 GetEnergySource().GetCompEM().UnplugDevice(m_ThisEntityAI);
497 }
498 }
499 }
500
503 {
504 if ( GetPluggedDevices() ) // This check is necesarry in case this function is called before initialization
505 {
506 int indexStart = GetPluggedDevicesCount() - 1;
507 for (int i = indexStart; i >= 0; --i)
508 {
510 }
511 }
512 }
513
514 // Used only for storing of the plug's state through server restart
515 void RestorePlugState(bool state)
516 {
517 m_RestorePlugState = state;
518 }
519
521 void SetEnergy(float new_energy)
522 {
523 if (m_ThisEntityAI && (g_Game.IsServer() || !g_Game.IsMultiplayer())) // Client can't change energy value.
524 {
525 m_ThisEntityAI.SetWeightDirty();
526 float old_energy = m_Energy;
527 m_Energy = new_energy;
528
529 if (old_energy - GetEnergyUsage() <= 0 || (old_energy != new_energy && Math.Min(old_energy,new_energy) <= 0))
530 {
532 }
533 }
534 }
535
537 void SetEnergy0To1(float energy01)
538 {
539 SetEnergy( Math.Lerp(0, GetEnergyMax(),energy01));
540 }
541
544 {
545 if (!m_ThisEntityAI)
546 return;
547
548 // Lets update sockets, if there are any
549 int slots_c = GetSocketsCount();
550
551 for (int i = 0; i < slots_c; ++i)
552 {
553 EntityAI plug_owner = GetDeviceBySocketID(i);
554
555 if (plug_owner)
556 {
557 string plugged_selection = SOCKET_ + (i+1).ToString() + _PLUGGED;
558 string available_selection = SOCKET_ + (i+1).ToString() + _AVAILABLE;
559 m_ThisEntityAI.ShowSelection(plugged_selection);
560 m_ThisEntityAI.HideSelection(available_selection);
561 string texture_path = plug_owner.GetCompEM().GetCordTextureFile();
562 int selection_index = m_ThisEntityAI.GetHiddenSelectionIndex(plugged_selection);
563 m_ThisEntityAI.SetObjectTexture(selection_index, texture_path);
564 }
565 else
566 {
567 m_ThisEntityAI.ShowSelection(SOCKET_ + (i+1).ToString() + _AVAILABLE);
568 m_ThisEntityAI.HideSelection(SOCKET_ + (i+1).ToString() + _PLUGGED);
569 }
570 }
571
572 // Now lets update the cord/plug state
573 if (GetEnergySource())
574 {
575 m_ThisEntityAI.ShowSelection(SEL_CORD_PLUGGED);
576 m_ThisEntityAI.HideSelection(SEL_CORD_FOLDED);
577 }
578 else
579 {
580 m_ThisEntityAI.ShowSelection(SEL_CORD_FOLDED);
581 m_ThisEntityAI.HideSelection(SEL_CORD_PLUGGED);
582 }
583 }
584
587 {
588 if (m_ThisEntityAI && m_ThisEntityAI.GetCompEM().GetEnergySource())
589 {
590 EntityAI player = m_ThisEntityAI.GetHierarchyRootPlayer();
591 // Check if the item is held in hands during advanced placement
592 if (player)
593 {
594 // Measure distance from the player
595 vector playerPosition = player.GetPosition();
596 if (!IsEnergySourceAtReach(playerPosition, 5))
597 UnplugThis();
598 }
599 else
600 {
601 // Measure distance from the device
602 vector itemPosition = m_ThisEntityAI.GetPosition();
603
604 if (m_ThisEntityAI.GetHierarchyParent())
605 itemPosition = m_ThisEntityAI.GetHierarchyParent().GetPosition();
606
607 if (!IsEnergySourceAtReach(itemPosition))
608 UnplugThis();
609 }
610 }
611 }
612
613 // Returns an array of plug types this device can accept
615 {
617 }
618
619 // Stores IDs of the energy source.
620 void StoreEnergySourceIDs(int b1, int b2, int b3, int b4)
621 {
626 }
627
629 void SetEnergyMaxPristine(float new_limit)
630 {
631 m_EnergyStorageMax = new_limit;
632 }
633
635 void SetCordLength( float new_length )
636 {
637 m_CordLength = new_length;
638 }
639
640 // Sets the plug type (for plug -> socket compatibility checks).
641 void SetPlugType( int new_type )
642 {
643 m_PlugType = new_type;
644 }
645
646 // Sets the new attachment action type.
647 void SetAttachmentAction( int new_action_type )
648 {
649 m_AttachmentActionType = new_action_type;
650 }
651
653 void SetEnergyUsage( float new_usage )
654 {
655 m_EnergyUsage = new_usage;
656 }
657
660 {
661 if (!m_ThisEntityAI)
662 return;
663
664 string cfg_energy_usage = "CfgVehicles " + m_ThisEntityAI.GetType() + " EnergyManager ";
665 m_EnergyUsage = g_Game.ConfigGetFloat (cfg_energy_usage + "energyUsagePerSecond");
666 }
667
668 // Sets path to the cord texture file.
669 void SetCordTextureFile( string new_path )
670 {
671 m_CordTextureFile = new_path;
672 }
673
674 // Sets energy source. Intended to be called only on client through RPC.
676 {
677 SetEnergySource(source);
678 }
679
681 void SetDeviceBySocketID(int id, EntityAI plugged_device)
682 {
683 m_Sockets[id] = plugged_device;
684 }
685
686
688 void SetElectricityIconVisibility( bool make_visible )
689 {
690 m_HasElectricityIcon = make_visible;
691 }
692
693 // Checks whenever this device can work or not and updates this information on all clients. Can be called many times per frame because synchronization happens only once if a change has occured.
695 {
696 if (g_Game.IsServer() || !g_Game.IsMultiplayer())
697 {
698 bool current_state = CanWork();
699 if (current_state != m_CanWork)
700 {
701 m_CanWork = current_state;
702
703 if (m_ThisEntityAI)
704 {
705 Synch();
706 if (m_ThisEntityAI.GetHierarchyParent() && m_ThisEntityAI.GetHierarchyParent().GetCompEM())
707 {
708 m_ThisEntityAI.GetHierarchyParent().GetCompEM().UpdateCanWork();
709 }
710 }
711 }
712 }
713 }
714
716 {
718 {
719 if (IsSwitchedOn())
720 {
721 SwitchOff();
722 }
723 }
724 }
725
727 void SetUpdateInterval( float value )
728 {
729 m_UpdateInterval = value;
730 }
731
732 // Returns true if this device was plugged into something at the end of previous session
734 {
735 return m_RestorePlugState;
736 }
737
739 bool PlugThisInto(EntityAI energy_source, int socket_id = -1)
740 {
741 if (m_ThisEntityAI)
742 {
743 return energy_source.GetCompEM().PlugInDevice(m_ThisEntityAI, socket_id);
744 }
745 else
746 {
747 return false;
748 }
749 }
750
753 {
754 if ( !IsSwitchedOn() )
755 {
756 return true;
757 }
758
759 return false;
760 }
761
762
768 bool CanWork( float test_energy = -1)
769 {
770 if ( g_Game.IsMultiplayer() && g_Game.IsClient() )
771 {
772 return m_CanWork;
773 }
774
775 if (!m_ThisEntityAI || m_ThisEntityAI.IsRuined())
776 {
777 return false;
778 }
779
780 // Check if the power source(s) (which can be serially connected) can provide needed energy.
781 float energy_usage = test_energy;
782 float gathered_energy = GetEnergy();
783 EntityAI energy_source = GetEnergySource();
784
785 if (energy_usage == -1)
786 {
787 energy_usage = GetEnergyUsage();
788 }
789
790 if ( !CheckWetness() )
791 {
792 return false;
793 }
794
795 if (gathered_energy <= 0 && energy_usage <= 0) //empty power source
796 {
797 return false;
798 }
799
800 int cycle_limit = 500; // Sanity check to definitely avoid infinite cycles
801
802 while ( gathered_energy < energy_usage ) // Look for energy source if we don't have enough stored energy
803 {
804 // Safetycheck!
805 if (cycle_limit > 0)
806 {
807 cycle_limit--;
808 }
809 else
810 {
811 DPrint("Energy Manager ERROR: The 'cycle_limit' safety break had to be activated to prevent possible game freeze. Dumping debug information...");
812 //Print(m_ThisEntityAI);
813 //Print(this);
814 //Print(energy_source);
815
816 if (energy_source.GetCompEM())
817 {
818 //Print(energy_source.GetCompEM());
819 }
820
821 //Print(gathered_energy);
822 //Print(energy_usage);
823
824 //Print(m_ThisEntityAI.GetPosition());
825
826 if (energy_source)
827 {
828 //Print(energy_source.GetPosition());
829 }
830
831 //Print("End of the 'cycle_limit' safety break ^ ");
832
833 return false;
834 }
835 // ^ Safetycheck!
836
837 if ( energy_source && energy_source != m_ThisEntityAI && !energy_source.IsRuined() && energy_source.GetCompEM() && energy_source.GetCompEM().IsSwitchedOn() && energy_source.GetCompEM().CheckWetness() )
838 {
839 gathered_energy = gathered_energy + energy_source.GetCompEM().GetEnergy();
840 energy_source = energy_source.GetCompEM().GetEnergySource();
841 }
842 else
843 {
844 // No power source, no energy.
845 return false;
846 }
847 }
848
849 // Enough energy was found
850 return true;
851 }
852
855 {
856 if (m_ThisEntityAI)
857 {
858 return (m_ThisEntityAI.GetWet() <= 1-m_WetnessExposure);
859 }
860 else
861 {
862 return false;
863 }
864 }
865
868 {
869 if ( IsPassive() )
870 {
871 return false;
872 }
873
874 return IsSwitchedOn();
875 }
876
877 // Returns previous state of the switch.
882
885 {
886 return m_IsSwichedOn;
887 }
888
891 {
892 if ( IsPlugged() )
893 return false;
894
895 return true;
896 }
897
900 {
901 return m_IsPassiveDevice;
902 }
903
906 {
907 return m_IsPlugged;
908 }
909
910
912 bool ConsumeEnergy(float amount)
913 {
914 if (m_ThisEntityAI)
915 {
916 return FindAndConsumeEnergy(m_ThisEntityAI, amount, true);
917 }
918 else
919 {
920 return false;
921 }
922 }
923
926 {
927 return m_IsWorking;
928 }
929
932 {
933 if ( GetEnergy() > GetEnergyUsage() )
934 {
935 return true;
936 }
937
938 return false;
939 }
940
942 bool HasFreeSocket( int socket_id = -1 )
943 {
944 if (socket_id == -1)
945 {
946 int plugged_devices = GetPluggedDevicesCount();
947 int plugged_devices_limit = GetSocketsCount();
948
949 if ( plugged_devices < plugged_devices_limit )
950 {
951 return true;
952 }
953
954 return false;
955 }
956 else
957 {
958 EntityAI device = GetDeviceBySocketID(socket_id);
959
960 if (device)
961 {
962 return false;
963 }
964 else
965 {
966 return true;
967 }
968 }
969 }
970
972 bool IsPlugCompatible(int plug_ID)
973 {
974 if ( plug_ID == PLUG_UNDEFINED )
975 {
976 return true; // When plugType is undefined in config then make it compatible.
977 }
978
980 {
981 int nCompatiblePlugTypes = m_CompatiblePlugTypes.Count();
982 for ( int i = 0; i < nCompatiblePlugTypes; ++i )
983 {
984 int plug_ID_to_Check = m_CompatiblePlugTypes.Get(i);
985
986 if ( plug_ID_to_Check == plug_ID )
987 {
988 return true;
989 }
990 }
991 }
992 else
993 {
994 // Since the config parameter compatiblePlugTypes is not present, then accept all plugs for simplicity's sake
995 return true;
996 }
997
998 return false;
999 }
1000
1002 bool CanReceivePlugFrom( EntityAI device_to_plug )
1003 {
1004 // The following conditions are broken down for the sake of easier reading/debugging.
1005 if (m_ThisEntityAI && HasFreeSocket() && device_to_plug != m_ThisEntityAI)
1006 {
1007 if ( device_to_plug.GetCompEM().GetEnergySource() != m_ThisEntityAI)
1008 {
1009 if ( IsPlugCompatible(device_to_plug.GetCompEM().GetPlugType()) )
1010 {
1011 if ( device_to_plug.GetCompEM().IsEnergySourceAtReach( device_to_plug.GetPosition(), 0, m_ThisEntityAI.GetPosition() ) )
1012 {
1013 return true;
1014 }
1015 }
1016 }
1017 }
1018
1019 return false;
1020 }
1021
1023 bool CanBePluggedInto( EntityAI potential_energy_provider )
1024 {
1025 if (m_ThisEntityAI)
1026 {
1027 return potential_energy_provider.GetCompEM().CanReceivePlugFrom(m_ThisEntityAI);
1028 }
1029 else
1030 {
1031 return false;
1032 }
1033 }
1034
1037 {
1038 return m_HasElectricityIcon;
1039 }
1040
1046
1063 bool IsEnergySourceAtReach( vector from_position, float add_tolerance = 0, vector override_source_position = "-1 -1 -1" )
1064 {
1065 if ( !IsPlugged() && override_source_position == "-1 -1 -1" )
1066 {
1067 return false;
1068 }
1069
1070 if ( GetCordLength() == 0 ) // 0 is an exception, which means infinitely long cable.
1071 {
1072 return true;
1073 }
1074
1075 vector source_pos;
1076 float distance;
1077
1078 if ( override_source_position == "-1 -1 -1" )
1079 {
1080 EntityAI energy_source = GetEnergySource();
1081
1082 if (!energy_source)
1083 return false;
1084
1085 source_pos = energy_source.GetPosition();
1086 distance = vector.Distance( from_position, source_pos );
1087 }
1088 else
1089 {
1090 source_pos = override_source_position;
1091 distance = vector.Distance( from_position, source_pos );
1092 }
1093
1094 if (distance > GetCordLength() + add_tolerance)
1095 {
1096 return false;
1097 }
1098 else
1099 {
1100 return true;
1101 }
1102 }
1103
1108
1110 bool IsSelectionAPlug(string selection_to_test )
1111 {
1112 if ( GetPluggedDevices() )
1113 {
1114 int socket_count = GetSocketsCount();
1115
1116 for ( int i = socket_count; i >= 0; --i )
1117 {
1118 string real_selection = SOCKET_ + i.ToString() +_PLUGGED;
1119
1120 if ( selection_to_test == real_selection)
1121 {
1122 return true;
1123 }
1124 }
1125 }
1126
1127 return false;
1128 }
1129
1130
1131
1132
1135 {
1136 return m_SocketsCount;
1137 }
1138
1141 {
1142 return m_PlugType;
1143 }
1144
1145 // Returns the action ID which is supposed to be done upon receiving an attachment
1147 {
1149 }
1150
1151 // Returns persistent ID (block 1) of the energy source
1156
1157 // Returns persistent ID (block 2) of the energy source
1162
1163 // Returns persistent ID (block 3) of the energy source
1168
1169 // Returns persistent ID (block 4) of the energy source
1174
1175 // Returns network ID (low) of the energy source
1180
1181 // Returns network ID (high) of the energy source
1186
1189 {
1190 if ( GetPluggedDevices() )
1191 {
1192 return GetPluggedDevices().Count();
1193 }
1194
1195 return 0;
1196 }
1197
1200 {
1201 if ( m_EnergyStorageMax > 0 )
1202 {
1203 int coef = Math.Round( m_Energy / m_EnergyStorageMax * 100 );
1204 return coef;
1205 }
1206
1207 return 0;
1208 }
1209
1212 {
1213 if ( m_EnergyStorageMax > 0 )
1214 {
1216 }
1217
1218 return 0;
1219 }
1220
1223 {
1224 #ifdef DIAG_DEVELOPER
1225 if (FeatureTimeAccel.GetFeatureTimeAccelEnabled(ETimeAccelCategories.ENERGY_CONSUMPTION) || (FeatureTimeAccel.GetFeatureTimeAccelEnabled(ETimeAccelCategories.ENERGY_RECHARGE)))
1226 {
1227 return 1;//when modifying time accel, we might want to see things happen when they should, instead of waiting for the next tick
1228 }
1229 #endif
1230 return m_UpdateInterval;
1231 }
1232
1235 {
1236 return m_WetnessExposure;
1237 }
1238
1241 {
1242 return m_EnergyUsage;
1243 }
1244
1247 {
1248 return m_Energy;
1249 }
1250
1252 float AddEnergy(float added_energy)
1253 {
1254 if (added_energy != 0)
1255 {
1256 //Print("AddEnergy ---------> " + added_energy + " " + this + " " +m_ThisEntityAI.ClassName());
1257 #ifdef DIAG_DEVELOPER
1258 if (FeatureTimeAccel.GetFeatureTimeAccelEnabled(ETimeAccelCategories.ENERGY_CONSUMPTION) && added_energy < 0)
1259 {
1260 float timeAccel = FeatureTimeAccel.GetFeatureTimeAccelValue();
1261 added_energy *= timeAccel;
1262 }
1263 #endif
1264
1265 bool energy_was_added = (added_energy > 0);
1266
1267 float energy_to_clamp = GetEnergy() + added_energy;
1268 float clamped_energy = Math.Clamp( energy_to_clamp, 0, GetEnergyMax() );
1269 SetEnergy(clamped_energy);
1270 StartUpdates();
1271
1272 if (energy_was_added)
1273 OnEnergyAdded();
1274 else
1276
1277 return energy_to_clamp - clamped_energy;
1278 }
1279
1280 return 0;
1281 }
1282
1285 {
1286 float max_health = 0;
1287
1288 if (m_ThisEntityAI && m_ThisEntityAI.HasDamageSystem())
1289 max_health = m_ThisEntityAI.GetMaxHealth("","");
1290 //else if ( m_ReduceMaxEnergyByDamageCoef != 0 )
1291 // Error("[ERROR] ReduceMaxEnergyByDamageCoef is setup but " + m_ThisEntityAI.GetType() + " does not have a Damage System");
1292
1293 if ( max_health == 0 || m_ReduceMaxEnergyByDamageCoef == 0 )
1294 return GetEnergyMaxPristine();
1295
1296 float health = 100;
1297
1298 if (m_ThisEntityAI && (g_Game.IsServer() || !g_Game.IsMultiplayer())) // TO DO: Remove this IF when method GetHealth can be called on client!
1299 health = m_ThisEntityAI.GetHealth("","");
1300
1301 float damage_coef = 1 - (health / max_health);
1302
1303 return GetEnergyMaxPristine() * (1 - ( damage_coef * m_ReduceMaxEnergyByDamageCoef ) );
1304 }
1305
1308 {
1309 return m_EnergyStorageMax;
1310 }
1311
1313 {
1314 return m_EnergyAtSpawn;
1315 }
1316
1319 {
1320 return m_CordLength;
1321 }
1322
1325 {
1326 return m_EnergySource;
1327 }
1328
1331 {
1332 return m_Sockets[id];
1333 }
1334
1336 EntityAI GetPlugOwner(string plug_selection_name)
1337 {
1338 if ( m_DeviceByPlugSelection && m_DeviceByPlugSelection.Contains(plug_selection_name) )
1339 {
1340 return m_DeviceByPlugSelection.Get(plug_selection_name);
1341 }
1342
1343 return NULL;
1344 }
1345
1348 {
1349 if ( GetPluggedDevicesCount() > 0 )
1350 {
1351 return GetPluggedDevices().Get(0);
1352 }
1353
1354 return NULL;
1355 }
1356
1359 {
1360 return m_CordTextureFile;
1361 }
1362
1368
1371 {
1372 array<EntityAI> return_array = new array<EntityAI>;
1373 int plugged_devices_c = GetPluggedDevicesCount();
1374 for ( int i = 0; i < plugged_devices_c; ++i )
1375 {
1376 EntityAI device = GetPluggedDevices().Get(i);
1377 if ( IsSwitchedOn() )
1378 {
1379 return_array.Insert(device);
1380 }
1381 }
1382
1383 return return_array;
1384 }
1385
1386
1387 /*===================================
1388 PUBLIC EVENTS
1389 ===================================*/
1390
1391 // Called every device update if its supposed to do some work. The update can be every second or at random, depending on its manipulation.
1392 void OnWork( float consumed_energy )
1393 {
1394 if (m_ThisEntityAI)
1395 m_ThisEntityAI.OnWork(consumed_energy);
1396 }
1397
1398 // Called when this device is plugged into some energy source
1399 void OnIsPlugged(EntityAI source_device)
1400 {
1401 if (m_DebugPlugs)
1402 {
1403 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(DebugUpdate, 10, true);
1404 }
1405
1406 UpdateCanWork();
1407 if (m_ThisEntityAI)
1408 m_ThisEntityAI.OnIsPlugged(source_device);
1409 }
1410
1411 // Called when this device is UNPLUGGED from the energy source
1412 void OnIsUnplugged( EntityAI last_energy_source )
1413 {
1414 UpdateCanWork();
1415 if (m_ThisEntityAI)
1416 m_ThisEntityAI.OnIsUnplugged( last_energy_source );
1417 }
1418
1419 // When something is plugged into this device
1421 {
1422 if (!m_ThisEntityAI)
1423 return;
1424
1425 //play sound
1426 if (device.GetCompEM().GetPlugType() == PLUG_COMMON_APPLIANCE && m_ThisEntityAI.IsInitialized())
1427 {
1428 EffectSound sound_plug;
1429 m_ThisEntityAI.PlaySoundSet(sound_plug, "cablereel_plugin_SoundSet", 0, 0);
1430 }
1431
1432 m_ThisEntityAI.OnOwnSocketTaken(device);
1433 }
1434
1435 // When something is UNPLUGGED from this device
1437 {
1438 if (!m_ThisEntityAI)
1439 return;
1440
1441 //play sound
1442 if ( device.GetCompEM().GetPlugType() == PLUG_COMMON_APPLIANCE && m_ThisEntityAI.IsInitialized() )
1443 {
1444 EffectSound sound_unplug;
1445 m_ThisEntityAI.PlaySoundSet( sound_unplug, "cablereel_unplug_SoundSet", 0, 0 );
1446 }
1447
1448 m_ThisEntityAI.OnOwnSocketReleased( device );
1449 }
1450
1451
1452 // Handles automatic attachment action
1453 void OnAttachmentAdded(EntityAI elec_device)
1454 {
1455 if (!m_ThisEntityAI)
1456 return;
1457
1458 int attachment_action_type = GetAttachmentAction();
1459
1460 if (attachment_action_type == PLUG_THIS_INTO_ATTACHMENT)
1461 {
1462 if (elec_device.GetCompEM().CanReceivePlugFrom(m_ThisEntityAI))
1463 {
1464 PlugThisInto(elec_device);
1465 }
1466 }
1467 else if (attachment_action_type == PLUG_ATTACHMENTS_INTO_THIS)
1468 {
1469 elec_device.GetCompEM().PlugThisInto(m_ThisEntityAI);
1470 }
1471 }
1472
1473 // Handles automatic detachment action
1475 {
1476 int attachment_action_type = GetAttachmentAction();
1477
1478 if ( attachment_action_type == PLUG_THIS_INTO_ATTACHMENT )
1479 {
1480 if ( elec_device == GetEnergySource() )
1481 {
1482 UnplugThis();
1483 }
1484 }
1485 else if ( attachment_action_type == PLUG_ATTACHMENTS_INTO_THIS )
1486 {
1487 elec_device.GetCompEM().UnplugThis();
1488 }
1489 }
1490
1491 // Starts the device's main cycle
1493 {
1494 if (!m_IsPassiveDevice)
1495 {
1496 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).Remove(DeviceUpdate);
1497
1498 float updateInterval = GetUpdateInterval() * 1000;
1499 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(DeviceUpdate, updateInterval, true);
1500 }
1501 }
1502
1505 {
1506 if (m_ThisEntityAI)
1507 m_ThisEntityAI.OnEnergyConsumed();
1508 }
1509
1512 {
1513 if (m_ThisEntityAI)
1514 m_ThisEntityAI.OnEnergyAdded();
1515 }
1516
1517
1518 /*===================================
1519 PROTECTED FUNCTIONS
1520 ===================================*/
1521
1522 // Stops the device's main cycle
1523 protected void StopUpdates()
1524 {
1525 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).Remove(DeviceUpdate);
1526 }
1527
1531 void InteractBranch(EntityAI originalCaller, Man player = null, int system = 0)
1532 {
1533 OnInteractBranch(originalCaller, player, system);
1534 if ( GetSocketsCount() > 0 )
1535 {
1537
1538 foreach ( EntityAI device : devices)
1539 {
1540 if ( device != originalCaller ) // originalCaller check here prevents infinite loops
1541 {
1542 device.GetCompEM().InteractBranch( originalCaller, player, system );
1543 }
1544 }
1545 }
1546 }
1547
1549 protected void OnInteractBranch(EntityAI originalCaller, Man player, int system)
1550 {
1551 if (m_ThisEntityAI)
1552 m_ThisEntityAI.IncreaseLifetime();
1553
1554 }
1555
1556 // 'Wakes up' all devices down the network so they start working, if they have enough power, and are switched ON
1557 protected void WakeUpWholeBranch( EntityAI original_caller )
1558 {
1559 if ( GetSocketsCount() > 0 )
1560 {
1561 array<EntityAI> plugged_devices = GetPluggedDevices();
1562 int plugged_devices_c = plugged_devices.Count();
1563
1564 for ( int i = 0; i < plugged_devices_c; ++i )
1565 {
1566 EntityAI device = plugged_devices.Get(i);
1567 if ( device != original_caller ) // original_caller check here prevents infinite loops
1568 {
1569 device.GetCompEM().UpdateCanWork();
1570 device.GetCompEM().DeviceUpdate();
1571 device.GetCompEM().StartUpdates();
1572 device.GetCompEM().WakeUpWholeBranch( original_caller );
1573 }
1574 }
1575 }
1576 }
1577
1578 // Finds an available socket and plugs the given device into it.
1579 // This is mainly about visualisation.
1580 protected void PlugCordIntoSocket( EntityAI device_to_plug, int socket_id = -1 )
1581 {
1582 if (socket_id >= 0)
1583 {
1584 EntityAI plug_owner_by_socket = GetDeviceBySocketID(socket_id);
1585
1586 if (!plug_owner_by_socket)
1587 {
1588 UpdateSocketSelections(socket_id, device_to_plug);
1589 return;
1590 }
1591 }
1592
1593 int slots_c = GetSocketsCount();
1594
1595 for ( int i = 0; i < slots_c; ++i )
1596 {
1597 EntityAI plug_owner = GetDeviceBySocketID(i);
1598
1599 if ( !plug_owner ) // Check if this socket is available
1600 {
1601 UpdateSocketSelections(i, device_to_plug);
1602 break;
1603 }
1604 }
1605 }
1606
1607 // Updates socket selections (plugged/unplugged) of the given ID and sets color texture of the plug.
1608 protected void UpdateSocketSelections(int socket_id, EntityAI device_to_plug)
1609 {
1610 if (!m_ThisEntityAI)
1611 return;
1612
1613 SetDeviceBySocketID(socket_id, device_to_plug);
1614
1615 string plugged_selection = SOCKET_ + (socket_id+1).ToString() + _PLUGGED;
1616 SetPlugOwner( plugged_selection, device_to_plug );
1617 m_ThisEntityAI.ShowSelection ( plugged_selection );
1618
1619 string unplugged_selection = SOCKET_ + (socket_id+1).ToString() + _AVAILABLE;
1620 m_ThisEntityAI.HideSelection ( unplugged_selection );
1621 string texture_path = device_to_plug.GetCompEM().GetCordTextureFile();
1622 int selection_index = m_ThisEntityAI.GetHiddenSelectionIndex( plugged_selection );
1623 m_ThisEntityAI.SetObjectTexture( selection_index, texture_path );
1624 device_to_plug.GetCompEM().SetMySocketID(socket_id);
1625 }
1626
1627
1628 // Sets energy source for this device
1629 protected void SetEnergySource( EntityAI source )
1630 {
1631 m_EnergySource = source;
1632
1633 if (source)
1634 {
1635 m_IsPlugged = true;
1636 StartUpdates();
1637 }
1638 else
1639 {
1640 m_IsPlugged = false;
1643 }
1644
1645 if (m_EnergySource)
1647
1648 Synch();
1649 }
1650
1651 // Plugs the given device into this one
1652 protected bool PlugInDevice(EntityAI device_to_plug, int socket_id = -1)
1653 {
1654 if (m_ThisEntityAI && CanReceivePlugFrom(device_to_plug))
1655 {
1656 device_to_plug.IncreaseLifetime();
1658 if (device_to_plug.GetCompEM().IsPlugged())
1659 device_to_plug.GetCompEM().UnplugThis();
1660
1661 GetPluggedDevices().Insert(device_to_plug);
1662 device_to_plug.GetCompEM().SetEnergySource(m_ThisEntityAI);
1663
1664 PlugCordIntoSocket(device_to_plug, socket_id); // Visualisation
1665 OnOwnSocketTaken(device_to_plug);
1666
1667 device_to_plug.GetCompEM().OnIsPlugged(m_ThisEntityAI);
1669
1670 if (g_Game.IsServer() || !g_Game.IsMultiplayer())
1671 {
1672 device_to_plug.HideSelection(SEL_CORD_FOLDED);
1673 device_to_plug.ShowSelection(SEL_CORD_PLUGGED);
1674 }
1675
1676 return true;
1677 }
1678
1679 return false;
1680 }
1681
1682 // Sets the device to which the given plug selection belongs to
1683 protected void SetPlugOwner(string selection_name, EntityAI device)
1684 {
1685 if ( m_DeviceByPlugSelection.Contains(selection_name) )
1686 {
1687 m_DeviceByPlugSelection.Set(selection_name, device);
1688 }
1689 }
1690
1691 // Frees the given socket.
1692 // This is only about visualisation.
1693 protected void UnplugCordFromSocket( int socket_to_unplug_ID )
1694 {
1695 EntityAI plug_owner = GetDeviceBySocketID(socket_to_unplug_ID);
1696
1697 if (m_ThisEntityAI && plug_owner)
1698 {
1699 SetDeviceBySocketID(socket_to_unplug_ID, NULL);
1700 string unplugged_selection = SOCKET_ + (socket_to_unplug_ID+1).ToString() + _AVAILABLE;
1701 m_ThisEntityAI.ShowSelection ( unplugged_selection );
1702
1703 string plugged_selection = SOCKET_ + (socket_to_unplug_ID+1).ToString() + _PLUGGED;
1704 m_ThisEntityAI.HideSelection ( plugged_selection );
1705 SetPlugOwner( plugged_selection, NULL );
1706 plug_owner.GetCompEM().SetMySocketID(-1);
1707 }
1708 }
1709
1710 // Sets the state of the device
1711 protected void SetPowered( bool state )
1712 {
1713 m_IsWorking = state;
1714 }
1715
1716 // Tries to consume the given amount of energy. If there is none in this device, then it tries to take it from some power source.
1717 protected bool FindAndConsumeEnergy(EntityAI original_caller, float amount, bool ignore_switch_state = false)
1718 {
1719 if ((ignore_switch_state || IsSwitchedOn()) && m_ThisEntityAI && !m_ThisEntityAI.IsRuined())
1720 {
1721 float available_energy = AddEnergy(-amount);
1722
1723 if (available_energy < 0 && IsPlugged())
1724 {
1725 // This devices does not has enough of stored energy, therefore it will take it from its power source (which can be a chain of cable reels)
1726 EntityAI next_power_source = GetEnergySource();
1727
1728 if (next_power_source && next_power_source != original_caller) // Prevents infinite loop if the power source is the original caller itself
1729 {
1730 return next_power_source.GetCompEM().FindAndConsumeEnergy(original_caller, -available_energy);
1731 }
1732 }
1733
1734 if (available_energy >= 0)
1735 {
1736 return true;
1737 }
1738
1739 return false;
1740 }
1741 else
1742 {
1743 return false;
1744 }
1745 }
1746
1747 // Gets the socket ID this device is powered from.
1748 protected int GetMySocketID()
1749 {
1750 return m_MySocketID;
1751 }
1752
1753 // Sets the socket ID this device is plugged into.
1754 protected void SetMySocketID( int slot_ID )
1755 {
1756 m_MySocketID = slot_ID;
1757 }
1758
1759 void Synch()
1760 {
1761 if (m_ThisEntityAI && g_Game.IsServer())
1762 m_ThisEntityAI.SetSynchDirty();
1763 }
1764
1766 {
1767 m_LastUpdateTime = 0;
1768 }
1769
1774
1776 {
1777 return g_Game.GetTime();
1778 }
1779
1780 // Updates the device's state of power. This function is visualized in the diagram at DayZ Confluence >> Camping & Squatting >> Electricity >> Energy Manager functionalities
1782 {
1783 /*
1784 vector pos = m_ThisEntityAI.GetPosition();
1785 string debug_message = "Object " + m_ThisEntityAI.GetType() + " | Energy: " + GetEnergy() + " | IsAtReach: " + (IsEnergySourceAtReach(pos)).ToString();
1786 Print(debug_message);
1787 */
1788
1789 if ( !m_IsPassiveDevice )
1790 {
1791 // 'm_ThisEntityAI' and 'this' must be checked because this method is caled from a timer
1792 if (m_ThisEntityAI && this && IsSwitchedOn() && !m_ThisEntityAI.IsRuined() && CheckWetness() && m_CanWork && !g_Game.IsMissionMainMenu())
1793 {
1794 bool was_powered = IsWorking();
1795 float consumed_energy_coef;
1796 // Make sure to use only as much % of energy as needed since this function can be called at random.
1797
1798 if ( m_LastUpdateTime == 0 )
1799 {
1801 consumed_energy_coef = 1.0;
1802 }
1803 else
1804 {
1805 float updatetime = GetCurrentUpdateTime();
1806 float time = updatetime - m_LastUpdateTime;
1807 consumed_energy_coef = time / 1000;
1808 }
1809
1810 if (consumed_energy_coef > 0) // Prevents calling of OnWork events when no energy is consumed
1811 {
1813 float consume_energy = GetEnergyUsage() * consumed_energy_coef;
1814 bool has_consumed_enough = true;
1815
1816 if (g_Game.IsServer() || !g_Game.IsMultiplayer()) // single player or server side multiplayer
1817 has_consumed_enough = ConsumeEnergy( consume_energy );
1818
1819 SetPowered( has_consumed_enough );
1820
1821 if ( has_consumed_enough )
1822 {
1823 if ( !was_powered )
1824 {
1825 m_CanStopWork = true;
1827 g_Game.GameScript.CallFunction(m_ThisEntityAI, "OnWorkStart", NULL, 0);
1828 UpdateCanWork();
1829 }
1830
1831 OnWork( consume_energy );
1832 }
1833 else
1834 {
1835 if ( was_powered )
1836 {
1837 if (m_CanStopWork)
1838 {
1839 m_CanStopWork = false;
1841 g_Game.GameScript.CallFunction(m_ThisEntityAI, "OnWorkStop", NULL, 0); // This event is called only once when the device STOPS being powered
1842 UpdateCanWork();
1843
1844 if (m_AutoSwitchOff)
1845 {
1846 SwitchOff();
1847 }
1848 }
1849 }
1850
1851 StopUpdates();
1852 }
1853 }
1854 else
1855 {
1857 }
1858 }
1859 else if (this && m_ThisEntityAI)
1860 {
1861 SetPowered( false );
1862 StopUpdates();
1863
1864 if (m_CanStopWork)
1865 {
1866 m_CanStopWork = false;
1868 g_Game.GameScript.CallFunction(m_ThisEntityAI, "OnWorkStop", NULL, 0); // This event is called only once when the device STOPS being powered
1869 UpdateCanWork();
1870
1871 if (m_AutoSwitchOff)
1872 {
1873 SwitchOff();
1874 }
1875 }
1876 }
1877 }
1878 }
1879
1884}
const int PLUG_ATTACHMENTS_INTO_THIS
const int PLUG_THIS_INTO_ATTACHMENT
const int PLUG_UNDEFINED
const int PLUG_COMMON_APPLIANCE
DayZGame g_Game
Определения DayZGame.c:4074
proto string ToString()
override float Get()
Определения PlayerStatBase.c:134
EntityAI m_ThisEntityAI
Определения Component.c:24
bool m_RestorePlugState
Определения ComponentEnergyManager.c:30
static const string SEL_CORD_FOLDED
Определения ComponentEnergyManager.c:66
ref Timer m_UpdateTimer
DEPRECATED BELOW.
Определения ComponentEnergyManager.c:1881
float GetEnergyAtSpawn()
Определения ComponentEnergyManager.c:1312
float m_LastUpdateTime
Определения ComponentEnergyManager.c:55
void SetElectricityIconVisibility(bool make_visible)
Energy manager: Sets visibility of the electricity icon (bolt).
Определения ComponentEnergyManager.c:688
void SwitchOn()
Energy manager: Switches ON the device so it starts doing its work if it has enough energy.
Определения ComponentEnergyManager.c:371
float GetEnergyMax()
Energy manager: Returns the maximum amount of energy this device can curently store....
Определения ComponentEnergyManager.c:1284
bool GetPreviousSwitchState()
Определения ComponentEnergyManager.c:878
void UnplugAllDevices()
Energy manager: Unplugs everything directly connected to this device.
Определения ComponentEnergyManager.c:502
void SetMySocketID(int slot_ID)
Определения ComponentEnergyManager.c:1754
static const string SOCKET_
Определения ComponentEnergyManager.c:62
float m_WetnessExposure
Определения ComponentEnergyManager.c:56
void InteractBranch(EntityAI originalCaller, Man player=null, int system=0)
Определения ComponentEnergyManager.c:1531
int m_EnergySourceStorageIDb3
Определения ComponentEnergyManager.c:42
float GetEnergyUsage()
Energy manager: Returns the number of energy this device needs to run itself (See its config >> energ...
Определения ComponentEnergyManager.c:1240
void OnInteractBranch(EntityAI originalCaller, Man player, int system)
Called when the player is interacting with an item containing this energy component,...
Определения ComponentEnergyManager.c:1549
void ComponentEnergyManager()
Определения ComponentEnergyManager.c:79
int GetEnergySourceNetworkIDLow()
Определения ComponentEnergyManager.c:1176
bool IsWorking()
Energy manager: Returns true if this device is working right now.
Определения ComponentEnergyManager.c:925
int m_EnergySourceStorageIDb2
Определения ComponentEnergyManager.c:41
void SetEnergyMaxPristine(float new_limit)
Energy manager: Changes the maximum amount of energy this device can store (when pristine).
Определения ComponentEnergyManager.c:629
Shape DrawArrow(vector from, vector to, float size=0.5, int color=0xFFFFFFFF, float flags=0)
Определения ComponentEnergyManager.c:147
static const string _AVAILABLE
Определения ComponentEnergyManager.c:64
bool m_ConvertEnergyToQuantity
Определения ComponentEnergyManager.c:36
void SetDebugPlugs(bool newVal)
Определения ComponentEnergyManager.c:358
void GetCompatiblePlugTypes(out TIntArray IDs)
Определения ComponentEnergyManager.c:614
float m_EnergyAtSpawn
Определения ComponentEnergyManager.c:50
void SetEnergy0To1(float energy01)
Energy manager: Sets stored energy for this device between 0 and MAX based on relative input value be...
Определения ComponentEnergyManager.c:537
bool HasFreeSocket(int socket_id=-1)
Energy manager: Returns true if this device has any free socket to receive a plug....
Определения ComponentEnergyManager.c:942
ref Timer m_UpdateQuantityTimer
Определения ComponentEnergyManager.c:1882
float GetWetnessExposure()
Returns wetness exposure value defined in config.
Определения ComponentEnergyManager.c:1234
float m_UpdateInterval
Определения ComponentEnergyManager.c:57
bool m_HasElectricityIcon
Определения ComponentEnergyManager.c:33
void WakeUpWholeBranch(EntityAI original_caller)
Определения ComponentEnergyManager.c:1557
void UnplugDevice(EntityAI device_to_unplug)
Energy manager: Unplugs the given device from this one.
Определения ComponentEnergyManager.c:447
bool CheckWetness()
Energy manager: Checks if this device is being stopped from working by its wetness level....
Определения ComponentEnergyManager.c:854
static const string _PLUGGED
Определения ComponentEnergyManager.c:63
void SetUpdateInterval(float value)
Energy manager: Sets the interval of the OnWork(...) calls. Changing this value does not change the r...
Определения ComponentEnergyManager.c:727
void SetPassiveState(bool state=true)
Energy manager: Changes the status of this device. When it's passive (true), the main timer and OnWor...
Определения ComponentEnergyManager.c:437
static bool m_DebugPlugs
Определения ComponentEnergyManager.c:21
bool PlugInDevice(EntityAI device_to_plug, int socket_id=-1)
Определения ComponentEnergyManager.c:1652
void SetAttachmentAction(int new_action_type)
Определения ComponentEnergyManager.c:647
bool FindAndConsumeEnergy(EntityAI original_caller, float amount, bool ignore_switch_state=false)
Определения ComponentEnergyManager.c:1717
ref Timer m_DebugUpdate
Определения ComponentEnergyManager.c:1883
void OnEnergyAdded()
Energy manager: Called when energy was added on this device.
Определения ComponentEnergyManager.c:1511
void UnplugCordFromSocket(int socket_to_unplug_ID)
Определения ComponentEnergyManager.c:1693
float AddEnergy(float added_energy)
Energy manager: Adds energy to this device and clamps it within its min/max storage limits....
Определения ComponentEnergyManager.c:1252
const float DEFAULT_UPDATE_INTERVAL
Определения ComponentEnergyManager.c:20
int GetEnergySourceStorageIDb4()
Определения ComponentEnergyManager.c:1170
void UnplugThis()
Energy manager: Unplugs this device from its power source.
Определения ComponentEnergyManager.c:490
float GetCurrentUpdateTime()
Определения ComponentEnergyManager.c:1775
int GetPluggedDevicesCount()
Energy manager: Returns the number of devices plugged into this one.
Определения ComponentEnergyManager.c:1188
void ClearLastUpdateTime()
Определения ComponentEnergyManager.c:1765
void SetCordLength(float new_length)
Energy manager: Changes the length of the virtual power cord.
Определения ComponentEnergyManager.c:635
void SetEnergySourceClient(EntityAI source)
Определения ComponentEnergyManager.c:675
void SetEnergySource(EntityAI source)
Определения ComponentEnergyManager.c:1629
EntityAI m_EnergySource
Определения ComponentEnergyManager.c:69
int m_EnergySourceNetworkIDLow
Определения ComponentEnergyManager.c:45
int GetEnergy0To100()
Energy manager: Returns % of stored energy this device has as integer (from 0 to 100)
Определения ComponentEnergyManager.c:1199
void ~ComponentEnergyManager()
Определения ComponentEnergyManager.c:87
void PlugCordIntoSocket(EntityAI device_to_plug, int socket_id=-1)
Определения ComponentEnergyManager.c:1580
bool IsEnergySourceAtReach(vector from_position, float add_tolerance=0, vector override_source_position="-1 -1 -1")
Energy manager: Returns true if this device's virtual power cord can reach its energy source at the g...
Определения ComponentEnergyManager.c:1063
void HandleMoveInsideCargo(EntityAI container)
Определения ComponentEnergyManager.c:715
float GetEnergy()
Energy manager: Returns the amount of stored energy this device has.
Определения ComponentEnergyManager.c:1246
int GetPlugType()
Energy manager: Returns plug type. Check \DZ\data\basicDefines.hpp OR \Scripts\Classes\Component_cons...
Определения ComponentEnergyManager.c:1140
bool CanBePluggedInto(EntityAI potential_energy_provider)
Energy manager: Returns true if this device can be plugged into the given energy source....
Определения ComponentEnergyManager.c:1023
bool IsPlugged()
Energy manager: Returns true if this device is plugged into some other device (even if they are OFF o...
Определения ComponentEnergyManager.c:905
EntityAI GetEnergySource()
Energy manager: Returns the energy source this device is plugged into.
Определения ComponentEnergyManager.c:1324
ref array< EntityAI > m_PluggedDevices
Определения ComponentEnergyManager.c:70
void OnAttachmentRemoved(EntityAI elec_device)
Определения ComponentEnergyManager.c:1474
EntityAI GetThisEntityAI()
Определения ComponentEnergyManager.c:166
void OnWork(float consumed_energy)
Определения ComponentEnergyManager.c:1392
const int MAX_SOCKETS_COUNT
Определения ComponentEnergyManager.c:73
array< EntityAI > GetPluggedDevices()
Energy manager: Returns an array of devices which are plugged into this one.
Определения ComponentEnergyManager.c:1364
float m_ReduceMaxEnergyByDamageCoef
Определения ComponentEnergyManager.c:52
int GetEnergySourceNetworkIDHigh()
Определения ComponentEnergyManager.c:1182
bool IsPassive()
Energy manager: Returns true if this device is set to be passive. False if otherwise.
Определения ComponentEnergyManager.c:899
Shape m_DebugPlugArrow
Определения ComponentEnergyManager.c:22
bool HasConversionOfEnergyToQuantity()
Energy manager: Returns true if this item automatically converts its energy to quantity.
Определения ComponentEnergyManager.c:1042
void SetPowered(bool state)
Определения ComponentEnergyManager.c:1711
void SetPlugType(int new_type)
Определения ComponentEnergyManager.c:641
void StoreEnergySourceIDs(int b1, int b2, int b3, int b4)
Определения ComponentEnergyManager.c:620
int GetEnergySourceStorageIDb2()
Определения ComponentEnergyManager.c:1158
ref TIntArray m_CompatiblePlugTypes
Определения ComponentEnergyManager.c:68
void UpdatePlugState()
Energy manager: Unplugs this device when it's necesarry.
Определения ComponentEnergyManager.c:586
void OnAttachmentAdded(EntityAI elec_device)
Определения ComponentEnergyManager.c:1453
void OnIsPlugged(EntityAI source_device)
Определения ComponentEnergyManager.c:1399
EntityAI m_Sockets[MAX_SOCKETS_COUNT]
Определения ComponentEnergyManager.c:74
string GetCordTextureFile()
Energy manager: Returns path to the cord texture file.
Определения ComponentEnergyManager.c:1358
ref map< string, EntityAI > m_DeviceByPlugSelection
Определения ComponentEnergyManager.c:71
bool IsSelectionAPlug(string selection_to_test)
Energy manager: Returns true if this selection is a plug that's plugged into this device....
Определения ComponentEnergyManager.c:1110
void SetEnergy(float new_energy)
Energy manager: Sets stored energy for this device. It ignores the min/max limit!
Определения ComponentEnergyManager.c:521
void SetPlugOwner(string selection_name, EntityAI device)
Определения ComponentEnergyManager.c:1683
float GetCordLength()
Energy manager: Returns the length of the virtual power cord.
Определения ComponentEnergyManager.c:1318
EntityAI GetPlugOwner(string plug_selection_name)
Energy manager: Returns the device to which the given plug selection belongs to.
Определения ComponentEnergyManager.c:1336
int GetAttachmentAction()
Определения ComponentEnergyManager.c:1146
bool CanWork(float test_energy=-1)
Energy manager: Checks whenever this device can do work or not.
Определения ComponentEnergyManager.c:768
EntityAI GetPluggedDevice()
Energy manager: Returns a device which is plugged into this one. If there are more devices to choose ...
Определения ComponentEnergyManager.c:1347
void UpdateSelections()
Energy manager: Shows/Hides all selections this system works with. Call this if something is wrong wi...
Определения ComponentEnergyManager.c:543
void OnIsUnplugged(EntityAI last_energy_source)
Определения ComponentEnergyManager.c:1412
bool GetRestorePlugState()
Определения ComponentEnergyManager.c:733
bool HasVisibleSocketsInInventory()
Определения ComponentEnergyManager.c:1104
int m_AttachmentActionType
Определения ComponentEnergyManager.c:44
bool m_ShowSocketsInInventory
Определения ComponentEnergyManager.c:32
static const string SEL_CORD_PLUGGED
Определения ComponentEnergyManager.c:65
bool IsCordFolded()
Energy manager: Returns true if the cord of this device is folded. Returns false if it's plugged.
Определения ComponentEnergyManager.c:890
override int GetCompType()
Определения ComponentEnergyManager.c:313
void RestorePlugState(bool state)
Определения ComponentEnergyManager.c:515
int m_EnergySourceStorageIDb4
Определения ComponentEnergyManager.c:43
bool m_AutoSwitchOffWhenInCargo
Определения ComponentEnergyManager.c:34
float GetEnergy0To1()
Energy manager: Returns % of stored energy this device has as float (from 0.0 to 1....
Определения ComponentEnergyManager.c:1211
void SwitchOff()
Energy manager: Switches OFF the device.
Определения ComponentEnergyManager.c:402
void OnOwnSocketReleased(EntityAI device)
Определения ComponentEnergyManager.c:1436
array< EntityAI > GetPoweredDevices()
Energy manager: Returns an array of devices which are plugged into this one and are turned on.
Определения ComponentEnergyManager.c:1370
override void Event_OnAwake()
Определения ComponentEnergyManager.c:172
bool ConsumeEnergy(float amount)
Energy manager: Consumes the given amount of energy. If there is not enough of stored energy in this ...
Определения ComponentEnergyManager.c:912
float m_EnergyStorageMax
Определения ComponentEnergyManager.c:51
void RememberLastUpdateTime()
Определения ComponentEnergyManager.c:1770
bool CanSwitchOn()
Energy manager: Checks if the device can be switched ON.
Определения ComponentEnergyManager.c:752
void ResetEnergyUsage()
Energy manager: Resets energy usage to default (config) value.
Определения ComponentEnergyManager.c:659
int m_EnergySourceNetworkIDHigh
Определения ComponentEnergyManager.c:46
int GetEnergySourceStorageIDb1()
Определения ComponentEnergyManager.c:1152
bool IsPlugCompatible(int plug_ID)
Energy manager: Checks if the given plug is compatible with this device's socket. Used by CanReceiveP...
Определения ComponentEnergyManager.c:972
void SetEnergyUsage(float new_usage)
Energy manager: Changes the energy usage per second.
Определения ComponentEnergyManager.c:653
void OnEnergyConsumed()
Energy manager: Called when energy was consumed on this device.
Определения ComponentEnergyManager.c:1504
void SetCordTextureFile(string new_path)
Определения ComponentEnergyManager.c:669
override void Event_OnInit()
Определения ComponentEnergyManager.c:97
string m_CordTextureFile
Определения ComponentEnergyManager.c:59
bool CanSwitchOff()
Energy manager: Checks if the device can be switched OFF.
Определения ComponentEnergyManager.c:867
int GetSocketsCount()
Energy manager: Returns the count of power sockets (whenever used or not)
Определения ComponentEnergyManager.c:1134
void SetDeviceBySocketID(int id, EntityAI plugged_device)
Energy manager: Stores the device which is plugged into the given socket ID.
Определения ComponentEnergyManager.c:681
void UpdateSocketSelections(int socket_id, EntityAI device_to_plug)
Определения ComponentEnergyManager.c:1608
float GetUpdateInterval()
Energy manager: Returns the update interval of this device.
Определения ComponentEnergyManager.c:1222
bool m_IsSwichedOnPreviousState
Определения ComponentEnergyManager.c:25
bool HasElectricityIcon()
Energy manager: Returns true if the electricity icon (bolt) is supposed to be visible for this device...
Определения ComponentEnergyManager.c:1036
void OnOwnSocketTaken(EntityAI device)
Определения ComponentEnergyManager.c:1420
void OnDeviceDestroyed()
Определения ComponentEnergyManager.c:319
bool PlugThisInto(EntityAI energy_source, int socket_id=-1)
Energy manager: Attempts to plug this device into the energy_source. Returns true if the action was s...
Определения ComponentEnergyManager.c:739
int m_EnergySourceStorageIDb1
Определения ComponentEnergyManager.c:40
EntityAI GetDeviceBySocketID(int id)
Energy manager: Returns the device which is plugged into the given socket ID.
Определения ComponentEnergyManager.c:1330
float GetEnergyMaxPristine()
Energy manager: Returns the maximum amount of energy this device can store. It's damage is NOT taken ...
Определения ComponentEnergyManager.c:1307
bool IsSwitchedOn()
Energy manager: Returns state of the switch. Whenever the device is working or not does not matter....
Определения ComponentEnergyManager.c:884
int GetEnergySourceStorageIDb3()
Определения ComponentEnergyManager.c:1164
bool HasEnoughStoredEnergy()
Energy manager: Returns true if this device has enough of stored energy for its own use.
Определения ComponentEnergyManager.c:931
bool CanReceivePlugFrom(EntityAI device_to_plug)
Energy manager: Returns true if this device can receive power plug of the other device.
Определения ComponentEnergyManager.c:1002
Определения Component.c:16
Wrapper class for managing sound through SEffectManager.
Определения EffectSound.c:5
Определения EnMath.c:7
Определения DayZPlayerImplement.c:39
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
Определения Transport.c:70
static proto native float DistanceSq(vector v1, vector v2)
Returns the square distance between tips of two 3D vectors.
proto float Normalize()
Normalizes vector. Returns length.
static proto native float Distance(vector v1, vector v2)
Returns the distance between tips of two 3D vectors.
vector Perpend()
Returns perpendicular vector. Perpendicular vector is computed as cross product between input vector ...
Определения EnConvert.c:222
Определения EnConvert.c:119
const int COMP_TYPE_ENERGY_MANAGER
Определения Component.c:9
void Error(string err)
Messagebox with error message.
Определения EnDebug.c:90
proto void DPrint(string var)
Prints content of variable to console/log. Should be used for critical messages so it will appear in ...
class DiagMenu Shape
don't call destructor directly. Use Destroy() instead
array< int > TIntArray
Определения EnScript.c:733
static proto float Lerp(float a, float b, float time)
Linearly interpolates between 'a' and 'b' given 'time'.
static proto float Min(float x, float y)
Returns smaller of two given values.
static proto float Round(float f)
Returns mathematical round of value.
static proto float Clamp(float value, float min, float max)
Clamps 'value' to 'min' if it is lower than 'min', or to 'max' if it is higher than 'max'.
const int CALL_CATEGORY_SYSTEM
Определения 3_Game/DayZ/tools/tools.c:8