20 protected const float DEFAULT_UPDATE_INTERVAL = 15;
21 protected static bool m_DebugPlugs =
false;
22 protected Shape m_DebugPlugArrow;
24 protected bool m_IsSwichedOn;
25 protected bool m_IsSwichedOnPreviousState;
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;
31 protected bool m_AutoSwitchOff;
32 protected bool m_ShowSocketsInInventory;
33 protected bool m_HasElectricityIcon;
34 protected bool m_AutoSwitchOffWhenInCargo;
35 protected bool m_IsPlugged;
36 protected bool m_ConvertEnergyToQuantity;
38 protected int m_MySocketID = -1;
39 protected int m_PlugType;
40 protected int m_EnergySourceStorageIDb1;
41 protected int m_EnergySourceStorageIDb2;
42 protected int m_EnergySourceStorageIDb3;
43 protected int m_EnergySourceStorageIDb4;
44 protected int m_AttachmentActionType;
45 protected int m_EnergySourceNetworkIDLow = -1;
46 protected int m_EnergySourceNetworkIDHigh = -1;
48 protected float m_EnergyUsage;
49 protected float m_Energy;
50 protected float m_EnergyAtSpawn;
51 protected float m_EnergyStorageMax;
52 protected float m_ReduceMaxEnergyByDamageCoef;
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;
59 protected string m_CordTextureFile;
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";
68 protected ref
TIntArray m_CompatiblePlugTypes;
73 ref
Timer m_UpdateTimer;
74 ref
Timer m_UpdateQuantityTimer;
75 ref
Timer m_DebugUpdate;
77 const int MAX_SOCKETS_COUNT = 4;
78 EntityAI m_Sockets[MAX_SOCKETS_COUNT];
95 m_DebugPlugArrow.Destroy();
96 m_DebugPlugArrow = NULL;
101 override void Event_OnInit()
103 m_ThisEntityAI.m_EM =
this;
104 GetGame().GameScript.CallFunction(m_ThisEntityAI,
"OnInitEnergy", NULL, 0);
110 if ( GetDebugPlugs() )
115 m_DebugUpdate.Stop();
120 if (m_DebugPlugArrow)
122 m_DebugPlugArrow.Destroy();
123 m_DebugPlugArrow = NULL;
126 if ( GetEnergySource() )
128 vector from = GetEnergySource().GetPosition() +
"0 0.1 0";
129 vector to = m_ThisEntityAI.GetPosition() +
"0 0.1 0";
132 if (
vector.DistanceSq(from, to) == 0 )
135 if ( m_ThisEntityAI.GetType() ==
"BarbedWire" )
137 EntityAI BBB = m_ThisEntityAI.GetHierarchyParent();
139 if ( BBB && BBB.GetType() ==
"Fence" )
141 to = to +
"0 -1.3 0";
145 m_DebugPlugArrow = DrawArrow( from, to );
150 Shape DrawArrow(
vector from,
vector to,
float size = 0.5,
int color = 0xFFFFFFFF,
float flags = 0)
157 vector dir2 = dir.Perpend() * size;
162 pts[2] = to - dir1 - dir2;
163 pts[3] = to - dir1 + dir2;
166 return Shape.CreateLines(color, flags, pts, 5);
171 return m_ThisEntityAI;
175 override void Event_OnAwake()
177 string cfg_item =
"CfgVehicles " + m_ThisEntityAI.GetType();
178 string cfg_energy_manager = cfg_item +
" EnergyManager ";
181 m_EnergyUsage =
GetGame().ConfigGetFloat(cfg_energy_manager +
"energyUsagePerSecond");
182 bool switch_on =
GetGame().ConfigGetFloat(cfg_energy_manager +
"switchOnAtSpawn");
183 m_AutoSwitchOff =
GetGame().ConfigGetFloat(cfg_energy_manager +
"autoSwitchOff");
184 m_HasElectricityIcon =
GetGame().ConfigGetFloat(cfg_energy_manager +
"hasIcon");
185 m_AutoSwitchOffWhenInCargo =
GetGame().ConfigGetFloat(cfg_energy_manager +
"autoSwitchOffWhenInCargo");
187 m_EnergyAtSpawn =
GetGame().ConfigGetFloat(cfg_energy_manager +
"energyAtSpawn");
188 m_Energy = m_EnergyAtSpawn;
189 m_EnergyStorageMax =
GetGame().ConfigGetFloat(cfg_energy_manager +
"energyStorageMax");
190 m_ReduceMaxEnergyByDamageCoef =
GetGame().ConfigGetFloat(cfg_energy_manager +
"reduceMaxEnergyByDamageCoef");
191 m_SocketsCount =
GetGame().ConfigGetFloat(cfg_energy_manager +
"powerSocketsCount");
193 m_IsPassiveDevice =
GetGame().ConfigGetFloat(cfg_energy_manager +
"isPassiveDevice");
194 m_CordLength =
GetGame().ConfigGetFloat(cfg_energy_manager +
"cordLength");
195 m_PlugType =
GetGame().ConfigGetFloat(cfg_energy_manager +
"plugType");
197 m_AttachmentActionType =
GetGame().ConfigGetFloat(cfg_energy_manager +
"attachmentAction");
198 m_WetnessExposure =
GetGame().ConfigGetFloat(cfg_energy_manager +
"wetnessExposure");
200 float update_interval =
GetGame().ConfigGetFloat(cfg_energy_manager +
"updateInterval");
202 m_ConvertEnergyToQuantity =
GetGame().ConfigGetFloat(cfg_energy_manager +
"convertEnergyToQuantity");
206 float cfg_max_quantity =
GetGame().ConfigGetFloat (cfg_item +
" varQuantityMax");
208 if (m_ConvertEnergyToQuantity && cfg_max_quantity <= 0)
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!";
212 m_ConvertEnergyToQuantity =
false;
216 if (m_ConvertEnergyToQuantity)
218 if (!m_UpdateQuantityTimer)
221 m_UpdateQuantityTimer.Run( 0.3 ,
this,
"OnEnergyAdded", NULL,
false);
226 if ( update_interval <= 0 )
227 update_interval = DEFAULT_UPDATE_INTERVAL;
229 SetUpdateInterval( update_interval );
232 string cfg_check_energy_limit = cfg_energy_manager +
"energyStorageMax";
234 if ( !
GetGame().ConfigIsExisting (cfg_check_energy_limit) && m_Energy > 0 )
236 m_EnergyStorageMax = m_Energy;
240 string cfg_check_plug_types = cfg_energy_manager +
"compatiblePlugTypes";
242 if (
GetGame().ConfigIsExisting (cfg_check_plug_types) )
245 GetGame().ConfigGetIntArray(cfg_check_plug_types, m_CompatiblePlugTypes);
248 if (GetSocketsCount() > 0)
251 if ( m_CordLength < 0 )
254 string error_message_cord =
"Warning! " + m_ThisEntityAI.GetType() +
": config parameter 'cordLength' is less than 0! Cord length should not be negative!";
255 DPrint(error_message_cord);
258 if (GetSocketsCount() > 0)
262 string cfg_animation_sources =
"cfgVehicles " + m_ThisEntityAI.GetType() +
" " +
"AnimationSources ";
263 int animation_sources_count =
GetGame().ConfigGetChildrenCount(cfg_animation_sources);
265 for (
int i_selection = 0; i_selection < animation_sources_count; i_selection++)
269 GetGame().ConfigGetChildName(cfg_animation_sources, i_selection, selection);
270 m_DeviceByPlugSelection.Set(selection, NULL);
277 if ( m_SocketsCount > MAX_SOCKETS_COUNT )
279 m_SocketsCount = MAX_SOCKETS_COUNT;
280 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!";
281 DPrint(error_message_sockets);
284 m_Sockets[MAX_SOCKETS_COUNT];
286 GetGame().ConfigGetText(cfg_energy_manager +
"cordTextureFile", m_CordTextureFile);
293 for (
int i = 0; i <= GetSocketsCount(); ++i )
295 m_ThisEntityAI.HideSelection ( SOCKET_ + i.ToString() + _PLUGGED );
299 m_ShowSocketsInInventory =
false;
300 if ( GetSocketsCount() > 0 && IsPlugCompatible(
PLUG_COMMON_APPLIANCE) && m_ThisEntityAI.GetType() !=
"MetalWire" )
302 m_ShowSocketsInInventory =
true;
305 m_CanWork = HasEnoughStoredEnergy();
307 m_ThisEntityAI.HideSelection( SEL_CORD_PLUGGED );
310 #ifdef DIAG_DEVELOPER
311 GetGame().m_EnergyManagerArray.Insert(
this );
316 override int GetCompType()
322 void OnDeviceDestroyed()
324 bool was_working = m_ThisEntityAI.GetCompEM().IsWorking();
332 m_ThisEntityAI.OnWorkStop();
341 if ( !m_DebugUpdate )
344 if ( !m_DebugUpdate.IsRunning() )
345 m_DebugUpdate.Run(0.01,
this,
"DebugUpdate", NULL,
true);
349 if ( m_DebugPlugArrow )
351 m_DebugPlugArrow.Destroy();
352 m_DebugPlugArrow = NULL;
362 void SetDebugPlugs(
bool newVal )
364 m_DebugPlugs = newVal;
377 m_IsSwichedOnPreviousState = m_IsSwichedOn;
383 m_IsSwichedOn =
true;
390 WakeUpWholeBranch( m_ThisEntityAI );
395 GetGame().GameScript.CallFunction(m_ThisEntityAI,
"OnSwitchOn", NULL, 0);
401 GetGame().GameScript.CallFunction(m_ThisEntityAI,
"OnSwitchOn", NULL, 0);
408 m_IsSwichedOnPreviousState = m_IsSwichedOn;
412 if ( CanSwitchOff() )
414 m_IsSwichedOn =
false;
424 WakeUpWholeBranch( m_ThisEntityAI );
429 GetGame().GameScript.CallFunction(m_ThisEntityAI,
"OnSwitchOff", NULL, 0);
435 m_IsSwichedOn =
false;
436 GetGame().GameScript.CallFunction(m_ThisEntityAI,
"OnSwitchOff", NULL, 0);
441 void SetPassiveState(
bool state =
true)
443 m_IsPassiveDevice = state;
444 if ( !m_IsPassiveDevice )
451 void UnplugDevice(
EntityAI device_to_unplug)
455 int indexStart = GetPluggedDevicesCount() - 1;
456 bool deviceFound =
false;
458 for (
int i = indexStart; i >= 0; --i)
460 EntityAI plugged_device = GetPluggedDevices().Get(i);
462 if (plugged_device == device_to_unplug)
464 GetPluggedDevices().Remove(i);
472 int socket_ID = device_to_unplug.GetCompEM().GetMySocketID();
473 UnplugCordFromSocket(socket_ID);
474 device_to_unplug.GetCompEM().SetEnergySource(
null);
475 device_to_unplug.GetCompEM().DeviceUpdate();
476 device_to_unplug.GetCompEM().StartUpdates();
477 device_to_unplug.GetCompEM().WakeUpWholeBranch(m_ThisEntityAI);
479 if (m_DebugPlugs && m_DebugPlugArrow)
481 m_DebugPlugArrow.Destroy();
482 m_DebugPlugArrow =
null;
485 OnOwnSocketReleased(device_to_unplug);
486 device_to_unplug.GetCompEM().OnIsUnplugged(m_ThisEntityAI);
487 device_to_unplug.ShowSelection(SEL_CORD_FOLDED);
488 device_to_unplug.HideSelection(SEL_CORD_PLUGGED);
498 if (GetEnergySource())
500 GetEnergySource().GetCompEM().UnplugDevice(m_ThisEntityAI);
506 void UnplugAllDevices()
508 if ( GetPluggedDevices() )
510 int indexStart = GetPluggedDevicesCount() - 1;
511 for (
int i = indexStart; i >= 0; --i)
513 UnplugDevice(GetPluggedDevices().
Get(i));
519 void RestorePlugState(
bool state)
521 m_RestorePlugState = state;
525 void SetEnergy(
float new_energy)
529 m_ThisEntityAI.SetWeightDirty();
530 float old_energy = m_Energy;
531 m_Energy = new_energy;
533 if ( old_energy - GetEnergyUsage() <= 0 || (old_energy != new_energy &&
Math.Min(old_energy,new_energy) <= 0) )
541 void SetEnergy0To1(
float energy01)
543 SetEnergy(
Math.Lerp(0, GetEnergyMax(),energy01));
547 void UpdateSelections()
550 int slots_c = GetSocketsCount();
552 for (
int i = 0; i < slots_c; ++i )
554 EntityAI plug_owner = GetDeviceBySocketID(i);
558 string plugged_selection = SOCKET_ + (i+1).
ToString() + _PLUGGED;
559 string available_selection = SOCKET_ + (i+1).
ToString() + _AVAILABLE;
560 m_ThisEntityAI.ShowSelection ( plugged_selection );
561 m_ThisEntityAI.HideSelection ( available_selection );
562 string texture_path = plug_owner.GetCompEM().GetCordTextureFile();
563 int selection_index = m_ThisEntityAI.GetHiddenSelectionIndex( plugged_selection );
564 m_ThisEntityAI.SetObjectTexture(selection_index, texture_path );
568 m_ThisEntityAI.ShowSelection ( SOCKET_ + (i+1).ToString() + _AVAILABLE );
569 m_ThisEntityAI.HideSelection ( SOCKET_ + (i+1).ToString() + _PLUGGED );
574 if ( GetEnergySource() )
576 m_ThisEntityAI.ShowSelection ( SEL_CORD_PLUGGED );
577 m_ThisEntityAI.HideSelection ( SEL_CORD_FOLDED );
581 m_ThisEntityAI.ShowSelection ( SEL_CORD_FOLDED );
582 m_ThisEntityAI.HideSelection ( SEL_CORD_PLUGGED );
587 void UpdatePlugState()
589 if (m_ThisEntityAI.GetCompEM().GetEnergySource())
591 EntityAI player = m_ThisEntityAI.GetHierarchyRootPlayer();
596 vector playerPosition = player.GetPosition();
597 if (!IsEnergySourceAtReach(playerPosition, 5))
603 vector itemPosition = m_ThisEntityAI.GetPosition();
605 if (m_ThisEntityAI.GetHierarchyParent())
606 itemPosition = m_ThisEntityAI.GetHierarchyParent().GetPosition();
608 if (!IsEnergySourceAtReach(itemPosition))
615 void GetCompatiblePlugTypes(out
TIntArray IDs)
617 IDs = m_CompatiblePlugTypes;
621 void StoreEnergySourceIDs(
int b1,
int b2,
int b3,
int b4)
623 m_EnergySourceStorageIDb1 = b1;
624 m_EnergySourceStorageIDb2 = b2;
625 m_EnergySourceStorageIDb3 = b3;
626 m_EnergySourceStorageIDb4 = b4;
630 void SetEnergyMaxPristine(
float new_limit)
632 m_EnergyStorageMax = new_limit;
636 void SetCordLength(
float new_length )
638 m_CordLength = new_length;
642 void SetPlugType(
int new_type )
644 m_PlugType = new_type;
648 void SetAttachmentAction(
int new_action_type )
650 m_AttachmentActionType = new_action_type;
654 void SetEnergyUsage(
float new_usage )
656 m_EnergyUsage = new_usage;
660 void ResetEnergyUsage()
662 string cfg_energy_usage =
"CfgVehicles " + m_ThisEntityAI.GetType() +
" EnergyManager ";
663 m_EnergyUsage =
GetGame().ConfigGetFloat (cfg_energy_usage +
"energyUsagePerSecond");
667 void SetCordTextureFile(
string new_path )
669 m_CordTextureFile = new_path;
673 void SetEnergySourceClient(
EntityAI source )
675 SetEnergySource(source);
679 void SetDeviceBySocketID(
int id,
EntityAI plugged_device)
681 m_Sockets[id] = plugged_device;
686 void SetElectricityIconVisibility(
bool make_visible )
688 m_HasElectricityIcon = make_visible;
696 bool current_state = CanWork();
698 if (current_state != m_CanWork)
700 m_CanWork = current_state;
703 if ( m_ThisEntityAI && m_ThisEntityAI.GetHierarchyParent() && m_ThisEntityAI.GetHierarchyParent().GetCompEM() )
705 m_ThisEntityAI.GetHierarchyParent().GetCompEM().UpdateCanWork();
711 void HandleMoveInsideCargo(
EntityAI container)
713 if ( m_AutoSwitchOffWhenInCargo )
723 void SetUpdateInterval(
float value )
725 m_UpdateInterval = value;
729 bool GetRestorePlugState()
731 return m_RestorePlugState;
735 bool PlugThisInto(
EntityAI energy_source,
int socket_id = -1)
737 return energy_source.GetCompEM().PlugInDevice(m_ThisEntityAI, socket_id);
743 if ( !IsSwitchedOn() )
757 bool CanWork(
float test_energy = -1)
764 if (m_ThisEntityAI && m_ThisEntityAI.IsRuined())
770 float energy_usage = test_energy;
771 float gathered_energy = GetEnergy();
772 EntityAI energy_source = GetEnergySource();
774 if (energy_usage == -1)
776 energy_usage = GetEnergyUsage();
779 if ( !CheckWetness() )
784 if (gathered_energy <= 0 && energy_usage <= 0)
789 int cycle_limit = 500;
791 while ( gathered_energy < energy_usage )
800 DPrint(
"Energy Manager ERROR: The 'cycle_limit' safety break had to be activated to prevent possible game freeze. Dumping debug information...");
805 if (energy_source.GetCompEM())
826 if ( energy_source && energy_source != m_ThisEntityAI && !energy_source.IsRuined() && energy_source.GetCompEM() && energy_source.GetCompEM().IsSwitchedOn() && energy_source.GetCompEM().CheckWetness() )
828 gathered_energy = gathered_energy + energy_source.GetCompEM().GetEnergy();
829 energy_source = energy_source.GetCompEM().GetEnergySource();
845 return (m_ThisEntityAI.GetWet() <= 1-m_WetnessExposure);
856 return IsSwitchedOn();
860 bool GetPreviousSwitchState()
862 return m_IsSwichedOnPreviousState;
868 return m_IsSwichedOn;
883 return m_IsPassiveDevice;
894 bool ConsumeEnergy(
float amount)
896 return FindAndConsumeEnergy(m_ThisEntityAI, amount,
true);
906 bool HasEnoughStoredEnergy()
908 if ( GetEnergy() > GetEnergyUsage() )
917 bool HasFreeSocket(
int socket_id = -1 )
921 int plugged_devices = GetPluggedDevicesCount();
922 int plugged_devices_limit = GetSocketsCount();
924 if ( plugged_devices < plugged_devices_limit )
933 EntityAI device = GetDeviceBySocketID(socket_id);
947 bool IsPlugCompatible(
int plug_ID)
954 if ( m_CompatiblePlugTypes )
956 for (
int i = 0; i < m_CompatiblePlugTypes.Count(); i++ )
958 int plug_ID_to_Check = m_CompatiblePlugTypes.Get(i);
960 if ( plug_ID_to_Check == plug_ID )
976 bool CanReceivePlugFrom(
EntityAI device_to_plug )
980 if ( HasFreeSocket() && device_to_plug != m_ThisEntityAI)
982 if ( device_to_plug.GetCompEM().GetEnergySource() != m_ThisEntityAI)
984 if ( IsPlugCompatible(device_to_plug.GetCompEM().GetPlugType()) )
986 if ( device_to_plug.GetCompEM().IsEnergySourceAtReach( device_to_plug.GetPosition(), 0, m_ThisEntityAI.GetPosition() ) )
998 bool CanBePluggedInto(
EntityAI potential_energy_provider )
1000 return potential_energy_provider.GetCompEM().CanReceivePlugFrom( m_ThisEntityAI );
1004 bool HasElectricityIcon()
1006 return m_HasElectricityIcon;
1010 bool HasConversionOfEnergyToQuantity()
1012 return m_ConvertEnergyToQuantity;
1031 bool IsEnergySourceAtReach(
vector from_position,
float add_tolerance = 0,
vector override_source_position =
"-1 -1 -1" )
1033 if ( !IsPlugged() && override_source_position ==
"-1 -1 -1" )
1038 if ( GetCordLength() == 0 )
1046 if ( override_source_position ==
"-1 -1 -1" )
1048 EntityAI energy_source = GetEnergySource();
1053 source_pos = energy_source.GetPosition();
1054 distance =
vector.Distance( from_position, source_pos );
1058 source_pos = override_source_position;
1059 distance =
vector.Distance( from_position, source_pos );
1062 if (distance > GetCordLength() + add_tolerance)
1072 bool HasVisibleSocketsInInventory()
1074 return m_ShowSocketsInInventory;
1078 bool IsSelectionAPlug(
string selection_to_test )
1080 if ( GetPluggedDevices() )
1082 int socket_count = GetSocketsCount();
1084 for (
int i = socket_count; i >= 0; --i )
1086 string real_selection = SOCKET_ + i.ToString() +_PLUGGED;
1088 if ( selection_to_test == real_selection)
1102 int GetSocketsCount()
1104 return m_SocketsCount;
1114 int GetAttachmentAction()
1116 return m_AttachmentActionType;
1120 int GetEnergySourceStorageIDb1()
1122 return m_EnergySourceStorageIDb1;
1126 int GetEnergySourceStorageIDb2()
1128 return m_EnergySourceStorageIDb2;
1132 int GetEnergySourceStorageIDb3()
1134 return m_EnergySourceStorageIDb3;
1138 int GetEnergySourceStorageIDb4()
1140 return m_EnergySourceStorageIDb4;
1144 int GetEnergySourceNetworkIDLow()
1146 return m_EnergySourceNetworkIDLow;
1150 int GetEnergySourceNetworkIDHigh()
1152 return m_EnergySourceNetworkIDHigh;
1156 int GetPluggedDevicesCount()
1158 if ( GetPluggedDevices() )
1160 return GetPluggedDevices().Count();
1167 int GetEnergy0To100()
1169 if ( m_EnergyStorageMax > 0 )
1171 int coef =
Math.Round( m_Energy / m_EnergyStorageMax * 100 );
1179 float GetEnergy0To1()
1181 if ( m_EnergyStorageMax > 0 )
1183 return m_Energy / m_EnergyStorageMax;
1190 float GetUpdateInterval()
1192 #ifdef DIAG_DEVELOPER
1193 if (FeatureTimeAccel.GetFeatureTimeAccelEnabled(ETimeAccelCategories.ENERGY_CONSUMPTION) || (FeatureTimeAccel.GetFeatureTimeAccelEnabled(ETimeAccelCategories.ENERGY_RECHARGE)))
1198 return m_UpdateInterval;
1202 float GetWetnessExposure()
1204 return m_WetnessExposure;
1208 float GetEnergyUsage()
1210 return m_EnergyUsage;
1220 float AddEnergy(
float added_energy)
1222 if (added_energy != 0)
1225 #ifdef DIAG_DEVELOPER
1226 if (FeatureTimeAccel.GetFeatureTimeAccelEnabled(ETimeAccelCategories.ENERGY_CONSUMPTION) && added_energy < 0)
1228 float timeAccel = FeatureTimeAccel.GetFeatureTimeAccelValue();
1229 added_energy *= timeAccel;
1233 bool energy_was_added = (added_energy > 0);
1235 float energy_to_clamp = GetEnergy() + added_energy;
1236 float clamped_energy =
Math.Clamp( energy_to_clamp, 0, GetEnergyMax() );
1237 SetEnergy(clamped_energy);
1240 if (energy_was_added)
1245 return energy_to_clamp - clamped_energy;
1252 float GetEnergyMax()
1254 float max_health = 0;
1256 if ( m_ThisEntityAI.HasDamageSystem() )
1257 max_health = m_ThisEntityAI.GetMaxHealth(
"",
"");
1261 if ( max_health == 0 || m_ReduceMaxEnergyByDamageCoef == 0 )
1262 return GetEnergyMaxPristine();
1267 health = m_ThisEntityAI.GetHealth(
"",
"");
1269 float damage_coef = 1 - (health / max_health);
1271 return GetEnergyMaxPristine() * (1 - ( damage_coef * m_ReduceMaxEnergyByDamageCoef ) );
1275 float GetEnergyMaxPristine()
1277 return m_EnergyStorageMax;
1280 float GetEnergyAtSpawn()
1282 return m_EnergyAtSpawn;
1286 float GetCordLength()
1288 return m_CordLength;
1294 return m_EnergySource;
1298 EntityAI GetDeviceBySocketID(
int id)
1300 return m_Sockets[id];
1304 EntityAI GetPlugOwner(
string plug_selection_name)
1306 if ( m_DeviceByPlugSelection.Contains(plug_selection_name) )
1308 return m_DeviceByPlugSelection.Get(plug_selection_name);
1317 if ( GetPluggedDevicesCount() > 0 )
1319 return GetPluggedDevices().Get(0);
1326 string GetCordTextureFile()
1328 return m_CordTextureFile;
1334 return m_PluggedDevices;
1341 int plugged_devices_c = GetPluggedDevicesCount();
1342 for (
int i = 0; i < plugged_devices_c; ++i )
1344 EntityAI device = GetPluggedDevices().Get(i);
1345 if ( IsSwitchedOn() )
1347 return_array.Insert(device);
1351 return return_array;
1360 void OnWork(
float consumed_energy )
1362 m_ThisEntityAI.OnWork(consumed_energy);
1366 void OnIsPlugged(
EntityAI source_device)
1373 if (!m_DebugUpdate.IsRunning())
1374 m_DebugUpdate.Run(0.01,
this,
"DebugUpdate", NULL,
true);
1378 m_ThisEntityAI.OnIsPlugged(source_device);
1382 void OnIsUnplugged(
EntityAI last_energy_source )
1385 m_ThisEntityAI.OnIsUnplugged( last_energy_source );
1389 void OnOwnSocketTaken(
EntityAI device )
1395 m_ThisEntityAI.PlaySoundSet( sound_plug,
"cablereel_plugin_SoundSet", 0, 0 );
1398 m_ThisEntityAI.OnOwnSocketTaken(device);
1402 void OnOwnSocketReleased(
EntityAI device )
1408 m_ThisEntityAI.PlaySoundSet( sound_unplug,
"cablereel_unplug_SoundSet", 0, 0 );
1411 m_ThisEntityAI.OnOwnSocketReleased( device );
1416 void OnAttachmentAdded(
EntityAI elec_device)
1418 int attachment_action_type = GetAttachmentAction();
1422 if ( elec_device.GetCompEM().CanReceivePlugFrom( m_ThisEntityAI ) )
1424 PlugThisInto(elec_device);
1429 elec_device.GetCompEM().PlugThisInto(m_ThisEntityAI);
1434 void OnAttachmentRemoved(
EntityAI elec_device)
1436 int attachment_action_type = GetAttachmentAction();
1440 if ( elec_device == GetEnergySource() )
1447 elec_device.GetCompEM().UnplugThis();
1454 if (!m_IsPassiveDevice)
1461 m_UpdateTimer.Run(GetUpdateInterval(),
this,
"DeviceUpdate",
null,
true);
1467 void OnEnergyConsumed()
1469 m_ThisEntityAI.OnEnergyConsumed();
1473 void OnEnergyAdded()
1475 if (m_UpdateQuantityTimer)
1477 m_UpdateQuantityTimer.Stop();
1478 m_UpdateQuantityTimer = NULL;
1481 m_ThisEntityAI.OnEnergyAdded();
1490 protected void StopUpdates()
1502 void InteractBranch(
EntityAI originalCaller, Man player =
null,
int system = 0)
1504 OnInteractBranch(originalCaller, player, system);
1505 if ( GetSocketsCount() > 0 )
1509 foreach (
EntityAI device : devices)
1511 if ( device != originalCaller )
1513 device.GetCompEM().InteractBranch( originalCaller, player, system );
1520 protected void OnInteractBranch(
EntityAI originalCaller, Man player,
int system)
1522 m_ThisEntityAI.IncreaseLifetime();
1527 protected void WakeUpWholeBranch(
EntityAI original_caller )
1529 if ( GetSocketsCount() > 0 )
1532 int plugged_devices_c = plugged_devices.Count();
1534 for (
int i = 0; i < plugged_devices_c; ++i )
1536 EntityAI device = plugged_devices.Get(i);
1537 if ( device != original_caller )
1539 device.GetCompEM().UpdateCanWork();
1540 device.GetCompEM().DeviceUpdate();
1541 device.GetCompEM().StartUpdates();
1542 device.GetCompEM().WakeUpWholeBranch( original_caller );
1550 protected void PlugCordIntoSocket(
EntityAI device_to_plug,
int socket_id = -1 )
1554 EntityAI plug_owner_by_socket = GetDeviceBySocketID(socket_id);
1556 if (!plug_owner_by_socket)
1558 UpdateSocketSelections(socket_id, device_to_plug);
1563 int slots_c = GetSocketsCount();
1565 for (
int i = 0; i < slots_c; ++i )
1567 EntityAI plug_owner = GetDeviceBySocketID(i);
1571 UpdateSocketSelections(i, device_to_plug);
1578 protected void UpdateSocketSelections(
int socket_id,
EntityAI device_to_plug)
1580 SetDeviceBySocketID(socket_id, device_to_plug);
1582 string plugged_selection = SOCKET_ + (socket_id+1).
ToString() + _PLUGGED;
1583 SetPlugOwner( plugged_selection, device_to_plug );
1584 m_ThisEntityAI.ShowSelection ( plugged_selection );
1586 string unplugged_selection = SOCKET_ + (socket_id+1).
ToString() + _AVAILABLE;
1587 m_ThisEntityAI.HideSelection ( unplugged_selection );
1588 string texture_path = device_to_plug.GetCompEM().GetCordTextureFile();
1589 int selection_index = m_ThisEntityAI.GetHiddenSelectionIndex( plugged_selection );
1590 m_ThisEntityAI.SetObjectTexture( selection_index, texture_path );
1591 device_to_plug.GetCompEM().SetMySocketID(socket_id);
1596 protected void SetEnergySource(
EntityAI source )
1598 m_EnergySource = source;
1607 m_IsPlugged =
false;
1608 m_EnergySourceNetworkIDLow = -1;
1609 m_EnergySourceNetworkIDHigh = -1;
1613 m_EnergySource.GetNetworkID(m_EnergySourceNetworkIDLow, m_EnergySourceNetworkIDHigh);
1619 protected bool PlugInDevice(
EntityAI device_to_plug,
int socket_id = -1)
1621 if (CanReceivePlugFrom(device_to_plug))
1623 device_to_plug.IncreaseLifetime();
1624 InteractBranch(m_ThisEntityAI);
1625 if (device_to_plug.GetCompEM().IsPlugged())
1626 device_to_plug.GetCompEM().UnplugThis();
1628 GetPluggedDevices().Insert(device_to_plug);
1629 device_to_plug.GetCompEM().SetEnergySource(m_ThisEntityAI);
1631 PlugCordIntoSocket(device_to_plug, socket_id);
1632 OnOwnSocketTaken(device_to_plug);
1634 device_to_plug.GetCompEM().OnIsPlugged(m_ThisEntityAI);
1635 WakeUpWholeBranch( m_ThisEntityAI );
1639 device_to_plug.HideSelection(SEL_CORD_FOLDED);
1640 device_to_plug.ShowSelection(SEL_CORD_PLUGGED);
1650 protected void SetPlugOwner(
string selection_name,
EntityAI device)
1652 if ( m_DeviceByPlugSelection.Contains(selection_name) )
1654 m_DeviceByPlugSelection.Set(selection_name, device);
1660 protected void UnplugCordFromSocket(
int socket_to_unplug_ID )
1662 EntityAI plug_owner = GetDeviceBySocketID(socket_to_unplug_ID);
1666 SetDeviceBySocketID(socket_to_unplug_ID, NULL);
1667 string unplugged_selection = SOCKET_ + (socket_to_unplug_ID+1).
ToString() + _AVAILABLE;
1668 m_ThisEntityAI.ShowSelection ( unplugged_selection );
1670 string plugged_selection = SOCKET_ + (socket_to_unplug_ID+1).
ToString() + _PLUGGED;
1671 m_ThisEntityAI.HideSelection ( plugged_selection );
1672 SetPlugOwner( plugged_selection, NULL );
1673 plug_owner.GetCompEM().SetMySocketID(-1);
1678 protected void SetPowered(
bool state )
1680 m_IsWorking = state;
1684 protected bool FindAndConsumeEnergy(
EntityAI original_caller,
float amount,
bool ignore_switch_state =
false)
1686 if ( (ignore_switch_state || IsSwitchedOn()) && !m_ThisEntityAI.IsRuined() )
1688 float available_energy = AddEnergy(-amount);
1690 if ( available_energy < 0 && IsPlugged() )
1693 EntityAI next_power_source = GetEnergySource();
1695 if (next_power_source && next_power_source != original_caller)
1697 return next_power_source.GetCompEM().FindAndConsumeEnergy( original_caller, -available_energy );
1701 if ( available_energy >= 0)
1715 protected int GetMySocketID()
1717 return m_MySocketID;
1721 protected void SetMySocketID(
int slot_ID )
1723 m_MySocketID = slot_ID;
1728 m_ThisEntityAI.SetSynchDirty();
1731 void ClearLastUpdateTime()
1733 m_LastUpdateTime = 0;
1736 void RememberLastUpdateTime()
1738 m_LastUpdateTime = GetCurrentUpdateTime();
1741 float GetCurrentUpdateTime()
1755 if ( !m_IsPassiveDevice )
1758 if ( m_ThisEntityAI &&
this && IsSwitchedOn() && !m_ThisEntityAI.IsRuined() && CheckWetness() && m_CanWork && !
GetGame().IsMissionMainMenu() )
1760 bool was_powered = IsWorking();
1761 float consumed_energy_coef;
1764 if ( m_LastUpdateTime == 0 )
1766 RememberLastUpdateTime();
1767 consumed_energy_coef = 1.0;
1771 float updatetime = GetCurrentUpdateTime();
1772 float time = updatetime - m_LastUpdateTime;
1773 consumed_energy_coef = time / 1000;
1776 if (consumed_energy_coef > 0)
1778 m_LastUpdateTime = GetCurrentUpdateTime();
1779 float consume_energy = GetEnergyUsage() * consumed_energy_coef;
1780 bool has_consumed_enough =
true;
1783 has_consumed_enough = ConsumeEnergy( consume_energy );
1785 SetPowered( has_consumed_enough );
1787 if ( has_consumed_enough )
1791 m_CanStopWork =
true;
1792 WakeUpWholeBranch(m_ThisEntityAI);
1793 GetGame().GameScript.CallFunction(m_ThisEntityAI,
"OnWorkStart", NULL, 0);
1797 OnWork( consume_energy );
1805 m_CanStopWork =
false;
1806 ClearLastUpdateTime();
1807 GetGame().GameScript.CallFunction(m_ThisEntityAI,
"OnWorkStop", NULL, 0);
1810 if (m_AutoSwitchOff)
1822 ClearLastUpdateTime();
1825 else if (
this && m_ThisEntityAI)
1827 SetPowered(
false );
1832 m_CanStopWork =
false;
1833 ClearLastUpdateTime();
1834 GetGame().GameScript.CallFunction(m_ThisEntityAI,
"OnWorkStop", NULL, 0);
1837 if (m_AutoSwitchOff)