Jump to content

[1.10.1+] Contract Configurator [v1.30.5] [2020-10-05]


nightingale

Recommended Posts

Is there a way to make a contract complete instantly after accepting? (Requiring scene change is fine, I just mean has no objectives)

Edit: Scratch that, made it work with a timer set to 0s :)

Edit 2: If there's a better way to do the above, I'm still interested, but now I'd like to know how you make a one-time contract that never reappears if you decline it?

Edited by Rokanov
I have questions!
Link to comment
Share on other sites

Would there be anyway to check this to see is xyx is true on all of them?

    DATA
{
type = CelestialBody
orbitedmoons = HomeWorld().Parent() == Sun ? HomeWorld().Children() : HomeWorld().Parent().Children().Where(cb => cb.IsHomeWorld() == false)
}

So say HasLanded() == true, but for each one? I'm guessing it is similar to my other question about applying stuff to a list.

If that doesn't work maybe you could help me figure out what to do.

I have a series of contracts and I want them to be more or less completed in order. So I have requirements of complete x contract. The issue though is if someone were to install the pack in a existing game some contracts may not fire if someone has visited a certain body.

So my idea was to add another any requirement that if they have done x with any of this list of bodies, then it returns true.

Link to comment
Share on other sites

Would there be anyway to check this to see is xyx is true on all of them?

    DATA
{
type = CelestialBody
orbitedmoons = HomeWorld().Parent() == Sun ? HomeWorld().Children() : HomeWorld().Parent().Children().Where(cb => cb.IsHomeWorld() == false)
}

So say HasLanded() == true, but for each one? I'm guessing it is similar to my other question about applying stuff to a list.

If that doesn't work maybe you could help me figure out what to do.

I have a series of contracts and I want them to be more or less completed in order. So I have requirements of complete x contract. The issue though is if someone were to install the pack in a existing game some contracts may not fire if someone has visited a certain body.

So my idea was to add another any requirement that if they have done x with any of this list of bodies, then it returns true.

Something like this?


DATA
{
type = List<CelestialBody>
orbitedmoons = HomeWorld().Parent() == Sun ? HomeWorld().Children() : HomeWorld().Parent().Children().Where(cb => cb.IsHomeWorld() == false)
allMoonsWithSomething = @orbitedmoons.Where(cb => cb.HasLanded())
}

Or if you meant check in a requirement, then you can do something along these lines:


REQUIREMENT
{
type = expression
expression = @/orbitedmoons.Count() == @/allMoonsWithSomething.Count()
}

(or for a marginal efficiency improvement, reverse the allMoonsWithSomething's check, and then check whether it has a Count() of 0 in your expression.

- - - Updated - - -

Edit 2: If there's a better way to do the above, I'm still interested, but now I'd like to know how you make a one-time contract that never reappears if you decline it?

Careful of those late edits - you edited well after I read your original post. ;)

There isn't a better way - the contract system requires at least one parameter or it will fail. So to have "no" parameters, you need some sort of dummy parameter (and you can change the title to make it look better). Timer seems as good a choice as any.

I can't think of a way to make a contract that doesn't reappear if declined - mainly because the contract system doesn't store declined contracts (otherwise the save file would become massive). [#298] is coming up in 1.7.0 that will allow expressions to be fired when a contract is offered. You could hypothetically use that to set a flag and then prevent the contract from being offered again if that flag is set. But what'll likely happen is that the player will never see the contract - it'll come up and be withdrawn while they're timewarping and it'll never show up again.

Link to comment
Share on other sites

Careful of those late edits - you edited well after I read your original post. ;)

There isn't a better way - the contract system requires at least one parameter or it will fail. So to have "no" parameters, you need some sort of dummy parameter (and you can change the title to make it look better). Timer seems as good a choice as any.

I can't think of a way to make a contract that doesn't reappear if declined - mainly because the contract system doesn't store declined contracts (otherwise the save file would become massive). [#298] is coming up in 1.7.0 that will allow expressions to be fired when a contract is offered. You could hypothetically use that to set a flag and then prevent the contract from being offered again if that flag is set. But what'll likely happen is that the player will never see the contract - it'll come up and be withdrawn while they're timewarping and it'll never show up again.

Thanks for the warning, I'll be more mindful of edits in the future!

That makes sense, I think the system I have in place works well enough (pretty sure it's not really an intended use for contracts!).

I'll give that a try when 1.7.0 is out and see if it's better. It's for a one-time optional contract, so further generation is a bit spammy but otherwise unproblematic.

Next question :): Is there a straightforward way to provide RSS support for specific planets? Kerbin seems easy enough, using HomeWorld(), but what about others like Duna/Mars or Eve/Venus?

I.e. Currently I have targetBody = Duna, but want something that selects Duna or Mars depending on whether RSS is present. Think I've cracked it (see below), but I'm so new to this I prefer to ask :)


Data
{

[INDENT]type = CelestialBody
uniqueValue = true

targetPlanet = AllBodies().Where(p => p.Name() == "Duna" || p.Name() == "Mars").Random()[/INDENT]


}

Link to comment
Share on other sites

Thanks for the warning, I'll be more mindful of edits in the future!

That makes sense, I think the system I have in place works well enough (pretty sure it's not really an intended use for contracts!).

I'll give that a try when 1.7.0 is out and see if it's better. It's for a one-time optional contract, so further generation is a bit spammy but otherwise unproblematic.

Next question :): Is there a straightforward way to provide RSS support for specific planets? Kerbin seems easy enough, using HomeWorld(), but what about others like Duna/Mars or Eve/Venus?

I.e. Currently I have targetBody = Duna, but want something that selects Duna or Mars depending on whether RSS is present. Think I've cracked it (see below), but I'm so new to this I prefer to ask :)


Data
{

[INDENT]type = CelestialBody
uniqueValue = true

targetPlanet = AllBodies().Where(p => p.Name() == "Duna" || p.Name() == "Mars").Random()[/INDENT]


}

That or a Module Manager patch specifically tailored towards your contract pack are your best options. Depending on what you're going for, you can also try dividing up the planets in other ways without naming them (eg. all children of the homeworld, or everything with an sma less than the homeworld, etc.).

Link to comment
Share on other sites

Thanks. So theoretically this should work?


DATA
{
type = List<CelestialBody>
orbitedmoons = HomeWorld().Parent() == Sun ? HomeWorld().Children() : HomeWorld().Parent().Children().Where(cb => cb.IsHomeWorld() == false)
moonorbitedcount = @orbitedmoons.Where(cb => cb.HaveOrbited())
}

REQUIREMENT
{
type = Expression
expression = @/moonorbitedcount.Count() >= 1
}

Link to comment
Share on other sites

Having issues with Data node inheritance from parent contract group -> child group -> contract. As far as I understand it from the documentation, this should be possible (trimmed version of my code):


CONTRACT_GROUP
{
name = HistoricMissions

DATA
{
type = CelestialBody

targetMoon = HomeWorld().Children().Random()
}

CONTRACT_GROUP
{
name = LunaMission
}
}

CONTRACT_TYPE
{
name = Luna-1
group = LunaMission

targetBody = @HistoricMissions:targetMoon
}

However I keep getting errors:


[COLOR=#333333][LOG 02:14:28.327] [DEBUG] ContractConfigurator.ContractConfigurator: Loading CONTRACT_TYPE: 'Luna-1'[/COLOR]
[COLOR=#333333][ERR 02:14:28.328] ContractConfigurator.ContractType: CONTRACT_TYPE 'Luna-1': Error parsing targetBody[/COLOR]


[COLOR=#333333][EXC 02:14:28.329] ArgumentException: Contract group 'HistoricMissions' does not exist, or is not a parent of this contract.[/COLOR]
[COLOR=#333333]ContractConfigurator.ExpressionParser.DataNode.Nod eForKey (System.String& key)[/COLOR]
[COLOR=#333333]ContractConfigurator.ExpressionParser.DataNode.IsI nitialized (System.String key)[/COLOR]
[COLOR=#333333]ContractConfigurator.ExpressionParser.ExpressionPa rser`1[T].ParseSpecialIdentifier (ContractConfigurator.ExpressionParser.Token token)[/COLOR]
[COLOR=#333333]Rethrow as Exception: Error parsing statement.[/COLOR]
[COLOR=#333333]Error occurred near '*':[/COLOR]
[COLOR=#333333]@HistoricMissions:targetMoon[/COLOR]
[COLOR=#333333]............................* <-- HERE[/COLOR]
[COLOR=#333333]ContractConfigurator.ExpressionParser.ExpressionPa rser`1[T].ParseExpression (System.String key, System.String expression, ContractConfigurator.ExpressionParser.DataNode dataNode)[/COLOR]
[COLOR=#333333]ContractConfigurator.ConfigNodeUtil.ParseSingleVal ue[CelestialBody] (System.String key, System.String stringValue, Boolean allowExpression)[/COLOR]
[COLOR=#333333]ContractConfigurator.ConfigNodeUtil.ParseValue[CelestialBody] (.ConfigNode configNode, System.String key, Boolean allowExpression)[/COLOR]
[COLOR=#333333]ContractConfigurator.ConfigNodeUtil.ParseValue[CelestialBody] (.ConfigNode configNode, System.String key, System.Action`1 setter, IContractConfiguratorFactory obj, .CelestialBody defaultValue, System.Func`2 validation)[/COLOR]
[COLOR=#333333]UnityEngine.Debug:LogException(Exception)[/COLOR]
[COLOR=#333333]ContractConfigurator.LoggingUtil:LogException(Exce ption)[/COLOR]
[COLOR=#333333]ContractConfigurator.ConfigNodeUtil.P[/COLOR][COLOR=#333333]arseValue(ConfigNode, String, Action`1, IContractConfiguratorFactory, CelestialBody, Func`2)[/COLOR]
[COLOR=#333333]ContractConfigurator.ConfigNodeUtil.P[/COLOR][COLOR=#333333]arseValue(ConfigNode, String, Action`1, IContractConfiguratorFactory, CelestialBody)[/COLOR]
[COLOR=#333333]ContractConfigurator.ContractType:Load(ConfigNode)[/COLOR]
[COLOR=#333333]ContractConfigurator.<LoadContractConfig>d__1e:Mov eNext()[/COLOR]
[COLOR=#333333]ContractConfigurator.<ContractConfiguratorReload>d __13:MoveNext()[/COLOR]
[COLOR=#333333][ERR 02:14:28.331] ContractConfigurator.ReachStateFactory: CONTRACT_TYPE 'Luna-1', PARAMETER 'ReachState' of type 'ReachState': targetBody for ContractConfigurator.ReachStateFactory must be specified.[/COLOR]

Am I going wrong somewhere?

Link to comment
Share on other sites

Having issues with Data node inheritance from parent contract group -> child group -> contract. As far as I understand it from the documentation, this should be possible (trimmed version of my code):

<snip>

Am I going wrong somewhere?

Nope, you've stumbled on a bug. I've got it fixed now, it'll be released in 1.7.0 (ETA... maybe a week?). If you want to test it out now, you can grab the dev dll.

Link to comment
Share on other sites

Feature request: Would it be possible to split maxSimultaneous (in CONTRACT_GROUP) to allow separate values for maximum available (offered) and maximum active (accepted)?

For instance, I have contract1 and contract2 of the same group. maxAvailable is 2, so both show up in mission control, however maxActive is 1, so when one is accepted the other cannot be.

This is to get around issues I'm having with contracts that have similar objectives where I would like both to be visible and offered, but make it not possible for both to be completed in one go, though perhaps this is possible if I use define (in Parameter) better?

For now I think I'll use ActiveContract requirements. Actually that might work better anyway... :huh:

- - - Updated - - -

Actually I don't think that would work in this scenario:

contract1 and contract2 offered, both define vessel in parameters.

contract1 accepted, vessel1 launched, vessel = vessel1.

at this stage I'd like contract2 to be available, however under both circumstances it would be locked out until contract1 is completed, right?

So is there a way of setting a vessel in only one contract at a time (when both are active)?

i.e contract1 and contract2 accepted, vessel1 launched, tied to contract1 but not contract2

Link to comment
Share on other sites

Feature request: Would it be possible to split maxSimultaneous (in CONTRACT_GROUP) to allow separate values for maximum available (offered) and maximum active (accepted)?

For instance, I have contract1 and contract2 of the same group. maxAvailable is 2, so both show up in mission control, however maxActive is 1, so when one is accepted the other cannot be.

This is to get around issues I'm having with contracts that have similar objectives where I would like both to be visible and offered, but make it not possible for both to be completed in one go, though perhaps this is possible if I use define (in Parameter) better?

For now I think I'll use ActiveContract requirements. Actually that might work better anyway... :huh:

- - - Updated - - -

Actually I don't think that would work in this scenario:

contract1 and contract2 offered, both define vessel in parameters.

contract1 accepted, vessel1 launched, vessel = vessel1.

at this stage I'd like contract2 to be available, however under both circumstances it would be locked out until contract1 is completed, right?

So is there a way of setting a vessel in only one contract at a time (when both are active)?

i.e contract1 and contract2 accepted, vessel1 launched, tied to contract1 but not contract2

ActiveContract is the preferrred way of handling this.

Assuming that you are using different vessel identifiers for the two contracts, you can use the IsNotVessel parameter to make them mutually exclusive. If the parameters are similar enough though, it may cause trouble for the user, as they'll be unable to "choose" which of the two contracts the vessel should apply to (it'll mostly be the one that gets checked first, which will be the one that was accepted first... probably). So better than using IsNotVessel is finding some way to add a parameter that differentiates the two contracts. Can't give specific advice without more info, but HasCrew and PartValidation are good possibilities.

- - - Updated - - -

Oh, another option... if you want them to choose between both contracts, and then have the second one re-offered only when the first one's vessel gets defined you could do something like this (untested):

Contract1:

REQUIREMENT
{
type = Any

// Contract2 has not been accepted
REQUIREMENT
{
type = AcceptContract
[COLOR=#333333][FONT=Consolas]contractType = Contract2
[/FONT][/COLOR] minCount = 0
maxCount = 0
}

// Vessel2 has been defined
REQUIREMENT
{
type = Expression
expression = VesselIdentifier(Vessel2) != null
}
}

(Contract2 would be the same as Contract1, but mirrored)

Link to comment
Share on other sites

Hey all,

I've taken my first tiny steps in trying to create some contracts. Mostly I'm basing these off of Kerbin of Fire contracts to see how I should I write them.

Ran into an issue: I have created a contract group and 1 contract. The contract group shows up in the Configurator, the contract itself doesn't.

What am I doing wrong?

Here are the files:

// Author: Stealth17

CONTRACT_TYPE

{

name = sd1

group = SandDInkerbalized

title = Contact Spotted

description = General Jeb! There is a hostile craft approaching the KSC base. Eliminate this target in any way you see fit. We anticipate more contacts soon, so prepare for the worst. Command out.

synopsis = Search & Destroy the enemy craft.

completedMessage = Target Destroyed - RTB.

targetBody = HomeWorld()

agent = Search and Destroy Inkerbalized

cancellable = false

declinable = false

maxCompletions = 1

weight = 100

// Contract rewards

rewardScience = 30.0

rewardReputation = 5.0

rewardFunds = 15000.0

failureReputation = 0.0

failureFunds = 0.0

advanceFunds = 0.0

REQUIREMENT

{

name = CompleteContract

type = CompleteContract

contractType =

}

BEHAVIOUR

{

name = SpawnVessel

type = SpawnVessel

// The VESSEL node indicates a vessel to spawn and can be specified

// multiple times.

VESSEL

{

// If the name is not supplied, defaults from the name within the

// craft file. Note that this name behaves like the

// VesselParameterGroup define field - in other words, you may

// refer back to this vessel by this name in VesselParameterGroup

// parameters.

name = Target1-1

// Path to the .craft file (relative to the GameData/ directory)

craftURL = ContractPacks/SDmissions/ships/ScoutI.craft

// Location of the flag to use.

// Default = Player's flag for the current game

flagURL = Squad/Flags/satellite

// The type of vessel (affects display in the tracking station).

// Valid values from VesselType enum:

// Base

// Lander

// Probe

// Probe

// Ship (default)

// Station

// Unknown

vesselType = Unknown

// Whether the vessel should show up as owned or unowned. If it is

// owned, then it will be immediately selectable.

owned = False

targetBody = Kerbin

lat = 0.0833

lon = 75.0759

alt = 74.7130960650975

}

}

PARAMETER

{

name = TargetDestroyed

type = TargetDestroyed

// The vessel attribute is the *defined* name of the vessel that should

// not be destroyed. This is a name of a vessel defined either with

// the define attribute of a VesselParameterGroup parameter, or via a

// SpawnVessel.

//

// It can be specified multiple times, but there must be at least one.

vessel = Scout-I

// Text for the contract parameter.

// Default: Target destroyed

//title =

}

}

// Author: Stealth17

CONTRACT_GROUP

{

name = Search and Destroy InKerbalized

minVersion = 0.7.4

maxSimultaneous = 30

}

I would really appreciat any help you could offer!

Link to comment
Share on other sites


CONTRACT_GROUP
{
name = [B]Search and Destroy InKerbalized[/B]
minVersion = 0.7.4

maxSimultaneous = 30
}

// Author: Stealth17

CONTRACT_TYPE
{
name = sd1
[B]group = SandDInkerbalized[/B]

The two lines in bold need to match exactly. Otherwise CC will tell you that the group SandDinkerbalized doesn't exist. Also not sure how CC reacts to spaces in contract groups (but I've never tried it).


REQUIREMENT
{
name = CompleteContract
type = CompleteContract

contractType =
}

What exactly is this line doing? I think this is a requirement that can never be met (so it will never show up) as there is no contract to fufill.

PARAMETER
{
name = TargetDestroyed
type = TargetDestroyed

// The vessel attribute is the *defined* name of the vessel that should
// not be destroyed. This is a name of a vessel defined either with
// the define attribute of a VesselParameterGroup parameter, or via a
// SpawnVessel.
//
// It can be specified multiple times, but there must be at least one.

vessel = Scout-I



// Text for the contract parameter.
// Default: Target destroyed
//title =
}

I don't think you've actually defined Scout-I anywhere (but I could be wrong? maybe you defined it in a different contract?)

Edited by severedsolo
Link to comment
Share on other sites

Hey all,

I've taken my first tiny steps in trying to create some contracts. Mostly I'm basing these off of Kerbin of Fire contracts to see how I should I write them.

Ran into an issue: I have created a contract group and 1 contract. The contract group shows up in the Configurator, the contract itself doesn't.

What am I doing wrong?

<snip>

First off, I'll point you to the How-To page on the wiki. It has a couple sections that are crucial for someone using Contract Configurator for the first time - in particular using the debug window, which will most likely have the error message that lets you know what the problem here is.

Now, if you meant that it's not even showing up in the debug menu, then there's a couple things to check for (neither appear to be the problem here):

  1. Make sure the root CONTRACT_TYPE node is correctly spelled - if it's not then it'll just be silently ignored
  2. Make sure all your {} braces match up correctly. KSP's config file loader sometimes silently drops stuff if you miss an end brace.

That being said, I suspect when you load up the debug window I suspect you'll at least find an error for your CompleteContract requirement (the contractType is blank).

EDIT: Double ninja'd!!! But do check the debug window... it'll be invaluable as you continue to develop contracts.

- - - Updated - - -

<snip> Also not sure how CC reacts to spaces in contract groups (but I've never tried it). <snip>

It's allowed, but not recommended, as then you can't do @ContractGroup:someAttrtibute. It's actually why the displayName attribute was added:


[COLOR=#333333][I]CONTRACT_GROUP[/I][/COLOR]
[COLOR=#333333][I]{
[/I][/COLOR] name[B] = SandDInkerbalized[/B]
[COLOR=#333333][I] displayName = Search and Destroy InKerbalized[/I][/COLOR]
[COLOR=#333333][I] minVersion = 0.7.4[/I][/COLOR]

[COLOR=#333333][I] maxSimultaneous = 30[/I][/COLOR]
[COLOR=#333333][I]}[/I][/COLOR]

And since I'm looking at that... maxSimultaneous of 30 might as well be a million, as a player can't have more than 10-15 contracts without editing the Contracts.cfg. :)

Link to comment
Share on other sites

Nope, you've stumbled on a bug. I've got it fixed now, it'll be released in 1.7.0 (ETA... maybe a week?). If you want to test it out now, you can grab the dev dll.

Just saw this. It would explain the issue I was having earlier. I'll have to try the dev dll.

Link to comment
Share on other sites

Thanks for all the quick replies! I've managed to get it working. This is going to take a lot of learning and experimenting :)

You might want to create a github account/repository. Helps when you accidentally break something and need to revert.. :)

Link to comment
Share on other sites

Ok, so I'm a bit confused with the duration parameter. Or maybe I'm using it wrong?


PARAMETER
{
name = Home
type = VesselParameterGroup
vessel = HighOrbiter
title = Optionally orbit for 2d, or just return home.
completeInSequence = true

PARAMETER
{
name = Orbit
type = Orbit
situation = ORBITING
optional = true
minAltitude = @targetBody.SpaceAltitudeThreshold()

PARAMETER
{
name = Duration
type = Duration
duration = 2d

notes = (Optional) A longer orbit (2 day) gives extra rewards.

preWaitText = Orbiting for a additional two days will provide us with some valuable data.
waitingText = One more day should do.
completionText = Excellent, this will be very helpful.
rewardFunds = 5000 / @targetBody.Multiplier()
rewardScience = 2 / @targetBody.Multiplier()
}
}

PARAMETER
{
name = ReturnHome
type = ReturnHome
}
}

Ideally this gives you a optional objective to orbit for 2d. However, the duration never counts down and I never see the duration text.

So I thought I'd try putting the orbit as a parameter under the duration but then the duration just starts counting down right away.

Link to comment
Share on other sites

Ok, so I'm a bit confused with the duration parameter. Or maybe I'm using it wrong?


PARAMETER
{
name = Home
type = VesselParameterGroup
vessel = HighOrbiter
title = Optionally orbit for 2d, or just return home.
completeInSequence = true

PARAMETER
{
name = Orbit
type = Orbit
situation = ORBITING
optional = true
minAltitude = @targetBody.SpaceAltitudeThreshold()

PARAMETER
{
name = Duration
type = Duration
duration = 2d

notes = (Optional) A longer orbit (2 day) gives extra rewards.

preWaitText = Orbiting for a additional two days will provide us with some valuable data.
waitingText = One more day should do.
completionText = Excellent, this will be very helpful.
rewardFunds = 5000 / @targetBody.Multiplier()
rewardScience = 2 / @targetBody.Multiplier()
}
}

PARAMETER
{
name = ReturnHome
type = ReturnHome
}
}

Ideally this gives you a optional objective to orbit for 2d. However, the duration never counts down and I never see the duration text.

So I thought I'd try putting the orbit as a parameter under the duration but then the duration just starts counting down right away.

Couple things:

  1. You shouldn't use it as a child to the Orbit parameter - as the orbit parameter won't care about its child parameters.
  2. The way it's supposed to work, is the Duration counter will start counting down after every sibling above it in the list is completed. So you should be able to do it like this:

  • VesselParameterGroup
    • Orbit
    • Duration
    • ReturnHome

If that doesn't work, post up the config and I'll take a look.

Link to comment
Share on other sites

Ok, I'll try it. Thanks!

New issue though. :)

I'm trying to do some tests so I can do a initial release. Had stuff working pretty good until I added this DATA node into the CONTRACT_GROUP.

I don't know why but it seems to be causing some of my contracts to not appear in mission control.


CONTRACT_GROUP
{
name = RefinedProgression

minVersion = 1.6.6

CONTRACT_GROUP
{
name = CloseExplorer
maxSimultaneous = 3
}

CONTRACT_GROUP
{
name = FarExplorer
}

CONTRACT_GROUP
{
name = Routinely
maxSimultaneous = 2
}

DATA
{
type = List<CelestialBody>
orbitedmoons = HomeWorld().Parent() == Sun ? HomeWorld().Children() : HomeWorld().Parent().Children().Where(cb => cb.IsHomeWorld() == false)
orbitedmoonslist = @orbitedmoons.Where(cb => cb.HaveOrbited())
}
}

I'm really confused as to what is happening. Anything under a child CONTRACT_GROUP doesn't show up at all whether it references this DATA node or not. I used the dev DLL you provided a few posts before.

Link to comment
Share on other sites

Ok, I'll try it. Thanks!

New issue though. :)

I'm trying to do some tests so I can do a initial release. Had stuff working pretty good until I added this DATA node into the CONTRACT_GROUP.

I don't know why but it seems to be causing some of my contracts to not appear in mission control.

<snip>

I'm really confused as to what is happening. Anything under a child CONTRACT_GROUP doesn't show up at all whether it references this DATA node or not.

You'll want to be careful with putting that type of stuff under the contract group - you may want to consider using requiredValue = false:

[TABLE=width: 640]

[TR=bgcolor: #F8F8F8]

[TD=align: left]requiredValue[/TD]

[TD=align: left](Optional, default = true) If true, the expression needs to return a valid (non-null) value for the contract to be offered. If false, the contract will be offered even if the expression returns null[/TD]

[/TR]

[/TABLE]

What that doesn't say is it'll also fail if a list of values is empty. So because that node is in the group, it applies to all contracts within that group.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...