GrillFuelBurnSystem.cs 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. using Content.Server.Temperature.Components;
  2. using Content.Server.Temperature.Systems;
  3. using Content.Shared.Examine;
  4. using Content.Shared.Interaction;
  5. using Content.Shared.Kitchen;
  6. using Content.Shared.Placeable;
  7. using Content.Shared.Stacks;
  8. using Content.Shared.Temperature;
  9. using Robust.Server.Audio;
  10. using Robust.Shared.Timing;
  11. using System.Linq;
  12. using Content.Server.IgnitionSource;
  13. using Robust.Server.GameObjects;
  14. using Robust.Shared.GameObjects;
  15. namespace Content.Server.Kitchen;
  16. public sealed class GrillFuelBurnSystem : EntitySystem
  17. {
  18. [Dependency] private readonly IGameTiming _gameTiming = default!;
  19. [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
  20. [Dependency] private readonly TemperatureSystem _temperature = default!;
  21. [Dependency] private readonly AudioSystem _audio = default!;
  22. [Dependency] private readonly IEntityManager _entityManager = default!;
  23. [Dependency] private readonly SharedStackSystem _stackSystem = default!;
  24. [Dependency] private readonly SharedPointLightSystem _pointLightSystem = default!;
  25. private readonly Dictionary<EntityUid, float> _remainingBurnTime = new();
  26. public override void Initialize()
  27. {
  28. base.Initialize();
  29. SubscribeLocalEvent<GrillFuelBurnComponent, MapInitEvent>(OnMapInit);
  30. SubscribeLocalEvent<GrillFuelBurnComponent, ExaminedEvent>(OnExamined);
  31. SubscribeLocalEvent<GrillFuelBurnComponent, ItemPlacedEvent>(OnItemPlaced);
  32. SubscribeLocalEvent<GrillFuelBurnComponent, InteractUsingEvent>(OnInteractUsing);
  33. }
  34. private void OnMapInit(EntityUid uid, GrillFuelBurnComponent component, MapInitEvent args)
  35. {
  36. _remainingBurnTime[uid] = component.Fuel * 2f * 60f;
  37. component.IsLit = false;
  38. }
  39. private void OnItemPlaced(EntityUid uid, GrillFuelBurnComponent comp, ref ItemPlacedEvent args)
  40. {
  41. var itemProto = _entityManager.GetComponent<MetaDataComponent>(args.OtherEntity).EntityPrototype?.ID;
  42. }
  43. private void OnInteractUsing(EntityUid uid, GrillFuelBurnComponent comp, InteractUsingEvent args)
  44. {
  45. if (_entityManager.TryGetComponent<IgnitionSourceComponent>(args.Used, out var ignitionSource))
  46. {
  47. if (!comp.IsLit && ignitionSource.Ignited && _remainingBurnTime[uid] > 0)
  48. {
  49. comp.IsLit = true;
  50. AdjustHeaterSetting(uid, comp);
  51. }
  52. args.Handled = true;
  53. return;
  54. }
  55. // Add fuel
  56. if (!_entityManager.TryGetComponent<BurnFuelComponent>(args.Used, out var burnFuel))
  57. {
  58. return;
  59. }
  60. var itemProto = _entityManager.GetComponent<MetaDataComponent>(args.Used).EntityPrototype?.ID;
  61. if (_entityManager.TryGetComponent<StackComponent>(args.Used, out var stackComp))
  62. {
  63. float availableFuel = stackComp.Count;
  64. float fuelNeeded = comp.MaxFuel - comp.Fuel;
  65. float fuelToAdd = Math.Min(availableFuel, fuelNeeded);
  66. if (fuelToAdd > 0)
  67. {
  68. comp.Fuel += fuelToAdd;
  69. _remainingBurnTime[uid] += fuelToAdd * burnFuel.BurnTime * 60f;
  70. _stackSystem.SetCount(args.Used, stackComp.Count - (int)fuelToAdd, stackComp);
  71. if (stackComp.Count <= 0)
  72. {
  73. QueueDel(args.Used);
  74. }
  75. AdjustHeaterSetting(uid, comp);
  76. args.Handled = true;
  77. }
  78. }
  79. else
  80. {
  81. if (comp.Fuel < comp.MaxFuel)
  82. {
  83. comp.Fuel++;
  84. _remainingBurnTime[uid] += burnFuel.BurnTime * 60f;
  85. QueueDel(args.Used);
  86. AdjustHeaterSetting(uid, comp);
  87. args.Handled = true;
  88. }
  89. }
  90. }
  91. public override void Update(float deltaTime)
  92. {
  93. var query = EntityQueryEnumerator<GrillFuelBurnComponent, ItemPlacerComponent>();
  94. while (query.MoveNext(out var uid, out var comp, out var placer))
  95. {
  96. if (comp.IsLit)
  97. {
  98. if (comp.Fuel <= 0 || _remainingBurnTime.GetValueOrDefault(uid) <= 0)
  99. {
  100. _remainingBurnTime.Remove(uid);
  101. comp.IsLit = false;
  102. AdjustHeaterSetting(uid, comp);
  103. if (comp.Expends == true)
  104. {
  105. var coordinates = Transform(uid).Coordinates;
  106. Spawn("Coal1", coordinates);
  107. QueueDel(uid);
  108. }
  109. continue;
  110. }
  111. _remainingBurnTime[uid] -= deltaTime;
  112. comp.Fuel -= deltaTime/60f;
  113. AdjustHeaterSetting(uid, comp);
  114. if (comp.Setting != EntityHeaterSetting.Off)
  115. {
  116. var energy = SettingPower(comp.Setting) * deltaTime;
  117. foreach (var ent in placer.PlacedEntities)
  118. {
  119. _temperature.ChangeHeat(ent, energy);
  120. }
  121. }
  122. }
  123. }
  124. }
  125. private void OnExamined(EntityUid uid, GrillFuelBurnComponent comp, ExaminedEvent args)
  126. {
  127. if (!args.IsInDetailsRange)
  128. return;
  129. var remainingTime = _remainingBurnTime.GetValueOrDefault(uid) / 60f;
  130. args.PushMarkup($"Has approximately {remainingTime:F1} minutes of fuel remaining.");
  131. }
  132. public void ChangeSetting(EntityUid uid, EntityHeaterSetting setting, GrillFuelBurnComponent? comp = null)
  133. {
  134. if (!Resolve(uid, ref comp))
  135. return;
  136. comp.Setting = setting;
  137. _appearance.SetData(uid, EntityHeaterVisuals.Setting, setting);
  138. // Adjust the PointLight based on the Setting
  139. if (_entityManager.TryGetComponent<PointLightComponent>(uid, out var lightComp))
  140. {
  141. switch (setting)
  142. {
  143. case EntityHeaterSetting.Off:
  144. _pointLightSystem.SetEnabled(uid, false, lightComp);
  145. break;
  146. case EntityHeaterSetting.Low:
  147. _pointLightSystem.SetEnabled(uid, true, lightComp);
  148. _pointLightSystem.SetRadius(uid, 2.0f, lightComp);
  149. _pointLightSystem.SetEnergy(uid, 2.0f, lightComp);
  150. break;
  151. case EntityHeaterSetting.Medium:
  152. _pointLightSystem.SetEnabled(uid, true, lightComp);
  153. _pointLightSystem.SetRadius(uid, 4.0f, lightComp);
  154. _pointLightSystem.SetEnergy(uid, 4.0f, lightComp);
  155. break;
  156. case EntityHeaterSetting.High:
  157. _pointLightSystem.SetEnabled(uid, true, lightComp);
  158. _pointLightSystem.SetRadius(uid, 6.0f, lightComp);
  159. _pointLightSystem.SetEnergy(uid, 6.0f, lightComp);
  160. break;
  161. }
  162. }
  163. else
  164. {
  165. Log.Warning($"No PointLightComponent found for campfire {uid}");
  166. }
  167. }
  168. private void AdjustHeaterSetting(EntityUid uid, GrillFuelBurnComponent comp)
  169. {
  170. if (!comp.IsLit) // If its not lit, updates to Off
  171. {
  172. if (comp.Setting != EntityHeaterSetting.Off)
  173. {
  174. ChangeSetting(uid, EntityHeaterSetting.Off, comp);
  175. }
  176. return;
  177. }
  178. var remainingTimeSeconds = _remainingBurnTime.GetValueOrDefault(uid);
  179. EntityHeaterSetting newSetting;
  180. if (remainingTimeSeconds > 600f) // > 10 minutes
  181. newSetting = EntityHeaterSetting.High;
  182. else if (remainingTimeSeconds > 300f) // 5-10 minutes
  183. newSetting = EntityHeaterSetting.Medium;
  184. else if (remainingTimeSeconds > 0f) // < 5 minutes
  185. newSetting = EntityHeaterSetting.Low;
  186. else
  187. newSetting = EntityHeaterSetting.Off;
  188. if (comp.Setting != newSetting)
  189. {
  190. ChangeSetting(uid, newSetting, comp);
  191. }
  192. }
  193. private float SettingPower(EntityHeaterSetting setting)
  194. {
  195. switch (setting)
  196. {
  197. case EntityHeaterSetting.Low:
  198. return 400f;
  199. case EntityHeaterSetting.Medium:
  200. return 800f;
  201. case EntityHeaterSetting.High:
  202. return 1600f;
  203. default:
  204. return 0f;
  205. }
  206. }
  207. }