Closed Acruid closed 3 years ago
Make some Reagent prototype.
This reagent prototype should implement some IMetabolizable interface.
Metabolizer can be a Component on mobs or whatever with an enum type.
The Metabolizer loops through a List
The implementation of such an IMetabolizable would look something like this initially:
public class Beer : IMetabolizable
{
private int Strength;
public void Metabolize(Metabolizer metabolizer, float frameTime){
metabolizer.dizzness+=Strength * frameTime;
}
}
But if you want the metabolizers type to infuence that, say a metabolism reacts differently to a reagent. You need to either:
public void Metabolize(Metabolizer metabolizer, float frameTime){
switch(metabolizer.Type)
{
case(Cat):
MyPrivateMethod();
break;
case(Human):
default:
metabolizer.dizzness+= Strength * frameTime
break;
}
}
But that would be disgusting. Instead add a dictionary that can be filled via YML on the Reagent prototype. Then the implementation could look like this:
public void Metabolize(Metabolizer metabolizer, float frameTime){
{
if(_dictionary.TryGetValue(metabolizer.Type, out var strategy))
{
strategy.Metabolize(metabolizer, frameTime);
}
}
The resulting YML could look a little like this:
- type:reagent
name: beer
- type: handler
metabolism: cat
behavior:
- type: DoThing
- type: handler
metabolism: human
behavior:
- type: MakeDizzy
With a MakeDizzy implementation as such:
public class MakeDizzy : IMetabolizable
{
public void Metabolize(Metabolizer metabolizer, float frameTime){
{
metabolizer.dizzness+=10 * frameTime
}
}
Because the specific behaviors are defined genericly they can also be initialized with different values:
- type:reagent
name: beer
- type: handler
metabolism: human
behavior:
- type: MakeDizzy
strength: 5
- type: AddFood
nutrition: 5
- type:reagent
name: fancy beer
- type: handler
metabolism: human
behavior:
- type: MakeDizzy
strength: 8
- type: AddFood
nutrition: 8
- type:reagent
name: vodka
- type: handler
metabolism: human
behavior:
- type: MakeDizzy
strength: 40
In the YML you could even define a some extra behaviors bound as a field. Maybe a default behavior that happens only when the reagent doesn't have a handler for your MetabolismType. And a default behavior that just always happens. Beer's YML could look a little like this:
- type:reagent
name: beer
- type: handler
defaultExcludedBehavior:
- type: MakeDizzy
- type: AddFood
- type: handler
metabolism: rockPeople
behavior:
- type: AddFood
Pretty sure I'm messing up how to write YML here so take it all with a grain of salt.
Reagents can also interact with things outside a Metabolizer. Like splashing uranium or plasma on the floor or throwing thermite on a wall. Spraying people in the face with a bottle of soap also comes to mind. You could add simple strategy fields to the Reagent prototype. These would implement a specific interface like ITileSplasher or IAirExposable. When a reagent is then asked to perform the tile splashing or face touching or whatever it can just call the relevant interface where the reagent's interaction with different components is defined.
Define recipes somewhere else. Honestly outside the scope of this issue but since we're revved up. Recipes being the way they are in SS13 seems fine tbh. Where you define reagents, the required ratios, the resulting reagent, what happens after (think potasium and water), any catalysts or temperatures that need to (not) be present. Solutions can check for recipes when their contents change (ss13 does this) or on a tick call or whatever (how to not call all solutions every tick though?).
Could you assign me to this issue?
It's been a while since this issue was made, so I figure it's a good time to make a post with up to date info on this feature. Below are some key parts of chemistry and their statuses:
Lemme know if there's anything important missing, and I'll try to keep this issue up to date.
Is there anything left to do in regards of this issue, or can it be closed already?
@Zumorica Moneyl's comment still has some unticked boxes.
Yeah all the things that are unchecked in that list aren't done yet. The "Status effects on mobs when they ingest, inject, or have chemicals spilled on them" one is partially done. We have a bunch of common chem recipes from vg and a system for metabolism effects, but almost none of the chems have their metabolism or environmental effects implemented.
If we want to use this as a general chemistry feature issue it's not complete. Do you think it'd be a good idea to close this issue and open a bunch of smaller issues for the unchecked things in that list? Might make it easier for people to pick the larger feature apart rather than having to find this issue and read to the bottom.
Do you think it'd be a good idea to close this issue and open a bunch of smaller issues for the unchecked things in that list?
Yeah, I personally think that'd be much better for the reasons you listed. I'll leave the final decision in regards to closing this issue to the people who've actually coded chemistry though.
Entities need to be able to contain reagents, and this system controls it.