Make lathes refund materials when recipe gets cancelled (#42416)

30 day free refund
This commit is contained in:
korczoczek 2026-01-14 22:12:30 +01:00 committed by BarryNorfolk
parent c037990939
commit 914bf8ab1c
1 changed files with 47 additions and 9 deletions

View File

@ -183,15 +183,8 @@ namespace Content.Server.Lathe
if (!CanProduce(uid, recipe, quantity, component)) if (!CanProduce(uid, recipe, quantity, component))
return false; return false;
foreach (var (mat, amount) in recipe.Materials) foreach (var (mat, amount) in GetAdjustedAmount(component, recipe))
{ _materialStorage.TryChangeMaterialAmount(uid, mat, -amount * quantity);
var adjustedAmount = recipe.ApplyMaterialDiscount
? (int)(-amount * component.MaterialUseMultiplier)
: -amount;
adjustedAmount *= quantity;
_materialStorage.TryChangeMaterialAmount(uid, mat, adjustedAmount);
}
if (component.Queue.Last is { } node && node.ValueRef.Recipe == recipe.ID) if (component.Queue.Last is { } node && node.ValueRef.Recipe == recipe.ID)
node.ValueRef.ItemsRequested += quantity; node.ValueRef.ItemsRequested += quantity;
@ -431,6 +424,48 @@ namespace Content.Server.Lathe
return GetAvailableRecipes(uid, component).Contains(recipe.ID); return GetAvailableRecipes(uid, component).Contains(recipe.ID);
} }
/// <summary>
/// Iterator returning adjusted amount of material needed to
/// produce a given recipe
/// </summary>
private static IEnumerable<(ProtoId<MaterialPrototype> mat, int amount)> GetAdjustedAmount(LatheComponent lathe, LatheRecipePrototype recipe)
{
foreach (var (mat, amount) in recipe.Materials)
{
var adjustedAmount = recipe.ApplyMaterialDiscount
? (int)(amount * lathe.MaterialUseMultiplier)
: amount;
yield return (mat, adjustedAmount);
}
}
/// <summary>
/// Refunds the material cost of the currently running recipe,
/// without cancelling production
/// </summary>
private void RefundCurrentRecipe(EntityUid uid, LatheComponent lathe)
{
_proto.Resolve(lathe.CurrentRecipe, out var recipe);
foreach (var (mat, amount) in GetAdjustedAmount(lathe, recipe!))
_materialStorage.TryChangeMaterialAmount(uid, mat, amount);
}
/// <summary>
/// Refunds the material cost of a given batch,
/// without deleting it
/// </summary>
private void RefundBatch(EntityUid uid, LatheComponent lathe, LatheRecipeBatch batch)
{
var delta = batch.ItemsRequested - batch.ItemsPrinted;
_proto.Resolve(batch.Recipe, out var recipe);
foreach (var (mat, amount) in GetAdjustedAmount(lathe, recipe!))
_materialStorage.TryChangeMaterialAmount(uid, mat, amount * delta);
}
public void AbortProduction(EntityUid uid, LatheComponent? component = null) public void AbortProduction(EntityUid uid, LatheComponent? component = null)
{ {
if (!Resolve(uid, ref component)) if (!Resolve(uid, ref component))
@ -453,6 +488,7 @@ namespace Content.Server.Lathe
} }
} }
RefundCurrentRecipe(uid, component);
component.CurrentRecipe = null; component.CurrentRecipe = null;
} }
RemCompDeferred<LatheProducingComponent>(uid); RemCompDeferred<LatheProducingComponent>(uid);
@ -506,6 +542,7 @@ namespace Content.Server.Lathe
LogImpact.Low, LogImpact.Low,
$"{ToPrettyString(args.Actor):player} deleted a lathe job for ({batch.ItemsPrinted}/{batch.ItemsRequested}) {GetRecipeName(batch.Recipe)} at {ToPrettyString(uid):lathe}"); $"{ToPrettyString(args.Actor):player} deleted a lathe job for ({batch.ItemsPrinted}/{batch.ItemsRequested}) {GetRecipeName(batch.Recipe)} at {ToPrettyString(uid):lathe}");
RefundBatch(uid, component, batch);
component.Queue.Remove(node); component.Queue.Remove(node);
UpdateUserInterfaceState(uid, component); UpdateUserInterfaceState(uid, component);
} }
@ -564,6 +601,7 @@ namespace Content.Server.Lathe
LogImpact.Low, LogImpact.Low,
$"{ToPrettyString(args.Actor):player} aborted printing {GetRecipeName(component.CurrentRecipe.Value)} at {ToPrettyString(uid):lathe}"); $"{ToPrettyString(args.Actor):player} aborted printing {GetRecipeName(component.CurrentRecipe.Value)} at {ToPrettyString(uid):lathe}");
RefundCurrentRecipe(uid, component);
component.CurrentRecipe = null; component.CurrentRecipe = null;
FinishProducing(uid, component); FinishProducing(uid, component);
} }