GrillFuelBurnSystem.cs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  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. int availableFuel = stackComp.Count;
  64. int fuelNeeded = comp.MaxFuel - comp.Fuel;
  65. int 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 - 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 && comp.Expends == true)
  97. {
  98. if (comp.Fuel <= 0 || _remainingBurnTime.GetValueOrDefault(uid) <= 0)
  99. {
  100. var coordinates = Transform(uid).Coordinates;
  101. Spawn("Coal1", coordinates);
  102. QueueDel(uid);
  103. _remainingBurnTime.Remove(uid);
  104. comp.IsLit = false;
  105. AdjustHeaterSetting(uid, comp);
  106. continue;
  107. }
  108. _remainingBurnTime[uid] -= deltaTime;
  109. AdjustHeaterSetting(uid, comp);
  110. if (comp.Setting != EntityHeaterSetting.Off)
  111. {
  112. var energy = SettingPower(comp.Setting) * deltaTime;
  113. foreach (var ent in placer.PlacedEntities)
  114. {
  115. _temperature.ChangeHeat(ent, energy);
  116. }
  117. }
  118. }
  119. }
  120. }
  121. private void OnExamined(EntityUid uid, GrillFuelBurnComponent comp, ExaminedEvent args)
  122. {
  123. if (!args.IsInDetailsRange)
  124. return;
  125. var remainingTime = _remainingBurnTime.GetValueOrDefault(uid) / 60f;
  126. args.PushMarkup($"Has approximately {remainingTime:F1} minutes of fuel remaining.");
  127. }
  128. public void ChangeSetting(EntityUid uid, EntityHeaterSetting setting, GrillFuelBurnComponent? comp = null)
  129. {
  130. if (!Resolve(uid, ref comp))
  131. return;
  132. comp.Setting = setting;
  133. _appearance.SetData(uid, EntityHeaterVisuals.Setting, setting);
  134. // Adjust the PointLight based on the Setting
  135. if (_entityManager.TryGetComponent<PointLightComponent>(uid, out var lightComp))
  136. {
  137. switch (setting)
  138. {
  139. case EntityHeaterSetting.Off:
  140. _pointLightSystem.SetEnabled(uid, false, lightComp);
  141. break;
  142. case EntityHeaterSetting.Low:
  143. _pointLightSystem.SetEnabled(uid, true, lightComp);
  144. _pointLightSystem.SetRadius(uid, 2.0f, lightComp);
  145. _pointLightSystem.SetEnergy(uid, 2.0f, lightComp);
  146. break;
  147. case EntityHeaterSetting.Medium:
  148. _pointLightSystem.SetEnabled(uid, true, lightComp);
  149. _pointLightSystem.SetRadius(uid, 4.0f, lightComp);
  150. _pointLightSystem.SetEnergy(uid, 4.0f, lightComp);
  151. break;
  152. case EntityHeaterSetting.High:
  153. _pointLightSystem.SetEnabled(uid, true, lightComp);
  154. _pointLightSystem.SetRadius(uid, 6.0f, lightComp);
  155. _pointLightSystem.SetEnergy(uid, 6.0f, lightComp);
  156. break;
  157. }
  158. }
  159. else
  160. {
  161. Log.Warning($"No PointLightComponent found for campfire {uid}");
  162. }
  163. }
  164. private void AdjustHeaterSetting(EntityUid uid, GrillFuelBurnComponent comp)
  165. {
  166. if (!comp.IsLit) // If its not lit, updates to Off
  167. {
  168. if (comp.Setting != EntityHeaterSetting.Off)
  169. {
  170. ChangeSetting(uid, EntityHeaterSetting.Off, comp);
  171. }
  172. return;
  173. }
  174. var remainingTimeSeconds = _remainingBurnTime.GetValueOrDefault(uid);
  175. EntityHeaterSetting newSetting;
  176. if (remainingTimeSeconds > 600f) // > 10 minutes
  177. newSetting = EntityHeaterSetting.High;
  178. else if (remainingTimeSeconds > 300f) // 5-10 minutes
  179. newSetting = EntityHeaterSetting.Medium;
  180. else if (remainingTimeSeconds > 0f) // < 5 minutes
  181. newSetting = EntityHeaterSetting.Low;
  182. else
  183. newSetting = EntityHeaterSetting.Off;
  184. if (comp.Setting != newSetting)
  185. {
  186. ChangeSetting(uid, newSetting, comp);
  187. }
  188. }
  189. private float SettingPower(EntityHeaterSetting setting)
  190. {
  191. switch (setting)
  192. {
  193. case EntityHeaterSetting.Low:
  194. return 400f;
  195. case EntityHeaterSetting.Medium:
  196. return 800f;
  197. case EntityHeaterSetting.High:
  198. return 1600f;
  199. default:
  200. return 0f;
  201. }
  202. }
  203. }