torch.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008
  1. class FlammableBase : ItemBase
  2. {
  3. void FlammableBase()
  4. {
  5. Init();
  6. }
  7. private SoundOnVehicle m_LoopSoundEntity;
  8. Particle m_FireParticle;
  9. bool m_CanReceiveUpgrade; // Synchronized variable
  10. bool m_IsBeingDestructed = false;
  11. float m_BurnTimePerRagEx;
  12. float m_BurnTimePerFullLardEx;
  13. float m_BurnTimePerFullFuelDoseEx;
  14. float m_MaxConsumableLardQuantityEx;
  15. float m_MaxConsumableFuelQuantityEx;
  16. float m_WaterEvaporationByFireIntensityEx = 0.001;
  17. int m_StartFadeOutOfLightAtQuantityEx = 3;
  18. int m_RagsUpgradedCount;//how many rags were upgraded with fuel/lard
  19. bool m_ConsumeRagFlipFlop;//are we burning rag or fuel/lard
  20. vector m_ParticleLocalPos = Vector(0, 0.50, 0);
  21. string m_DecraftResult = "WoodenStick";
  22. TorchLight m_Light;
  23. bool m_WasLit;//was this item ever lit ? (used for correct material setting after reconnect for extinguished flammable items)
  24. protected ref UniversalTemperatureSource m_UTSource;
  25. protected ref UniversalTemperatureSourceSettings m_UTSSettings;
  26. protected ref UniversalTemperatureSourceLambdaConstant m_UTSLConstant;
  27. override void DeferredInit()
  28. {
  29. if(m_RagsUpgradedCount)
  30. {
  31. LockRags(true);
  32. }
  33. }
  34. void Init()
  35. {
  36. if ( m_BurnTimePerRagEx == 0 || m_BurnTimePerFullLardEx == 0 || m_MaxConsumableLardQuantityEx == 0 || m_MaxConsumableFuelQuantityEx == 0 )
  37. {
  38. string cfg_path = "CfgVehicles " + GetType();
  39. m_BurnTimePerRagEx = GetGame().ConfigGetFloat( cfg_path + " burnTimePerRag" );
  40. m_BurnTimePerFullLardEx = GetGame().ConfigGetFloat( cfg_path + " burnTimePerFullLardDose" );
  41. m_BurnTimePerFullFuelDoseEx = GetGame().ConfigGetFloat( cfg_path + " burnTimePerFullFuelDose" );
  42. m_MaxConsumableLardQuantityEx = GetGame().ConfigGetFloat( cfg_path + " maxConsumableLardDose" );
  43. m_MaxConsumableFuelQuantityEx = GetGame().ConfigGetFloat( cfg_path + " maxConsumableFuelDose" );
  44. }
  45. RegisterNetSyncVariableBool("m_CanReceiveUpgrade");
  46. }
  47. override void EEInit()
  48. {
  49. super.EEInit();
  50. if (GetGame().IsServer() || !GetGame().IsMultiplayer())
  51. {
  52. m_UTSSettings = new UniversalTemperatureSourceSettings();
  53. m_UTSSettings.m_Updateable = true;
  54. m_UTSSettings.m_UpdateInterval = 1;
  55. m_UTSSettings.m_TemperatureItemCap = GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_MIDDLE;
  56. m_UTSSettings.m_TemperatureCap = 5;
  57. m_UTSSettings.m_RangeFull = 0.5;
  58. m_UTSSettings.m_RangeMax = 1;
  59. m_UTSLConstant = new UniversalTemperatureSourceLambdaConstant();
  60. m_UTSource = new UniversalTemperatureSource(this, m_UTSSettings, m_UTSLConstant);
  61. }
  62. }
  63. override vector GetUniversalTemperatureSourcePosition()
  64. {
  65. if (GetHierarchyRoot())
  66. {
  67. return GetHierarchyRoot().GetPosition();
  68. }
  69. return super.GetPosition();
  70. }
  71. override void EEDelete(EntityAI parent)
  72. {
  73. super.EEDelete(parent);
  74. if ( m_LoopSoundEntity != NULL && GetGame() != NULL )
  75. {
  76. GetGame().ObjectDelete( m_LoopSoundEntity );
  77. }
  78. StopAllParticles();
  79. }
  80. override bool CanReceiveAttachment(EntityAI attachment, int slotId)
  81. {
  82. ItemBase att = ItemBase.Cast(GetInventory().FindAttachment(slotId));
  83. if (att && att.IsFullQuantity())
  84. return false;
  85. return super.CanReceiveAttachment(attachment, slotId);
  86. }
  87. override bool CanPutInCargo( EntityAI parent )
  88. {
  89. if( !super.CanPutInCargo(parent) ) {return false;}
  90. return CanBeTakenAsCargo();
  91. }
  92. override bool CanReleaseAttachment(EntityAI attachment)
  93. {
  94. if( !super.CanReleaseAttachment( attachment ) )
  95. return false;
  96. return !GetCompEM().IsWorking();
  97. }
  98. override bool CanRemoveFromCargo(EntityAI parent)
  99. {
  100. return CanBeTakenAsCargo();
  101. }
  102. override bool CanPutAsAttachment (EntityAI parent)
  103. {
  104. return !GetCompEM().IsWorking();
  105. }
  106. bool CanBeTakenAsCargo()
  107. {
  108. // Don't let players burn their pockets!
  109. return !GetCompEM().IsWorking();
  110. }
  111. override bool IsIgnited()
  112. {
  113. return GetCompEM().IsWorking();
  114. }
  115. override bool CanIgniteItem(EntityAI ignite_target = NULL)
  116. {
  117. return GetCompEM().IsWorking();
  118. }
  119. override bool HasFlammableMaterial()
  120. {
  121. return true;
  122. }
  123. // Checkes if Torch can be ignited
  124. override bool CanBeIgnitedBy(EntityAI igniter = NULL)
  125. {
  126. if ( !GetCompEM().CheckWetness() )
  127. return false;
  128. ItemBase rag = GetRag();
  129. if (rag && GetCompEM().GetEnergy() < GetCompEM().GetEnergyUsage() * GetCompEM().GetUpdateInterval() )
  130. {
  131. if (IsRagDryEnough(rag))
  132. return false;
  133. }
  134. if ( !GetCompEM().CanWork() )
  135. return false;
  136. if ( GetCompEM().GetEnergy() < 3 )
  137. return false;
  138. PlayerBase player = PlayerBase.Cast(GetHierarchyRootPlayer());
  139. if (player)
  140. {
  141. if (this != player.GetItemInHands())//we are in player's inventory, but not in his hands
  142. {
  143. return false;
  144. }
  145. }
  146. return true;
  147. }
  148. bool IsRagDryEnough(ItemBase rag)
  149. {
  150. float wetness = rag.GetWet();
  151. bool is_dry_enough = wetness <= 1-GetCompEM().GetWetnessExposure();
  152. return is_dry_enough;
  153. }
  154. void UpdateCheckForReceivingUpgrade()
  155. {
  156. if ( GetGame().IsServer() || !GetGame().IsMultiplayer() )
  157. {
  158. m_CanReceiveUpgrade = GetRagQuantity() > 0 && m_RagsUpgradedCount < GetRagQuantity() || (m_BurnTimePerRagEx * (m_RagsUpgradedCount + GetRagQuantity()) - GetCompEM().GetEnergy()) > 1;
  159. SetSynchDirty();
  160. }
  161. }
  162. override void OnIgnitedThis(EntityAI fire_source)
  163. {
  164. if ( !GetCompEM().HasEnoughStoredEnergy() )
  165. {
  166. ConsumeRag();
  167. }
  168. GetCompEM().SwitchOn();
  169. }
  170. override void OnSwitchOn()
  171. {
  172. if (!GetCompEM().HasEnoughStoredEnergy())
  173. {
  174. GetCompEM().SwitchOff();
  175. }
  176. if (GetGame().IsServer() || !GetGame().IsMultiplayer())
  177. {
  178. m_UTSource.SetActive(true);
  179. }
  180. }
  181. override void OnSwitchOff()
  182. {
  183. if (GetGame().IsServer() || !GetGame().IsMultiplayer())
  184. {
  185. m_UTSource.SetActive(false);
  186. }
  187. }
  188. void SetTorchDecraftResult(string type)
  189. {
  190. m_DecraftResult = type; //not persistent for the moment
  191. }
  192. bool ConsumeRag()
  193. {
  194. ItemBase rag = GetRag();
  195. if (rag)
  196. {
  197. if (rag.GetQuantity() <= 1)
  198. {
  199. LockRags(false); // Unlock attachment slot before deletion. Otherwise it will get stuck locked and unusable.
  200. }
  201. rag.AddQuantity(-1);
  202. rag.SetHealth(0);
  203. //GetCompEM().AddEnergy( m_BurnTimePerRagEx );
  204. return true;
  205. }
  206. return false;
  207. }
  208. void ConsumeLard(Lard lard)
  209. {
  210. if (lard)
  211. {
  212. float lard_quant = lard.GetQuantity();
  213. float available_lard_quant = lard_quant;
  214. if ( available_lard_quant > m_MaxConsumableLardQuantityEx )
  215. available_lard_quant = m_MaxConsumableLardQuantityEx;
  216. float available_lard_coef = available_lard_quant / m_MaxConsumableLardQuantityEx;
  217. float add_energy = m_BurnTimePerFullLardEx * available_lard_coef;
  218. float add_energy_coef = 1;
  219. float energy_limit = GetCompEM().GetEnergyMax() - GetCompEM().GetEnergy();
  220. if (add_energy > energy_limit )
  221. {
  222. add_energy_coef = energy_limit / add_energy;
  223. add_energy = energy_limit;
  224. available_lard_quant = available_lard_quant * add_energy_coef;
  225. }
  226. GetCompEM().AddEnergy( add_energy );
  227. lard.AddQuantity(-available_lard_quant);
  228. CalculateQuantity();
  229. UpdateCheckForReceivingUpgrade();
  230. }
  231. }
  232. void Upgrade(ItemBase source)
  233. {
  234. if (!GetRag())
  235. {
  236. return;
  237. }
  238. RuinRags();
  239. LockRags(true);
  240. float torchCurrentEnergy = GetCompEM().GetEnergy();
  241. float sourceQuantity = 100000;//for upgrade from environment(gas pump)
  242. if (source)
  243. {
  244. sourceQuantity = source.GetQuantity();
  245. }
  246. float maxOverallCapacity = GetRagQuantity() * 2 * m_BurnTimePerRagEx;
  247. //float maxUpgradeCapacity = GetRagQuantity() * m_BurnTimePerRagEx;
  248. float currentlyUpgraded = Math.Max(0, torchCurrentEnergy - (GetRagQuantity() * m_BurnTimePerRagEx));
  249. //float freeUpgradeCapacity = maxUpgradeCapacity - currentlyUpgraded;
  250. float freeUpgradeCapacity = maxOverallCapacity - torchCurrentEnergy;
  251. float upgradeQuantity = Math.Min(freeUpgradeCapacity, sourceQuantity);
  252. int upgradedRags = Math.Ceil((upgradeQuantity + currentlyUpgraded) / m_BurnTimePerRagEx);
  253. upgradedRags = Math.Min(GetRagQuantity(), upgradedRags);
  254. m_RagsUpgradedCount = upgradedRags;
  255. GetCompEM().AddEnergy(upgradeQuantity);
  256. m_ConsumeRagFlipFlop = 0;//consume fuel first
  257. if (source)
  258. {
  259. source.AddQuantity(-upgradeQuantity);
  260. }
  261. CalculateQuantity();
  262. UpdateCheckForReceivingUpgrade();
  263. }
  264. void ConsumeFuelFromBottle(ItemBase vessel)
  265. {
  266. if (vessel)
  267. {
  268. float vessel_quant = vessel.GetQuantity();
  269. float available_vessel_quant = vessel_quant;
  270. if ( available_vessel_quant > m_MaxConsumableFuelQuantityEx )
  271. available_vessel_quant = m_MaxConsumableFuelQuantityEx;
  272. float available_vessel_coef = available_vessel_quant / m_MaxConsumableFuelQuantityEx;
  273. float add_energy = m_BurnTimePerFullFuelDoseEx * available_vessel_coef;
  274. float add_energy_coef = 1;
  275. float energy_limit = GetCompEM().GetEnergyMax() - GetCompEM().GetEnergy();
  276. if (add_energy > energy_limit )
  277. {
  278. add_energy_coef = energy_limit / add_energy;
  279. add_energy = energy_limit;
  280. available_vessel_quant = available_vessel_quant * add_energy_coef;
  281. }
  282. GetCompEM().AddEnergy( add_energy );
  283. vessel.AddQuantity(-available_vessel_quant);
  284. CalculateQuantity();
  285. UpdateCheckForReceivingUpgrade();
  286. }
  287. }
  288. void ConsumeFuelFromGasStation()
  289. {
  290. float add_energy = m_BurnTimePerFullFuelDoseEx;
  291. float add_energy_coef = 1;
  292. float energy_limit = GetCompEM().GetEnergyMax() - GetCompEM().GetEnergy();
  293. if (add_energy > energy_limit )
  294. {
  295. add_energy_coef = energy_limit / add_energy;
  296. add_energy = energy_limit;
  297. }
  298. GetCompEM().AddEnergy( add_energy );
  299. CalculateQuantity();
  300. UpdateCheckForReceivingUpgrade();
  301. }
  302. void RuinRags()
  303. {
  304. ItemBase rag = GetRag();
  305. if (rag)
  306. {
  307. rag.SetHealth(1); //does not actually ruin rags, combining would be impossible
  308. }
  309. }
  310. // Inventory manipulation
  311. override void OnInventoryExit(Man player)
  312. {
  313. super.OnInventoryExit(player);
  314. StandUp();
  315. }
  316. // Stands up the torch, if possible. Returns true on success.
  317. bool StandUp()
  318. {
  319. string surface_type;
  320. vector position = GetPosition();
  321. GetGame().SurfaceGetType ( position[0], position[2], surface_type );
  322. bool is_surface_soft = GetGame().IsSurfaceDigable(surface_type);
  323. if ( is_surface_soft && !IsRuined() )
  324. {
  325. vector ori_rotate = "0 0 0";
  326. ori_rotate[0] = Math.RandomFloat(0, 360);
  327. ori_rotate[1] = Math.RandomFloat(0, 10);
  328. SetOrientation(ori_rotate);
  329. return true; // I am standing up
  330. }
  331. return false; // I am NOT standing up
  332. }
  333. void CalculateQuantity()
  334. {
  335. if (GetGame().IsServer() || !GetGame().IsMultiplayer())
  336. {
  337. SetQuantityNormalized(GetCompEM().GetEnergy0To1());
  338. }
  339. }
  340. bool CanReceiveUpgrade()
  341. {
  342. return m_CanReceiveUpgrade;
  343. }
  344. void CraftingInit(float quantity)
  345. {
  346. GetCompEM().SetEnergy(m_BurnTimePerRagEx * quantity);
  347. m_CanReceiveUpgrade = true;
  348. SetSynchDirty();
  349. }
  350. override void EEItemAttached( EntityAI item, string slot_name )
  351. {
  352. super.EEItemAttached( item, slot_name );
  353. CalculateQuantity();
  354. UpdateCheckForReceivingUpgrade();
  355. }
  356. override void EEItemDetached( EntityAI item, string slot_name )
  357. {
  358. super.EEItemDetached( item, slot_name );
  359. if (m_IsBeingDestructed)
  360. {
  361. if (GetGame().IsServer() || !GetGame().IsMultiplayer())
  362. {
  363. EntityAI rags = EntityAI.Cast(GetGame().CreateObjectEx(item.GetType(), GetPosition(), ECE_PLACE_ON_SURFACE));
  364. if( rags )
  365. MiscGameplayFunctions.TransferItemProperties(item, rags);
  366. }
  367. return;
  368. }
  369. CalculateQuantity();
  370. UpdateCheckForReceivingUpgrade();
  371. GetGame().GetCallQueue( CALL_CATEGORY_SYSTEM ).CallLater( TryTransformIntoStick, 100);
  372. }
  373. bool CanTransformIntoStick()
  374. {
  375. if ((GetGame().IsServer() || !GetGame().IsMultiplayer()) && !IsIgnited() && !GetRag() && !IsSetForDeletion() )
  376. return true;
  377. else
  378. return false;
  379. }
  380. void TryTransformIntoStick()
  381. {
  382. PlayerBase player = PlayerBase.Cast(GetHierarchyRootPlayer());
  383. if ( m_IsBeingDestructed || (player && player.IsPlayerDisconnected()) )
  384. return;
  385. if ( CanTransformIntoStick() )
  386. {
  387. m_IsBeingDestructed = true;
  388. if (player)
  389. {
  390. // Transform object into wooden stick
  391. StopAllParticles();
  392. TorchLambda lambda = new TorchLambda(this, m_DecraftResult);
  393. player.ServerReplaceItemInHandsWithNew(lambda);
  394. }
  395. else
  396. {
  397. // Create wooden stick and delete Torch
  398. vector pos = GetPosition();
  399. vector ori = GetOrientation();
  400. if ( GetType() == "WoodenStick" )
  401. ori = ori + Vector(0,90,0);
  402. ItemBase stick = ItemBase.Cast( GetGame().CreateObjectEx(m_DecraftResult, pos, ECE_PLACE_ON_SURFACE) );
  403. ApplyResultModifications(stick);
  404. stick.SetPosition(pos);
  405. stick.PlaceOnSurface();
  406. if ( stick.GetType() == "LongWoodenStick" )
  407. {
  408. pos = stick.GetPosition() + Vector(0,-0.3,0);
  409. stick.SetPosition(pos);
  410. }
  411. stick.SetOrientation(ori);
  412. GetGame().ObjectDelete(this);
  413. }
  414. }
  415. }
  416. override void OnWorkStart()
  417. {
  418. m_WasLit = true;
  419. LockRags(true);
  420. UpdateMaterial();
  421. }
  422. void StopAllParticles()
  423. {
  424. if (m_FireParticle)
  425. {
  426. m_FireParticle.Stop();
  427. }
  428. }
  429. Rag GetRag()
  430. {
  431. return Rag.Cast( GetAttachmentByType(Rag) );
  432. }
  433. void LockRags(bool do_lock)
  434. {
  435. ItemBase rag = GetRag();
  436. if (rag)
  437. {
  438. if (do_lock)
  439. {
  440. rag.LockToParent();
  441. }
  442. else if (!m_RagsUpgradedCount)
  443. {
  444. rag.UnlockFromParent();
  445. }
  446. }
  447. }
  448. void UpdateLight()
  449. {
  450. if (!m_Light)
  451. {
  452. m_Light = TorchLight.Cast( ScriptedLightBase.CreateLight( TorchLight, Vector(0,0,0), 1 ) );
  453. m_Light.AttachOnObject(this, m_ParticleLocalPos + Vector (0,0.2,0));
  454. }
  455. if (m_FireParticle)
  456. {
  457. Object direct_particle = m_FireParticle.GetDirectParticleEffect();
  458. if (direct_particle && direct_particle != m_Light.GetAttachmentParent())
  459. {
  460. m_Light.AttachOnObject(direct_particle, Vector(0,0.2,0));
  461. }
  462. }
  463. float update_interval = GetCompEM().GetUpdateInterval();
  464. if (GetQuantity() <= m_StartFadeOutOfLightAtQuantityEx)
  465. {
  466. float brightness_coef = GetQuantity() / m_StartFadeOutOfLightAtQuantityEx;
  467. float radius_coef = GetQuantity() / m_StartFadeOutOfLightAtQuantityEx;
  468. if (radius_coef < m_StartFadeOutOfLightAtQuantityEx/10)
  469. radius_coef = m_StartFadeOutOfLightAtQuantityEx/10;
  470. if (brightness_coef < m_StartFadeOutOfLightAtQuantityEx/10)
  471. brightness_coef = m_StartFadeOutOfLightAtQuantityEx/10;
  472. m_Light.FadeBrightnessTo(m_Light.m_TorchBrightness * brightness_coef, update_interval);
  473. m_Light.FadeRadiusTo(m_Light.m_TorchRadius * radius_coef, update_interval);
  474. }
  475. else
  476. {
  477. m_Light.FadeBrightnessTo(m_Light.m_TorchBrightness, update_interval);
  478. m_Light.FadeRadiusTo(m_Light.m_TorchRadius, update_interval);
  479. }
  480. }
  481. override void OnItemInHandsPlayerSwimStart(PlayerBase player)
  482. {
  483. GetCompEM().SwitchOff();
  484. }
  485. override void OnWork( float consumed_energy )
  486. {
  487. UpdateMaterial();
  488. if (GetGame().IsServer() || !GetGame().IsMultiplayer())
  489. {
  490. if (GetCompEM().GetEnergy() < ((GetRagQuantity() + m_RagsUpgradedCount) - 1) * m_BurnTimePerRagEx)
  491. {
  492. if (m_RagsUpgradedCount==0)//always burn rag
  493. {
  494. ConsumeRag();
  495. }
  496. else if (m_ConsumeRagFlipFlop)//burn rag
  497. {
  498. ConsumeRag();
  499. m_ConsumeRagFlipFlop = !m_ConsumeRagFlipFlop;
  500. }
  501. else//burn lard/fuel
  502. {
  503. m_RagsUpgradedCount--;
  504. m_ConsumeRagFlipFlop = !m_ConsumeRagFlipFlop;
  505. }
  506. }
  507. if (GetRag() && GetCompEM().GetEnergy() == 0 && GetRagQuantity() > 0)
  508. {
  509. GetRag().SetQuantity(0);
  510. }
  511. RuinRags();
  512. CalculateQuantity();
  513. UpdateCheckForReceivingUpgrade();
  514. AddWet( -m_WaterEvaporationByFireIntensityEx * GetCompEM().GetUpdateInterval() );
  515. Rag rag = GetRag();
  516. if ( rag )
  517. {
  518. rag.AddWet( -m_WaterEvaporationByFireIntensityEx * GetCompEM().GetUpdateInterval() );
  519. }
  520. }
  521. if ( !m_LoopSoundEntity && GetGame() && ( !GetGame().IsDedicatedServer() ) )
  522. {
  523. m_LoopSoundEntity = PlaySoundLoop(GetSoundName(), 50);
  524. }
  525. // Effect scaling by fuel
  526. if ( !GetGame().IsDedicatedServer() )
  527. {
  528. UpdateLight();
  529. UpdateParticle();
  530. }
  531. }
  532. string GetSoundName()
  533. {
  534. return "torchLoop";
  535. }
  536. void UpdateParticle()
  537. {
  538. if ( GetQuantity() < 40 )
  539. {
  540. if (!m_FireParticle)
  541. m_FireParticle = ParticleManager.GetInstance().PlayOnObject(ParticleList.TORCH_T1, this, m_ParticleLocalPos);
  542. float scale = GetQuantity() / 40;
  543. if (scale > 1)
  544. scale = 1;
  545. if (scale < 0.25)
  546. scale = 0.25;
  547. m_FireParticle.ScaleParticleParamFromOriginal(EmitorParam.SIZE, scale);
  548. m_FireParticle.ScaleParticleParamFromOriginal(EmitorParam.VELOCITY, scale);
  549. m_FireParticle.ScaleParticleParamFromOriginal(EmitorParam.VELOCITY_RND, scale);
  550. }
  551. else
  552. {
  553. if ( !m_FireParticle || m_FireParticle.GetParticleID() != ParticleList.TORCH_T2 )
  554. {
  555. // Executes once when fire particle starts or changes
  556. if (m_FireParticle)
  557. m_FireParticle.Stop();
  558. m_FireParticle = ParticleManager.GetInstance().PlayOnObject(ParticleList.TORCH_T2, this, m_ParticleLocalPos);
  559. }
  560. }
  561. }
  562. override void OnWorkStop()
  563. {
  564. UpdateMaterial();
  565. if (m_Light)
  566. m_Light.FadeOut();
  567. if ( m_LoopSoundEntity && GetGame() && ( !GetGame().IsDedicatedServer() ) )
  568. {
  569. GetGame().ObjectDelete( m_LoopSoundEntity );
  570. m_LoopSoundEntity = NULL;
  571. }
  572. if ( m_FireParticle)
  573. {
  574. m_FireParticle.Stop();
  575. m_FireParticle = NULL;
  576. }
  577. CalculateQuantity();
  578. UpdateCheckForReceivingUpgrade();
  579. LockRags(false);
  580. if (GetGame().IsServer() || !GetGame().IsMultiplayer())
  581. {
  582. if (GetRag() && GetCompEM().GetEnergy() == 0 && GetRagQuantity() > 0)
  583. {
  584. GetRag().SetQuantity(0);
  585. }
  586. }
  587. TryTransformIntoStick();
  588. }
  589. // COMBAT
  590. // This needs refactor!
  591. override int GetMeleeMode()
  592. {
  593. if ( GetCompEM().IsWorking() )
  594. return 3; // ???
  595. else
  596. return 0; // ???
  597. }
  598. override int GetMeleeHeavyMode()
  599. {
  600. if ( GetCompEM().IsWorking() )
  601. return 4; // ???
  602. else
  603. return 1; // ???
  604. }
  605. override int GetMeleeSprintMode()
  606. {
  607. if ( GetCompEM().IsWorking() )
  608. return 5; // ???
  609. else
  610. return 2; // ???
  611. }
  612. override void SetActions()
  613. {
  614. super.SetActions();
  615. AddAction(ActionLightItemOnFire);
  616. }
  617. override void OnAttachmentQuantityChangedEx(ItemBase item, float delta)
  618. {
  619. super.OnAttachmentQuantityChangedEx(item, delta);
  620. if (delta != 0)
  621. {
  622. if (delta > 0 || !GetCompEM().IsWorking()) // dont adjust energy when rag burns out
  623. GetCompEM().AddEnergy(m_BurnTimePerRagEx * delta);
  624. CalculateQuantity();
  625. UpdateCheckForReceivingUpgrade();
  626. }
  627. }
  628. override bool DisassembleOnLastDetach()
  629. {
  630. return true;
  631. }
  632. override void OnDebugSpawn()
  633. {
  634. GetInventory().CreateAttachment("Rag");
  635. CraftingInit(GetRagQuantity());
  636. CalculateQuantity();
  637. }
  638. int GetRagQuantity()
  639. {
  640. if (GetRag())
  641. {
  642. return Math.Round(GetRag().GetQuantity());
  643. }
  644. return 0;
  645. }
  646. string GetBurningMaterial()
  647. {
  648. return "";
  649. }
  650. string GetBurntMaterial()
  651. {
  652. return "";
  653. }
  654. void UpdateMaterial()
  655. {
  656. if (GetGame().IsServer() || !GetGame().IsMultiplayer())
  657. {
  658. if (GetCompEM().IsWorking())
  659. {
  660. if (GetBurningMaterial())
  661. {
  662. SetObjectMaterial(0, GetBurningMaterial());
  663. }
  664. }
  665. else if (m_WasLit)
  666. {
  667. if (GetBurntMaterial())
  668. {
  669. SetObjectMaterial(0, GetBurntMaterial());
  670. }
  671. }
  672. }
  673. }
  674. override void OnStoreSave(ParamsWriteContext ctx)
  675. {
  676. super.OnStoreSave(ctx);
  677. ctx.Write(m_WasLit);
  678. }
  679. override bool OnStoreLoad( ParamsReadContext ctx, int version )
  680. {
  681. if (!super.OnStoreLoad(ctx, version))
  682. {
  683. return false;
  684. }
  685. if (version >= 130)
  686. {
  687. if (!ctx.Read( m_WasLit ))
  688. {
  689. return false;
  690. }
  691. }
  692. UpdateMaterial();
  693. return true;
  694. }
  695. void ApplyResultModifications(ItemBase result)
  696. {
  697. result.SetQuantity(1);
  698. }
  699. //-------------
  700. // DEBUG BELLOW
  701. //-------------
  702. #ifdef DEVELOPER
  703. override void GetDebugActions(out TSelectableActionInfoArrayEx outputList)
  704. {
  705. outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ACTIVATE_ENTITY, "Ignite", FadeColors.LIGHT_GREY));
  706. outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.LIGHT_GREY));
  707. super.GetDebugActions(outputList);
  708. }
  709. override bool OnAction(int action_id, Man player, ParamsReadContext ctx)
  710. {
  711. if (super.OnAction(action_id, player, ctx))
  712. return true;
  713. if (GetGame().IsServer() || !GetGame().IsMultiplayer())
  714. {
  715. if (action_id == EActions.ACTIVATE_ENTITY)
  716. {
  717. OnIgnitedThis(null);
  718. }
  719. }
  720. return false;
  721. }
  722. override string GetDebugText()
  723. {
  724. string debug_output;
  725. debug_output = super.GetDebugText();
  726. if( GetGame().IsDedicatedServer())
  727. {
  728. debug_output+="m_RagsUpgradedCount:"+m_RagsUpgradedCount+"\n";
  729. debug_output+="m_ConsumeRagFlipFlop:"+m_ConsumeRagFlipFlop+"\n";
  730. if (IsIgnited() && m_ConsumeRagFlipFlop)
  731. {
  732. debug_output+="Burning rag \n";
  733. }
  734. else if (IsIgnited())
  735. {
  736. debug_output+="Burning lard/fuel \n";
  737. }
  738. }
  739. else
  740. {
  741. }
  742. return debug_output;
  743. }
  744. #endif
  745. }
  746. class Torch : FlammableBase
  747. {
  748. //legacy vars which cannot be moved/removed
  749. static float m_BurnTimePerRag;
  750. static float m_BurnTimePerFullLard;
  751. static float m_BurnTimePerFullFuelDose;
  752. static float m_MaxConsumableLardQuantity;
  753. static float m_MaxConsumableFuelQuantity;
  754. static float m_WaterEvaporationByFireIntensity = 0.001;
  755. static int m_StartFadeOutOfLightAtQuantity = 3;
  756. override void Init()
  757. {
  758. super.Init();
  759. //for legacy reasons
  760. m_BurnTimePerRag = m_BurnTimePerRagEx;
  761. m_BurnTimePerFullLard = m_BurnTimePerFullLardEx;
  762. m_BurnTimePerFullFuelDose = m_BurnTimePerFullFuelDoseEx;
  763. m_MaxConsumableLardQuantity = m_MaxConsumableLardQuantityEx;
  764. m_MaxConsumableFuelQuantity = m_MaxConsumableFuelQuantityEx;
  765. }
  766. override void SetActions()
  767. {
  768. super.SetActions();
  769. AddAction(ActionUpgradeTorchFromGasPump);
  770. AddAction(ActionRefuelTorch);
  771. }
  772. // !Called on CHILD when it's attached to parent.
  773. override void OnWasAttached( EntityAI parent, int slot_id )
  774. {
  775. super.OnWasAttached(parent, slot_id);
  776. if (GetGame().IsServer() || !GetGame().IsMultiplayer())
  777. LockRags(true);
  778. }
  779. // !Called on CHILD when it's detached from parent.
  780. override void OnWasDetached( EntityAI parent, int slot_id )
  781. {
  782. super.OnWasDetached(parent, slot_id);
  783. if (GetGame().IsServer() || !GetGame().IsMultiplayer())
  784. LockRags(false);
  785. }
  786. override void OnStoreSave(ParamsWriteContext ctx)
  787. {
  788. super.OnStoreSave(ctx);
  789. ctx.Write(m_ConsumeRagFlipFlop);
  790. ctx.Write(m_RagsUpgradedCount);
  791. }
  792. override bool OnStoreLoad( ParamsReadContext ctx, int version )
  793. {
  794. if (!super.OnStoreLoad(ctx, version))
  795. {
  796. return false;
  797. }
  798. if (version >= 129)
  799. {
  800. if (!ctx.Read( m_ConsumeRagFlipFlop ))
  801. {
  802. return false;
  803. }
  804. if (!ctx.Read( m_RagsUpgradedCount ))
  805. {
  806. return false;
  807. }
  808. }
  809. UpdateCheckForReceivingUpgrade();
  810. return true;
  811. }
  812. };
  813. class TorchLambda : ReplaceItemWithNewLambdaBase
  814. {
  815. override void CopyOldPropertiesToNew (notnull EntityAI old_item, EntityAI new_item)
  816. {
  817. super.CopyOldPropertiesToNew(old_item, new_item);
  818. ItemBase stick;
  819. FlammableBase flammable = FlammableBase.Cast(old_item);
  820. Class.CastTo(stick, new_item);
  821. if (stick && flammable)
  822. {
  823. flammable.ApplyResultModifications(stick);
  824. }
  825. }
  826. };