powergenerator.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. class PowerGeneratorBase extends ItemBase
  2. {
  3. float m_Fuel;
  4. private static float m_FuelTankCapacity; // Capacity in ml.
  5. private static float m_FuelToEnergyRatio; // Conversion ratio of 1 ml of fuel to X Energy
  6. private int m_FuelPercentage;
  7. protected const float LOW_ENERGY_FUEL_PERCENTAGE = 20; // how much % of fuel has to remain to trigger low fuel state
  8. static const string START_SOUND = "powerGeneratorTurnOn_SoundSet";
  9. static const string LOOP_SOUND = "powerGeneratorLoop_SoundSet";
  10. protected const string LOOP_LOW_FUEL_SOUND = "powerGenerator_low_Fuel_Loop_SoundSet";
  11. static const string STOP_SOUND = "powerGeneratorTurnOff_SoundSet";
  12. static const string SPARKPLUG_ATTACH_SOUND = "sparkplug_attach_SoundSet";
  13. static const string SPARKPLUG_DETACH_SOUND = "sparkplug_detach_SoundSet";
  14. protected bool m_IsLowEnergy;
  15. protected EffectSound m_EngineLoop;
  16. protected EffectSound m_EngineStart;
  17. protected EffectSound m_EngineStop;
  18. ref Timer m_SoundLoopStartTimer;
  19. ref protected Effect m_Smoke;
  20. ItemBase m_SparkPlug; //! DEPRECATED Attached spark plug item
  21. protected ref UniversalTemperatureSource m_UTSource;
  22. protected ref UniversalTemperatureSourceSettings m_UTSSettings;
  23. protected ref UniversalTemperatureSourceLambdaConstant m_UTSLEngine;
  24. // Constructor
  25. void PowerGeneratorBase()
  26. {
  27. SetEventMask(EntityEvent.INIT); // Enable EOnInit event
  28. m_FuelPercentage = 50;
  29. RegisterNetSyncVariableInt("m_FuelPercentage");
  30. }
  31. void ~PowerGeneratorBase()
  32. {
  33. SEffectManager.DestroyEffect(m_Smoke);
  34. }
  35. override void EEInit()
  36. {
  37. super.EEInit();
  38. if (GetGame().IsServer() || !GetGame().IsMultiplayer())
  39. {
  40. m_UTSSettings = new UniversalTemperatureSourceSettings();
  41. m_UTSSettings.m_ManualUpdate = true;
  42. m_UTSSettings.m_TemperatureItemCap = GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_MIDDLE;
  43. m_UTSSettings.m_TemperatureCap = 8;
  44. m_UTSSettings.m_RangeFull = 1;
  45. m_UTSSettings.m_RangeMax = 2.5;
  46. m_UTSLEngine = new UniversalTemperatureSourceLambdaConstant();
  47. m_UTSource = new UniversalTemperatureSource(this, m_UTSSettings, m_UTSLEngine);
  48. }
  49. }
  50. override void EOnInit(IEntity other, int extra)
  51. {
  52. if (GetGame().IsServer())
  53. {
  54. m_FuelPercentage = GetCompEM().GetEnergy0To100();
  55. SetSynchDirty();
  56. }
  57. UpdateFuelMeter();
  58. }
  59. override float GetLiquidThroughputCoef()
  60. {
  61. return LIQUID_THROUGHPUT_GENERATOR;
  62. }
  63. protected vector GetSmokeParticlePosition()
  64. {
  65. return "0.3 0.21 0.4";
  66. }
  67. protected vector GetSmokeParticleOrientation()
  68. {
  69. return "270 0 0";
  70. }
  71. // Play the loop sound
  72. void StartLoopSound()
  73. {
  74. if (GetGame().IsClient() || !GetGame().IsMultiplayer())
  75. {
  76. if (GetCompEM().IsWorking())
  77. {
  78. if (m_IsLowEnergy)
  79. PlaySoundSetLoop(m_EngineLoop, LOOP_LOW_FUEL_SOUND, 0.3, 0.3);
  80. else
  81. PlaySoundSetLoop(m_EngineLoop, LOOP_SOUND, 0.3, 0.3);
  82. // Particle
  83. m_Smoke = new EffGeneratorSmoke();
  84. SEffectManager.PlayOnObject(m_Smoke, this, GetSmokeParticlePosition(), GetSmokeParticleOrientation());
  85. }
  86. }
  87. }
  88. // Taking item into inventory
  89. override bool CanPutInCargo( EntityAI parent )
  90. {
  91. if (!super.CanPutInCargo(parent))
  92. {
  93. return false;
  94. }
  95. return CanManipulate();
  96. }
  97. // Taking item into inventory
  98. override bool CanPutIntoHands(EntityAI parent)
  99. {
  100. if(!super.CanPutIntoHands(parent))
  101. {
  102. return false;
  103. }
  104. return CanManipulate();
  105. }
  106. // Returns true/false if this item can be moved into inventory/hands
  107. bool CanManipulate()
  108. {
  109. return GetCompEM().GetPluggedDevicesCount() == 0 && !GetCompEM().IsWorking();
  110. }
  111. /*===================================
  112. EVENTS
  113. ===================================*/
  114. // Init
  115. override void OnInitEnergy()
  116. {
  117. m_FuelTankCapacity = GetGame().ConfigGetFloat ("CfgVehicles " + GetType() + " fuelTankCapacity");
  118. m_FuelToEnergyRatio = GetCompEM().GetEnergyMax() / m_FuelTankCapacity; // Conversion ratio of 1 ml of fuel to X Energy
  119. UpdateFuelMeter();
  120. }
  121. // Generator is working
  122. override void OnWorkStart()
  123. {
  124. if (GetGame().IsClient() || !GetGame().IsMultiplayer())
  125. {
  126. if (IsInitialized())
  127. {
  128. PlaySoundSet(m_EngineStart, START_SOUND, 0, 0);
  129. }
  130. if (!m_SoundLoopStartTimer)
  131. {
  132. m_SoundLoopStartTimer = new Timer(CALL_CATEGORY_SYSTEM);
  133. }
  134. if (!m_SoundLoopStartTimer.IsRunning()) // Makes sure the timer is NOT running already
  135. {
  136. m_SoundLoopStartTimer.Run(1.5, this, "StartLoopSound", NULL, false);
  137. }
  138. }
  139. if (GetGame().IsServer() || !GetGame().IsMultiplayer())
  140. {
  141. m_UTSource.SetDefferedActive(true, 20.0);
  142. }
  143. }
  144. // Do work
  145. override void OnWork(float consumed_energy)
  146. {
  147. if (GetGame().IsServer() || !GetGame().IsMultiplayer())
  148. {
  149. m_UTSource.Update(m_UTSSettings, m_UTSLEngine);
  150. }
  151. if (GetGame().IsServer())
  152. {
  153. m_FuelPercentage = GetCompEM().GetEnergy0To100();
  154. SetSynchDirty();
  155. }
  156. if (m_FuelPercentage < LOW_ENERGY_FUEL_PERCENTAGE && !m_IsLowEnergy)
  157. SetLowEnergyState(true);
  158. else if (m_FuelPercentage >= LOW_ENERGY_FUEL_PERCENTAGE && m_IsLowEnergy)
  159. SetLowEnergyState(false);
  160. UpdateFuelMeter();
  161. }
  162. // Turn off when this runs out of fuel
  163. override void OnWorkStop()
  164. {
  165. if (GetGame().IsClient() || !GetGame().IsMultiplayer())
  166. {
  167. // Sound
  168. PlaySoundSet(m_EngineStop, STOP_SOUND, 0, 0);
  169. StopSoundSet(m_EngineLoop);
  170. // particle
  171. SEffectManager.DestroyEffect(m_Smoke);
  172. // Fuel meter
  173. UpdateFuelMeter();
  174. }
  175. if (GetGame().IsServer() || !GetGame().IsMultiplayer())
  176. {
  177. m_UTSource.SetDefferedActive(false, 20.0);
  178. }
  179. }
  180. // Called when this generator is picked up
  181. override void OnItemLocationChanged(EntityAI old_owner, EntityAI new_owner)
  182. {
  183. super.OnItemLocationChanged(old_owner, new_owner);
  184. UpdateFuelMeter();
  185. }
  186. override void EEItemAttached(EntityAI item, string slot_name)
  187. {
  188. super.EEItemAttached(item, slot_name);
  189. GetCompEM().InteractBranch(this);
  190. ItemBase item_IB = ItemBase.Cast(item);
  191. if (item_IB.IsKindOf("Sparkplug") && IsInitialized())
  192. {
  193. ShowSelection("sparkplug_installed");
  194. #ifndef SERVER
  195. EffectSound sound = SEffectManager.PlaySound(SPARKPLUG_ATTACH_SOUND, GetPosition());
  196. sound.SetAutodestroy( true );
  197. #endif
  198. }
  199. }
  200. override void EEItemDetached(EntityAI item, string slot_name)
  201. {
  202. super.EEItemDetached(item, slot_name);
  203. GetCompEM().InteractBranch(this);
  204. ItemBase item_IB = ItemBase.Cast(item);
  205. if (item_IB.IsKindOf("Sparkplug"))
  206. {
  207. HideSelection("sparkplug_installed");
  208. GetCompEM().SwitchOff();
  209. #ifndef SERVER
  210. EffectSound sound = SEffectManager.PlaySound(SPARKPLUG_DETACH_SOUND, GetPosition());
  211. sound.SetAutodestroy(true);
  212. #endif
  213. }
  214. }
  215. /*================================
  216. FUNCTIONS
  217. ================================*/
  218. protected void SetLowEnergyState(bool state)
  219. {
  220. m_IsLowEnergy = state;
  221. if (GetGame().IsClient() || !GetGame().IsMultiplayer())
  222. {
  223. StopSoundSet(m_EngineLoop);
  224. StartLoopSound();
  225. }
  226. }
  227. void UpdateFuelMeter()
  228. {
  229. if (GetGame().IsClient() || !GetGame().IsMultiplayer())
  230. {
  231. SetAnimationPhase("dial_fuel", m_FuelPercentage * 0.01);
  232. }
  233. }
  234. // Adds energy to the generator
  235. void SetFuel(float fuel_amount)
  236. {
  237. // clamp
  238. if (GetFuel() == 0.0 && fuel_amount <= 0.0)
  239. return;
  240. if (m_FuelTankCapacity > 0)
  241. {
  242. m_FuelToEnergyRatio = GetCompEM().GetEnergyMax() / m_FuelTankCapacity;
  243. GetCompEM().SetEnergy(fuel_amount * m_FuelToEnergyRatio);
  244. m_FuelPercentage = GetCompEM().GetEnergy0To100();
  245. SetSynchDirty();
  246. UpdateFuelMeter();
  247. }
  248. else
  249. {
  250. string error = string.Format("ERROR! Item %1 has fuel tank with 0 capacity! Add parameter 'fuelTankCapacity' to its config and set it to more than 0!", this.GetType());
  251. DPrint(error);
  252. }
  253. }
  254. // Adds fuel (energy) to the generator
  255. // Returns how much fuel was accepted
  256. float AddFuel(float available_fuel)
  257. {
  258. if (available_fuel == 0.0)
  259. return 0.0;
  260. GetCompEM().InteractBranch(this);
  261. float needed_fuel = GetMaxFuel() - GetFuel();
  262. if (needed_fuel > available_fuel)
  263. {
  264. SetFuel(GetFuel() + available_fuel);
  265. return available_fuel; // Return used fuel amount
  266. }
  267. else
  268. {
  269. SetFuel(GetMaxFuel());
  270. return needed_fuel;
  271. }
  272. }
  273. // Check the bottle if it can be used to fill the tank
  274. bool CanAddFuel(ItemBase container)
  275. {
  276. if (container)
  277. {
  278. // Get the liquid
  279. int liquid_type = container.GetLiquidType();
  280. // Do all checks
  281. if ( container.GetQuantity() > 0 && GetCompEM().GetEnergy() < GetCompEM().GetEnergyMax() && (liquid_type & LIQUID_GASOLINE))
  282. {
  283. return true;
  284. }
  285. }
  286. return false;
  287. }
  288. // Returns fuel amount
  289. float GetFuel()
  290. {
  291. return Math.Clamp(GetCompEM().GetEnergy() / m_FuelToEnergyRatio, 0.0, GetMaxFuel());
  292. }
  293. // Returns max fuel amount
  294. float GetMaxFuel()
  295. {
  296. return m_FuelTankCapacity;
  297. }
  298. float GetFuelPercentage()
  299. {
  300. return m_FuelPercentage;
  301. }
  302. // Checks sparkplug
  303. bool HasSparkplug()
  304. {
  305. int slot = InventorySlots.GetSlotIdFromString("SparkPlug");
  306. EntityAI ent = GetInventory().FindAttachment(slot);
  307. return ent && !ent.IsRuined();
  308. }
  309. override void OnVariablesSynchronized()
  310. {
  311. super.OnVariablesSynchronized();
  312. UpdateFuelMeter();
  313. }
  314. //================================================================
  315. // ADVANCED PLACEMENT
  316. //================================================================
  317. override string GetDeploySoundset()
  318. {
  319. return "placePowerGenerator_SoundSet";
  320. }
  321. override void SetActions()
  322. {
  323. super.SetActions();
  324. AddAction(ActionTogglePlaceObject);
  325. AddAction(ActionPullOutPlug);
  326. AddAction(ActionTurnOnPowerGenerator);
  327. AddAction(ActionTurnOffPowerGenerator);
  328. AddAction(ActionPlaceObject);
  329. }
  330. //Debug menu Spawn Ground Special
  331. override void OnDebugSpawn()
  332. {
  333. EntityAI entity;
  334. if (Class.CastTo(entity, this))
  335. {
  336. entity.GetInventory().CreateInInventory("SparkPlug");
  337. }
  338. SetFuel(GetMaxFuel());
  339. }
  340. override void GetDebugActions(out TSelectableActionInfoArrayEx outputList)
  341. {
  342. outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "PowerGenerator Fuel", FadeColors.RED));
  343. outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.GENERIC_FUEL_FULL, "Full", FadeColors.LIGHT_GREY));
  344. outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.GENERIC_FUEL_EMPTY, "Empty", FadeColors.LIGHT_GREY));
  345. outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.GENERIC_FUEL_INCREASE, "10% increase", FadeColors.LIGHT_GREY));
  346. outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.GENERIC_FUEL_DECREASE, "10% decrease", FadeColors.LIGHT_GREY));
  347. outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
  348. super.GetDebugActions(outputList);
  349. }
  350. override bool OnAction(int action_id, Man player, ParamsReadContext ctx)
  351. {
  352. if (super.OnAction(action_id, player, ctx))
  353. return true;
  354. if (!GetGame().IsServer())
  355. return false;
  356. switch (action_id)
  357. {
  358. case EActions.GENERIC_FUEL_FULL:
  359. SetFuel(GetMaxFuel());
  360. return true;
  361. case EActions.GENERIC_FUEL_EMPTY:
  362. SetFuel(0);
  363. return true;
  364. case EActions.GENERIC_FUEL_INCREASE:
  365. AddFuel(Math.Clamp(GetMaxFuel() * 0.1, 0.0, GetMaxFuel()));
  366. return true;
  367. case EActions.GENERIC_FUEL_DECREASE:
  368. float value = GetMaxFuel() * -0.1;
  369. if (value <= 0)
  370. SetFuel(0.0);
  371. return true;
  372. AddFuel(value);
  373. return true;
  374. }
  375. return false;
  376. }
  377. }
  378. class PowerGenerator extends PowerGeneratorBase {}