powergenerator.c 11 KB

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