-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'Lost-Paradise-Project:master' into dbg
- Loading branch information
Showing
159 changed files
with
1,808 additions
and
118 deletions.
There are no files selected for viewing
Validating CODEOWNERS rules …
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
**/_LostParadise @Flybik @Evgencheg | ||
. @BL02DL | ||
* @BL02DL |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
112 changes: 112 additions & 0 deletions
112
Content.Server/_LostParadise/CarnivoresDiet/AccumulateReagent.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
using Content.Server.Body.Components; | ||
using Content.Shared.Chemistry.Components; | ||
using Content.Shared.Chemistry.Reagent; | ||
using Content.Shared.FixedPoint; | ||
using JetBrains.Annotations; | ||
using Robust.Shared.Prototypes; | ||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; | ||
|
||
namespace Content.Server.Chemistry.ReagentEffects | ||
{ | ||
// This class is basically copied from the sealed class AdjustReagent, but compensates a reagent's metabolism rates when adjusting its levels. | ||
// Was introduced in order to make theobromine accumulate faster than it metabolises. | ||
// While quite kludgy, it is still much safer and cleaner alternative to actively preventing the metabolism system from processing theobromine while it's still in the system. | ||
|
||
// TL;DR Это костыль, который тупо добавляет столько же реагента, сколько должно впитаться за данный тик. | ||
// Решение сомнительное, но оно гораздо чище, чем лезть в код метаболирования и добавлять туда группу-исключение с проверкой на наличие реагента в кровеносной системе. | ||
|
||
[UsedImplicitly] | ||
public sealed partial class AccumulateReagent : ReagentEffect | ||
{ | ||
/// <summary> | ||
/// The reagent ID to accumulate. Only one of this and <see cref="Group"/> should be active. | ||
/// </summary> | ||
[DataField(customTypeSerializer: typeof(PrototypeIdSerializer<ReagentPrototype>), required: true)] | ||
public string? Reagent; | ||
|
||
/// <summary> | ||
/// Checks if the target has something that already adds the target reagent | ||
/// </summary> | ||
public bool ContainsPositiveAdjustEffect(IPrototypeManager prototypeMan, Solution solution, List<MetabolismGroupEntry> groups) | ||
{ | ||
foreach (var quantity in solution.Contents) | ||
{ | ||
var reagent = quantity.Reagent.Prototype; | ||
if (reagent == Reagent) | ||
continue; | ||
|
||
if (!prototypeMan.TryIndex(reagent, out ReagentPrototype? reagentProto)) | ||
continue; | ||
|
||
if (reagentProto?.Metabolisms == null) | ||
continue; | ||
|
||
// Ideally we should iterate over the body's MetabolismGroupEntry list. | ||
// But I have no idea why there's no Drink in its .MetabolismGroups property and how to fetch that. | ||
// So it will stay like this for now, but might cause unintended theobromine accumulation in some *very* unlikely and specific scenarios. | ||
foreach (var reagentEffectsEntry in reagentProto.Metabolisms.Values) | ||
{ | ||
foreach (var effect in reagentEffectsEntry.Effects) | ||
{ | ||
if (effect is not AdjustReagent adjustReagent) | ||
continue; | ||
|
||
if (adjustReagent.Reagent == Reagent) | ||
return true; | ||
} | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
public override void Effect(ReagentEffectArgs args) | ||
{ | ||
// Source is where Theobromine is currently coming from | ||
if (args.Source == null) | ||
return; | ||
|
||
if (Reagent == null) | ||
return; | ||
|
||
var prototypeMan = IoCManager.Resolve<IPrototypeManager>(); | ||
prototypeMan.TryIndex(Reagent, out ReagentPrototype? reagentProto); | ||
|
||
args.EntityManager.TryGetComponent(args.OrganEntity, out MetabolizerComponent? metabolizer); | ||
|
||
if (metabolizer?.MetabolismGroups is not List<MetabolismGroupEntry> groups) | ||
return; | ||
|
||
if (!ContainsPositiveAdjustEffect(prototypeMan, args.Source, groups)) | ||
return; | ||
|
||
if (reagentProto?.Metabolisms == null) | ||
return; | ||
|
||
FixedPoint2 totalCompensationRate = 0; | ||
foreach (var group in groups) | ||
{ | ||
// Normally, the rate should only be processed once since a reagent usually only has one group. | ||
if (!reagentProto.Metabolisms.TryGetValue(group.Id, out var reagentEffectsEntry)) | ||
continue; | ||
|
||
var groupRate = reagentEffectsEntry.MetabolismRate * group.MetabolismRateModifier; | ||
totalCompensationRate += groupRate; | ||
} | ||
|
||
// amount *= args.Scale; | ||
args.Source.AddReagent(Reagent, totalCompensationRate); | ||
} | ||
|
||
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) | ||
{ | ||
if (Reagent != null && prototype.TryIndex(Reagent, out ReagentPrototype? reagentProto)) | ||
{ | ||
return Loc.GetString("reagent-effect-guidebook-accumulate-reagent-reagent", | ||
("reagent", reagentProto.LocalizedName)); | ||
} | ||
|
||
throw new NotImplementedException(); | ||
} | ||
} | ||
} |
92 changes: 92 additions & 0 deletions
92
Content.Server/_LostParadise/CarnivoresDiet/PoorlyDigestible.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
using Content.Server.Nutrition.Components; | ||
using Content.Shared.Chemistry.Components; | ||
using Content.Shared.Chemistry.Reagent; | ||
using Content.Shared.FixedPoint; | ||
using Content.Shared.Tag; | ||
using Content.Shared.Whitelist; | ||
using Robust.Shared.GameObjects; | ||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace Content.Server.Body.Components | ||
{ | ||
[DataDefinition] | ||
public sealed partial class PoorlyDigestibleFood | ||
{ | ||
/// <summary> | ||
/// Reagents that get multiplied by the Factor field. | ||
/// </summary> | ||
[DataField("reducedReagents")] | ||
public List<string>? ReducedReagents = null; | ||
|
||
/// <summary> | ||
/// Food containing at least one of these tags is affected as long as it doesn't hit any BlacklistTags. | ||
/// </summary> | ||
[DataField("whitelistTags", customTypeSerializer: typeof(PrototypeIdListSerializer<TagPrototype>))] | ||
public List<string>? WhitelistTags = null; | ||
|
||
/// <summary> | ||
/// Food containing any of these tags is not affected. | ||
/// </summary> | ||
[DataField("blacklistTags", customTypeSerializer: typeof(PrototypeIdListSerializer<TagPrototype>))] | ||
public List<string>? BlacklistTags = null; | ||
|
||
/// <summary> | ||
/// Factor that the reagent quantities are multiplied by. | ||
/// </summary> | ||
[DataField("factor")] | ||
public FixedPoint2 Factor = 1f; | ||
|
||
/// <summary> | ||
/// Reagent that is used to replace the volume taken away by the Factor multiplication. | ||
/// </summary> | ||
[DataField("replacementReagent")] | ||
public string? ReplacementReagentID = null; | ||
|
||
public bool AffectsFood(EntityUid foodEnt, IEntityManager entityManager) | ||
{ | ||
if (WhitelistTags is null) | ||
return false; | ||
|
||
var tagSys = entityManager.System<TagSystem>(); | ||
|
||
if (BlacklistTags is not null && tagSys.HasAnyTag(foodEnt, BlacklistTags)) | ||
return false; | ||
|
||
return tagSys.HasAnyTag(foodEnt, WhitelistTags); | ||
} | ||
|
||
public Solution ModifySolution(Solution solution) | ||
{ | ||
// In case someone forgot to set the reagents being replaced, we do nothing. | ||
if (ReducedReagents is null || Factor <= 0f) | ||
return solution; | ||
|
||
// Recreating the list since we can't set quentities in-place. | ||
List<ReagentQuantity> newReagents = new(); | ||
FixedPoint2 removedQuantity = 0f; | ||
foreach (var quantity in solution.Contents) | ||
{ | ||
if (!ReducedReagents.Contains(quantity.Reagent.Prototype)) | ||
{ | ||
newReagents.Add(quantity); | ||
continue; | ||
} | ||
|
||
removedQuantity += quantity.Quantity; | ||
newReagents.Add(new ReagentQuantity(quantity.Reagent, quantity.Quantity * Factor)); | ||
} | ||
removedQuantity *= 1f - Factor; | ||
|
||
if (ReplacementReagentID is string reagentId) | ||
newReagents.Add(new ReagentQuantity(new ReagentId(reagentId, null), removedQuantity)); | ||
|
||
solution.SetContents(newReagents); | ||
return solution; | ||
} | ||
} | ||
} |
Binary file not shown.
Oops, something went wrong.