Modding:Active Parts: Difference between revisions

Jump to navigation Jump to search
14,194 bytes added ,  17:39, 13 August 2020
add scripting integration information
(put quotes around strings, explicate scanning properties)
(add scripting integration information)
Line 270: Line 270:
| true
| true
|}
|}
==Scripting integration==
===Introduction===
The most common way for parts to use <code>IActivePart</code> support is the <code>IsReady()</code> method. The example part below heals its parent object every turn:
<syntaxhighlight lang="csharp">
using System;
namespace XRL.World.Parts
{
    [Serializable]
    public class HealSelfEveryTurn : IActivePart
    {
        public HealSelfEveryTurn
        {
            WorksOnSelf = true;
        }
        public override bool WantEvent(int ID, int cascade)
        {
            return
                base.WantEvent(ID, cascade)
                || ID == EndTurnEvent.ID
            ;
        }
        public override bool HandleEvent(EndTurnEvent E)
        {
            if (IsReady(UseCharge: true))
            {
                ParentObject.Heal(1);
            }
            return true;
        }
    }
}
</syntaxhighlight>
In this very basic integration, the <code>UseCharge: true</code> parameter makes the part consume the amount of charge in its <code>ChargeUse</code> field. Without further configuration, this will have defaulted to 0. We want to call for charge to be used as the appropriate time to enable specific configurations that do use charge to be created.
This part is directly acting on its parent object, without checking any information about subjects provided by <code>IActivePart</code>. It sets <code>WorksOnSelf</code> because without any identifiable subject, the part will not be operational. Instances could set other subject-determining configuration points, which could change when the part works (since it won't work without a subject), but won't change what object the healing is applied to.  A more flexible integration could look like:
<syntaxhighlight lang="csharp">
using System;
namespace XRL.World.Parts
{
    [Serializable]
    public class HealEveryTurn : IActivePart
    {
        public override bool WantEvent(int ID, int cascade)
        {
            return
                base.WantEvent(ID, cascade)
                || ID == EndTurnEvent.ID
            ;
        }
        public override bool HandleEvent(EndTurnEvent E)
        {
            if (IsReady(UseCharge: true))
            {
                foreach (GameObject obj in GetActivePartSubjects())
                {
                    obj.Heal(1);
                }
            }
            return true;
        }
    }
}
</syntaxhighlight>
This part will need subject-determining configuration before it can operate. It will apply its healing to whatever subject or subjects are identified by that configuration, though, making it more powerful for designers to work with.
===Methods===
====IsReady()====
<syntaxhighlight lang="csharp">
public bool IsReady(
    bool UseCharge = false,
    bool IgnoreCharge = false,
    bool IgnoreBootSequence = false,
    bool IgnoreBreakage = false,
    bool IgnoreRust = false,
    bool IgnoreEMP = false,
    bool IgnoreRealityStabilization = false,
    bool IgnoreSubject = false,
    bool IgnoreLocallyDefinedFailure = false,
    int MultipleCharge = 1,
    int? ChargeUse = null,
    bool UseChargeIfUnpowered = false
)
</syntaxhighlight>
{| class="wikitable"
|-
! Parameter
! Behavior
|-
| UseCharge
| If true, an attempt will be made to consume any charge required by the part if it is not otherwise disabled. If false, charge will be checked for but not consumed.
|-
| IgnoreCharge
| If true, all considerations related to charge will be ignored.
|-
| IgnoreBootSequence
| If true, <code>IsBootSensitive</code> will be ignored.
|-
| IgnoreBreakage
| If true, <code>IsBreakageSensitive</code> will be ignored.
|-
| IgnoreRust
| If true, <code>IsRustSensitive</code> will be ignored.
|-
| IgnoreEMP
| If true, <code>IsEMPSensitive</code> will be ignored.
|-
| IgnoreRealityStabilization
| If true, <code>IsRealityDistortionBased</code> will be ignored.
|-
| IgnoreSubject
| If true, the part will not check for subjects or consider itself to be in SubjectNeeded status.
|-
| IgnoreLocallyDefinedFailure
| If true, <code>GetActivePartLocallyDefinedFailure()</code> will not be checked and the part will not consider itself to be in LocallyDefinedFailure status.
|-
| MultipleCharge
| Multiplies charge use in a fashion intended to represent operation over multiple turns. This means that <code>ChargeMinimum</code> is not multiplied, and that if charge is being consumed and not enough charge is available for the full set of multiples of charge use, charge will be consumed for however many multiples can be accommodated.
|-
| ChargeUse
| Overrides the part's <code>ChargeUse</code> setting for purposes of this call. The default of null means to use the part's <code>ChargeUse</code> setting.
|-
| UseChargeIfUnpowered
| With <code>UseCharge: false</code>, this parameter triggers consuming charge in the event that the part is otherwise operational but does not have enough charge. This is to allow certain process flows to ensure that they'll consume the last charge available in their parent object instead of leaving a tiny bit unused, which creates confusing UX with liquid-fueled energy cells.
|}
Returns true if the part's status is Operational. Triggers any appropriate render color changes. Updates the last known status.
====IsDisabled()====
<syntaxhighlight lang="csharp">
public bool IsReady(
    bool UseCharge = false,
    bool IgnoreCharge = false,
    bool IgnoreBootSequence = false,
    bool IgnoreBreakage = false,
    bool IgnoreRust = false,
    bool IgnoreEMP = false,
    bool IgnoreRealityStabilization = false,
    bool IgnoreSubject = false,
    bool IgnoreLocallyDefinedFailure = false,
    int MultipleCharge = 1,
    int? ChargeUse = null,
    bool UseChargeIfUnpowered = false
)
</syntaxhighlight>
The same as <code>IsReady()</code>, but with the opposite return value.
====GetActivePartStatus()====
<syntaxhighlight lang="csharp">
public ActivePartStatus GetActivePartStatus(
    bool UseCharge = false,
    bool IgnoreCharge = false,
    bool IgnoreBootSequence = false,
    bool IgnoreBreakage = false,
    bool IgnoreRust = false,
    bool IgnoreEMP = false,
    bool IgnoreRealityStabilization = false,
    bool IgnoreSubject = false,
    bool IgnoreLocallyDefinedFailure = false,
    int MultipleCharge = 1,
    int? ChargeUse = null,
    bool UseChargeIfUnpowered = false
)
</syntaxhighlight>
Identical to <code>IsReady()</code>, but returns an <code>ActivePartStatus</code> that can be used to determine what failure mode the part is in. Useful for constructing more helpful failure messaging.
Triggers any appropriate render color changes. Updates the last known status.
====WasReady()====
<syntaxhighlight lang="csharp">
public bool WasReady()
</syntaxhighlight>
Returns whether the active part's status was Operational the last time it was evaluated.
====WasDisabled()====
<syntaxhighlight lang="csharp">
public bool WasDisabled()
</syntaxhighlight>
Returns whether the active part's status was other than Operational the last time it was evaluated.
====GetLastActivePartStatus()====
<syntaxhighlight lang="csharp">
public ActivePartStatus GetLastActivePartStatus()
</syntaxhighlight>
Returns what the active part's status was the last time it was evaluated.
====ConsumeCharge()====
<syntaxhighlight lang="csharp">
public bool ConsumeCharge(int? ChargeUse = null)
</syntaxhighlight>
Triggers consumption of charge from the parent object, irrespective of operational status. The <code>ChargeUse</code> parameter can be used to override the part's <code>ChargeUse</code> setting; the default of null means do not override.
<syntaxhighlight lang="csharp">
public bool ConsumeCharge(int MultipleCharge, int? ChargeUse = null)
</syntaxhighlight>
As above, but <code>MultipleCharge</code> has the same behavior as for <code>IsReady()</code>.
====ConsumeChargeIfOperational()====
<syntaxhighlight lang="csharp">
public bool ConsumeChargeIfOperational(
    bool IgnoreBootSequence = false,
    bool IgnoreBreakage = false,
    bool IgnoreRust = false,
    bool IgnoreEMP = false,
    bool IgnoreRealityStabilization = false,
    bool IgnoreSubject = false,
    bool IgnoreLocallyDefinedFailure = false,
    int MultipleCharge = 1,
    int? ChargeUse = null,
    bool UseChargeIfUnpowered = false,
    bool NeedStatusUpdate = false
)
</syntaxhighlight>
Triggers consumption of charge from the parent object if the part is operational. Parameters that are also present in <code>IsReady()</code> behave the same as there.
Normally, status will only be obtained (and therefore color changes triggered and last known status updated) if there is any charge consumption to be performed. <code>NeedStatusUpdate</code> can be set to true to indicate that status should always be obtained.
====GetActivePartSubjects()====
<syntaxhighlight lang="csharp">
public virtual List<GameObject> GetActivePartSubjects()
</syntaxhighlight>
Returns a list of the active part's current subjects.
====GetActivePartFirstSubject()====
<syntaxhighlight lang="csharp">
public virtual GameObject GetActivePartFirstSubject()
</syntaxhighlight>
Returns the active part's first subject, or null if it has none.
<syntaxhighlight lang="csharp">
public virtual GameObject GetActivePartFirstSubject(Predicate<GameObject> Filter)
</syntaxhighlight>
Returns the first of the active part's subject that matches the filter specified, or null if none do.
====IsObjectActivePartSubject()====
<syntaxhighlight lang="csharp">
public virtual bool IsObjectActivePartSubject(GameObject obj)
</syntaxhighlight>
Returns whether the object specified is one of the active part's subjects.
====ActivePartHasMultipleSubjects====
<syntaxhighlight lang="csharp">
public virtual bool ActivePartHasMultipleSubjects()
</syntaxhighlight>
Returns whether the active part has at least two subjects.
====GetActivePartSubjectCount()====
<syntaxhighlight lang="csharp">
public virtual int GetActivePartSubjectCount()
</syntaxhighlight>
Returns how many subjects the active part has.
====ForeachActivePartSubjectWhile()====
<syntaxhighlight lang="csharp">
public virtual bool ForeachActivePartSubjectWhile(Predicate <GameObject> pProc, bool MayMoveAddOrDestroy = false)
</syntaxhighlight>
Calls <code>pProc</code> on each of the active part's subjects, terminating if <code>pProc</code> returns false. <code>MayMoveAddOrDestroy</code> should be set to true if the code in <code>pProc</code> might result in any object being moved, created, or destroyed.
====AnyActivePartSubjectWantsEvent()====
<syntaxhighlight lang="csharp">
public virtual bool AnyActivePartSubjectWantsEvent(int ID, int cascade)
</syntaxhighlight>
For integration with the <code>MinEvent</code> system. Returns true if any of the active part's subjects want to receive the event designated.
====ActivePartSubjectsHandleEvent()====
<syntaxhighlight lang="csharp">
public virtual bool ActivePartSubjectsHandleEvent(MinEvent E)
</syntaxhighlight>
For integration with the <code>MinEvent</code> system. Sends the event to each of the active part's subject, terminating early and returning false if any of the event handlers return false.
====GetActivePartLocallyDefinedFailure()====
<syntaxhighlight lang="csharp">
public virtual bool GetActivePartLocallyDefinedFailure()
</syntaxhighlight>
Intended to be overridden by inheritors to define their own failure conditions. Returns false by default; a locally defined failure will be considered to exist if it returns true.
====GetActivePartLocallyDefinedFailureDescription()====
<syntaxhighlight lang="csharp">
public virtual string GetActivePartLocallyDefinedFailureString()
</syntaxhighlight>
Intended to be overridden by inheritors to define the description to provide in status display for their own failure conditions. Returns null by default; a non-null return value will be used in place of "LocallyDefinedFailure" when displaying a LocallyDefinedFailure status.
====IsActivePartEngaged()====
<syntaxhighlight lang="csharp">
public virtual bool IsActivePartEngaged()
</syntaxhighlight>
Intended to be overridden by inheritors to define whether the part is "engaged" for purposes of <code>NeedsOtherActivePartEngaged</code>. Returns <code>IsReady()</code> by default.
====GetStatusSummary()====
<syntaxhighlight lang="csharp">
public virtual string GetStatusSummary(ActivePartStatus Status)
</syntaxhighlight>
For some specified status values, returns a string summary intended for player visibility. Some statuses return null, generally because it makes less sense to make them visible to the player. The status summaries are:
{| class="wikitable"
|-
! Status
! Summary
|-
| EMP
| <nowiki>"{{W|EMP}}"</nowiki>
|-
| Unpowered
| <nowiki>"{{K|unpowered}}"</nowiki>
|-
| SwitchedOff
| <nowiki>"{{K|switched off}}"</nowiki>
|-
| Booting (only if <code>BootSequence.IsObvious</code> is true)
| <nowiki>"{{b|warming up}}"</nowiki>
|-
| any other status besides Operational and NeedsSubject
| <nowiki>"{{r|nonfunctional}}"</nowiki>
|}
Can be overridden by inheritors to provide a status summary for LocallyDefinedFailure status or otherwise alter the default behavior.
<syntaxhighlight lang="csharp">
public string GetStatusSummary()
</syntaxhighlight>
Returns <code>GetStatusSummary(GetActivePartStatus())</code>.
====AddStatusSummary()====
<syntaxhighlight lang="csharp">
public void AddStatusSummary(StringBuilder SB)
</syntaxhighlight>
Retrieves <code>GetStatusSummary()</code> and, if it is not null or empty, appends <code>" ("</code>, the summary, and <code>")"</code> to the StringBuilder passed. This is to support code like this:
<syntaxhighlight lang="csharp">
public override bool HandleEvent(GetShortDescriptionEvent E)
{
    E.Postfix.AppendRules(AppendRulesDescription, AddStatusSummary);
    return true;
}
</syntaxhighlight>
====GetOperationalScopeDescription()====
<syntaxhighlight lang="csharp">
public string GetOperationalScopeDescription()
</syntaxhighlight>
Returns a readable general description of what objects the part operates on, based on its subject-determining configuration points. Example return values might be <code>its user</code> or <code>itself and its vicinity</code>.


==List of active parts==
==List of active parts==
671

edits

Navigation menu