Keen:Power Providers: Difference between revisions

From Medieval Engineers Wiki
Jump to navigation Jump to search
m (Protected "Official Content/Power Providers" ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite)))
mNo edit summary
Line 1: Line 1:
{{Header|Coming Soon}}
Some systems in the game need power to operate, and some other systems are capable of providing power. Power types in the game can be divided into two categories - physical power and other types of power. Physical power is the one that is generated in the physical game world and is used to power catapults, trebuchets, siege towers, elevators, trains, carts, and various other contraptions. The non-physical power, on the other hand, does not rely on any physical interaction, but rather purely on logic and animations. This guide will talk you through the non-physical power in general, concrete components that use it, and also how to create your own.
 
==IMyPowerProvider==
To simplify power generation and usage, there is the <code>IMyPowerProvider</code> interface. Requirements for power are very simple from the game logic perspective: you either have power, or you do not. There is no fuel power, no magical power, no electrical power, there is just an abstract notion of power instead. This power works in a very simple and straightforward way. There either is power, or there is no power, there is nothing in between.
 
The usage is very simple: there are components that implement <code>IMyPowerProvider</code> and other components, which ask for components that implement <code>IMyPowerProvider</code>. This makes it very easy to expand the power system, and very easy to plug in new power providers, just by making them implement this interface:
 
<source lang="csharp">
public interface IMyPowerProvider
{
    bool IsPowered { get; }
    event Action<IMyPowerProvider, bool> PowerStateChanged;
 
    bool IsReady { get; }
    event Action<IMyPowerProvider, bool> ReadyStateChanged;
 
    void TryStart();
    void TryStop();
}
</source>
 
'''IsPowered:''' this should return whether or not the component is currently supplying power.
 
'''PowerStateChanged:''' event that gets fired every time IsPowered changes. It also includes the new IsPowered state in the callback.
 
'''IsReady:''' whether or not this component is ready to be powered on.
 
'''ReadyStateChanged:''' event that gets fired every time IsReady changes. It also includes the new IsReady state in the callback.
 
'''TryStart():''' an outside request to be turned on and provide power.
 
'''TryStop():''' an outside request to be turned off and stop providing power.
 
 
In case you are creating a new component that is interested in getting power and it does not care about a specific implementation of a power provider, you can simply call: <code>var providers = Entity.Components.GetComponents<IMyPowerProvider>();</code> This will get all components from the entity that implement this interface. Whether you care about all of them is then up to you to decide.
 
 
==MyFuelComponent==
The fuel component is a power provider that turns items into power. Its common usage is ''Campfire'', ''Oven'', ''Furnace'' and other similar blocks that accept flammable items, to provide power for crafting. It can also be configured to consume any items of your liking and provide power for a predefined amount of time. As an example, let's define a fuel component for a Compost block.
 
===Definition===
<source lang="xml">
<Definition xsi:type="MyObjectBuilder_FuelComponentDefinition">
  <Id Type="FuelComponent" Subtype="Compost"/>
  <FuelInventory>CompostInventory</FuelInventory>
  <FuelTimes>
    <Fuel Tag="Fruit">
      <Time Seconds="60" />
    </Fuel>
    <Fuel Tag="Vegetable">
      <Time Seconds="60" />
    </Fuel>
    <Fuel Type="InventoryItem" Subtype="FlourWheat">
      <Time Seconds="12" />
    </Fuel>
    <Fuel Type="CubeBlock" Subtype="PumpkinCarved">
      <Time Minutes="1" />
    </Fuel>
  </FuelTimes>
</Definition>
</source>
 
'''Id:''' mandatory field, the type for this component is FuelComponent.
 
'''FuelInventory:''' subtype id of an inventory on the same entity, that is used to find fuel. If no inventory is specified, or the specified inventory is not found, it will try to find any inventory on the entity and use that.
 
'''FuelTimes:''' this tag just holds individual fuel times.
 
'''Fuel:''' a fuel entry. Can be specified by providing a Tag, or exact Type and Subtype of the items.
 
'''Time:''' specifies how long this fuel type lasts. Uses the time definition format.
 
 
{{TextBox|NOTICE: Explicit item ids take precedence over tags. So if you include a specific item, and also one or more of its tags, the value for the specific item will be used as fuel time.}}
 
===Event Bus Events===
The component fires two component events:
 
*'''FuelOn:''' this is called when the component is turned on and starts providing power.
*'''FuelOff:''' called when the component turns off and stops providing power (due to player interaction, fuel running out, etc.).
 
 
===Scripting===
This section will only go over events, properties and methods that are not part of the common <code>IMyPowerProvider</code> interface.
 
The following events can be hooked into by scripts:
<source lang="csharp">
public event Action<MyFuelComponent> TurnedOn;
public event Action<MyFuelComponent> TurnedOff;
public event Action<MyFuelComponent> FuelConsumed;
public event Action<MyFuelComponent> MissingFuel;
</source>
 
*'''TurnedOn:''' fired when the component is turned on and starts providing power.
*'''TurnedOff:''' fired when the component is turned off and no longer provides power.
*'''FuelConsumed:''' fired on successful fuel item consumption.
*'''MissingFuel:''' fired on unsuccessful fuel item consumption.
 
 
'''Properties:'''
 
<source lang="csharp">
public bool Enabled { get; private set; }
 
public MyDefinitionId? CurrentFuel { get; private set; }
 
public MyInventory Inventory { get; }
 
public float FuelProgress { get; }
       
public float MaxFuelTime;
</source>
 
*'''Enabled:''' whether or not this component is turned on (and providing power).
*'''Current Fuel:''' definition id of whatever item is currently being used to fuel the component.
*'''Inventory:''' inventory being used to search for potential fuel.
*'''FuelProgress:''' how much of the currently used fuel has been consumed. Values are in the range of 0 and 1, where 0 is 0% and 1 represents 100%.
*'''MaxFuelTime:''' how long the current fuel type can provide power.
 
 
'''Methods:'''
<source lang="csharp">
public void TurnOn();
 
public void TurnOff();
 
public long GetFuelTime(MyDefinitionId id);
</source>
 
*'''TurnOn():''' tries to start the fuel component. Equivalent to calling <code>IMyPowerProvier.TryStart()</code>.
*'''TurnOff():''' tries to stop the fuel consumption. Equivalent to calling <code>IMyPowerProvier.TryStop()</code>.
*'''GetFuelTime():''' returns how long an item with the definition id specified would last when used as fuel.
 
 
==MyMechanicalSinkComponent==
The mechanical sink is a part of the [[Official_Content/Mechanical_System|mechanical system]] and can also serve as a power provider for other components. Compared to <code>MyFuelComponent</code>, this one is significantly simpler. All this does is consume power from the mechanical system, and serve as a relay, instead of being an actual generator. This means that even its implementation of the <code>IMyPowerProvider</code> interface is very different:
 
'''IsPowered:''' returns true of the mechanical system this is attached to is providing power.
 
'''PowerStateChanged:''' event that gets fired every time IsPowered changes. It also includes the new IsPowered state in the callback.
 
'''IsReady:''' this is false because there is no way of starting or stopping this component from within itself.
 
'''ReadyStateChanged:''' event that gets fired every time IsReady changes. Since the IsReady value is always false, this event is not fired at all.
 
'''TryStart():''' this does nothing because the component cannot be started or stopped.
 
'''TryStop():''' this does nothing because the component cannot be started or stopped.
 
===Definition===
The definition does not contain any settings that are related to being a <code>IMyPowerProvider</code>. To see what the definition looks like, please refer to the [[Official_Content/Mechanical_System|mechanical system]].
 
 
[[Category:Keen_Modding_Guides]]
[[Category:Keen_Modding_Guides]]

Revision as of 16:06, 15 December 2017

Some systems in the game need power to operate, and some other systems are capable of providing power. Power types in the game can be divided into two categories - physical power and other types of power. Physical power is the one that is generated in the physical game world and is used to power catapults, trebuchets, siege towers, elevators, trains, carts, and various other contraptions. The non-physical power, on the other hand, does not rely on any physical interaction, but rather purely on logic and animations. This guide will talk you through the non-physical power in general, concrete components that use it, and also how to create your own.

IMyPowerProvider

To simplify power generation and usage, there is the IMyPowerProvider interface. Requirements for power are very simple from the game logic perspective: you either have power, or you do not. There is no fuel power, no magical power, no electrical power, there is just an abstract notion of power instead. This power works in a very simple and straightforward way. There either is power, or there is no power, there is nothing in between.

The usage is very simple: there are components that implement IMyPowerProvider and other components, which ask for components that implement IMyPowerProvider. This makes it very easy to expand the power system, and very easy to plug in new power providers, just by making them implement this interface:

public interface IMyPowerProvider
{
    bool IsPowered { get; }
    event Action<IMyPowerProvider, bool> PowerStateChanged;

    bool IsReady { get; }
    event Action<IMyPowerProvider, bool> ReadyStateChanged;

    void TryStart();
    void TryStop();
}

IsPowered: this should return whether or not the component is currently supplying power.

PowerStateChanged: event that gets fired every time IsPowered changes. It also includes the new IsPowered state in the callback.

IsReady: whether or not this component is ready to be powered on.

ReadyStateChanged: event that gets fired every time IsReady changes. It also includes the new IsReady state in the callback.

TryStart(): an outside request to be turned on and provide power.

TryStop(): an outside request to be turned off and stop providing power.


In case you are creating a new component that is interested in getting power and it does not care about a specific implementation of a power provider, you can simply call: var providers = Entity.Components.GetComponents<IMyPowerProvider>(); This will get all components from the entity that implement this interface. Whether you care about all of them is then up to you to decide.


MyFuelComponent

The fuel component is a power provider that turns items into power. Its common usage is Campfire, Oven, Furnace and other similar blocks that accept flammable items, to provide power for crafting. It can also be configured to consume any items of your liking and provide power for a predefined amount of time. As an example, let's define a fuel component for a Compost block.

Definition

<Definition xsi:type="MyObjectBuilder_FuelComponentDefinition">
  <Id Type="FuelComponent" Subtype="Compost"/>
  <FuelInventory>CompostInventory</FuelInventory>
  <FuelTimes>
    <Fuel Tag="Fruit">
      <Time Seconds="60" />
    </Fuel>
    <Fuel Tag="Vegetable">
      <Time Seconds="60" />
    </Fuel>
    <Fuel Type="InventoryItem" Subtype="FlourWheat">
      <Time Seconds="12" />
    </Fuel>
    <Fuel Type="CubeBlock" Subtype="PumpkinCarved">
      <Time Minutes="1" />
    </Fuel>
  </FuelTimes>
</Definition>

Id: mandatory field, the type for this component is FuelComponent.

FuelInventory: subtype id of an inventory on the same entity, that is used to find fuel. If no inventory is specified, or the specified inventory is not found, it will try to find any inventory on the entity and use that.

FuelTimes: this tag just holds individual fuel times.

Fuel: a fuel entry. Can be specified by providing a Tag, or exact Type and Subtype of the items.

Time: specifies how long this fuel type lasts. Uses the time definition format.


NOTICE: Explicit item ids take precedence over tags. So if you include a specific item, and also one or more of its tags, the value for the specific item will be used as fuel time.

Event Bus Events

The component fires two component events:

  • FuelOn: this is called when the component is turned on and starts providing power.
  • FuelOff: called when the component turns off and stops providing power (due to player interaction, fuel running out, etc.).


Scripting

This section will only go over events, properties and methods that are not part of the common IMyPowerProvider interface.

The following events can be hooked into by scripts:

public event Action<MyFuelComponent> TurnedOn;
public event Action<MyFuelComponent> TurnedOff;
public event Action<MyFuelComponent> FuelConsumed;
public event Action<MyFuelComponent> MissingFuel;
  • TurnedOn: fired when the component is turned on and starts providing power.
  • TurnedOff: fired when the component is turned off and no longer provides power.
  • FuelConsumed: fired on successful fuel item consumption.
  • MissingFuel: fired on unsuccessful fuel item consumption.


Properties:

public bool Enabled { get; private set; }

public MyDefinitionId? CurrentFuel { get; private set; }

public MyInventory Inventory { get; }

public float FuelProgress { get; }
        
public float MaxFuelTime;
  • Enabled: whether or not this component is turned on (and providing power).
  • Current Fuel: definition id of whatever item is currently being used to fuel the component.
  • Inventory: inventory being used to search for potential fuel.
  • FuelProgress: how much of the currently used fuel has been consumed. Values are in the range of 0 and 1, where 0 is 0% and 1 represents 100%.
  • MaxFuelTime: how long the current fuel type can provide power.


Methods:

public void TurnOn();

public void TurnOff();

public long GetFuelTime(MyDefinitionId id);
  • TurnOn(): tries to start the fuel component. Equivalent to calling IMyPowerProvier.TryStart().
  • TurnOff(): tries to stop the fuel consumption. Equivalent to calling IMyPowerProvier.TryStop().
  • GetFuelTime(): returns how long an item with the definition id specified would last when used as fuel.


MyMechanicalSinkComponent

The mechanical sink is a part of the mechanical system and can also serve as a power provider for other components. Compared to MyFuelComponent, this one is significantly simpler. All this does is consume power from the mechanical system, and serve as a relay, instead of being an actual generator. This means that even its implementation of the IMyPowerProvider interface is very different:

IsPowered: returns true of the mechanical system this is attached to is providing power.

PowerStateChanged: event that gets fired every time IsPowered changes. It also includes the new IsPowered state in the callback.

IsReady: this is false because there is no way of starting or stopping this component from within itself.

ReadyStateChanged: event that gets fired every time IsReady changes. Since the IsReady value is always false, this event is not fired at all.

TryStart(): this does nothing because the component cannot be started or stopped.

TryStop(): this does nothing because the component cannot be started or stopped.

Definition

The definition does not contain any settings that are related to being a IMyPowerProvider. To see what the definition looks like, please refer to the mechanical system.