Jump to content

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


nightingale

Recommended Posts

Hello again.

I've been working on my contract idea on and off in spare moments over the past week or so, and I think I have the shape of it pretty much right. I kept coming up with an issue that didn't seem to make sense, though, because I think I'd confused myself on something. The requirement "HasCrew", I'm pretty sure, refers to the entire space program, right? That's the entire collection of Kerbals you've hired? But the parameter "HasCrew" seems to be specific to a single vessel. Is that right? If so, is there a parameter that corresponds to the "HasCrew" requirement?

Link to comment
Share on other sites

So, I just got a contract under SS Lite, to do a BIOME scan of the Sun. Now, this is not a valid contract... as Sun has no biomes.

Is there any kind of logic checking I can introduce to make sure that sun (and probably jool) are not returned as valid targets?

Biome mapping of the Sun or Jool is possible, as is terrain mapping.

The bigger problem is just mapping of the sun in general. The dV requirements to get into the correct orbit are insane, so really it should just be excluded entirely.

Link to comment
Share on other sites

Hello again.

I've been working on my contract idea on and off in spare moments over the past week or so, and I think I have the shape of it pretty much right. I kept coming up with an issue that didn't seem to make sense, though, because I think I'd confused myself on something. The requirement "HasCrew", I'm pretty sure, refers to the entire space program, right? That's the entire collection of Kerbals you've hired? But the parameter "HasCrew" seems to be specific to a single vessel. Is that right? If so, is there a parameter that corresponds to the "HasCrew" requirement?

Done for next version, it's called HasAstronaut and takes the same inputs as the HasCrew requirement (which is now renamed to HasAstronaut for consistency). Test it on the dev version here if you like, otherwise it'll be in the next release in a few days.

Link to comment
Share on other sites

Done for next version, it's called HasAstronaut and takes the same inputs as the HasCrew requirement (which is now renamed to HasAstronaut for consistency). Test it on the dev version here if you like, otherwise it'll be in the next release in a few days.

Marvelous! In that case, I'll run away with the dev version this weekend, and maybe figure out how to put things on github, on the off chance there's anyone else out there who wants to work with the Kerbal Resources department and get paid for training up their crews. Thanks. :)

Link to comment
Share on other sites

Biome mapping of the Sun or Jool is possible, as is terrain mapping.

The bigger problem is just mapping of the sun in general. The dV requirements to get into the correct orbit are insane, so really it should just be excluded entirely.

What, you don't want to do a difficult gravity-assisted inclination change at Jool? Followed up by a ridiculous burn to reduce your Ap?

Link to comment
Share on other sites

Biome mapping of the Sun or Jool is possible, as is terrain mapping.

The bigger problem is just mapping of the sun in general. The dV requirements to get into the correct orbit are insane, so really it should just be excluded entirely.

I don't think it should be disabled just because it's difficult. If they can do it good on them and they should be rewarded handsomely. Just don't give them a commensurately large advance that they could abuse as a loan for other missions. That way they only take it if they feel they are ready for it.

Link to comment
Share on other sites

I'm working on an AntennaRange contract pack, and I want to make it general rather than planet-specific by using the list syntax, but I'm running into difficulties. Here's my targetBody selection:


targetBody = Homeworld().Children().Where(b => !OrbitedBodies().Contains().Random()

(This one is for the contracts to the homeworld's moons, which use a different dish than all of the other bodies, which has a much more complicated expression. First things first.)

However, the system grumbles that targetBody isn't set (for the Orbit PARAMETER), and when I try to verify that it's non-null as an Expression REQUIREMENT that Homeworld().Children().Where(b => !OrbitedBodies().Contains(B)).Count() > 0, the system grumbles that Expression evaluates to a double instead of a boolean. Do I need more parentheses to hold Contract Configurator's hand through the order of operations?

Link to comment
Share on other sites

I'm working on an AntennaRange contract pack, and I want to make it general rather than planet-specific by using the list syntax, but I'm running into difficulties. Here's my targetBody selection:


targetBody = Homeworld().Children().Where(b => !OrbitedBodies().Contains().Random()

(This one is for the contracts to the homeworld's moons, which use a different dish than all of the other bodies, which has a much more complicated expression. First things first.)

However, the system grumbles that targetBody isn't set (for the Orbit PARAMETER), and when I try to verify that it's non-null as an Expression REQUIREMENT that Homeworld().Children().Where(b => !OrbitedBodies().Contains(B)).Count() > 0, the system grumbles that Expression evaluates to a double instead of a boolean. Do I need more parentheses to hold Contract Configurator's hand through the order of operations?

Actually, I based it off the C# operator precedence (which is pretty much the same as any other language), and unary not (!) has one of the highest precedences. So Contract Configurator is doing what you're telling it to. :) Since Count() is unsigned, you can just rewrite that as xxx.Count() == 0. That being said, what you found sounds like a bug. The expression requirement should work as a workaround, but I'll get the main issue fixed for the next release (which should be pretty soon).

Link to comment
Share on other sites

Actually, I based it off the C# operator precedence (which is pretty much the same as any other language), and unary not (!) has one of the highest precedences. So Contract Configurator is doing what you're telling it to. :) Since Count() is unsigned, you can just rewrite that as xxx.Count() == 0. That being said, what you found sounds like a bug. The expression requirement should work as a workaround, but I'll get the main issue fixed for the next release (which should be pretty soon).

When you say unary not has the highest precedence, does that mean that the Where expression is saying "(not OrbitedBodes) contains"? That sounds like the opposite of what I want, which is "not (OrbitedBodies contains)".

(Actually, it would be great if there were a way to poll the ships which orbit the various bodies -- then I could pick a body which doesn't have enough ships in orbit around it, or even not enough ships with dishes in orbit, rather than just guessing that a body which has been orbited at some point probably has a relay.)

Link to comment
Share on other sites

First off - this is what I see when using your expression:

[ERR 20:24:07.814] ContractConfigurator.ContractType: CONTRACT_TYPE 'TargetBodyTest': Error parsing targetBody[EXC 20:24:07.817] MissingMethodException: Cannot find function 'Homeworld' for class 'CelestialBody'.
ContractConfigurator.ExpressionParser.ExpressionParser`1[T].GetCalledFunction (System.String functionName, Function& selectedMethod, Boolean isFunction)
ContractConfigurator.ExpressionParser.ExpressionParser`1[CelestialBody].ParseMethod[CelestialBody] (ContractConfigurator.ExpressionParser.Token token, .CelestialBody obj, Boolean isFunction)
Rethrow as Exception: Error parsing statement.
Error occurred near '*':
Homeworld().Children().Where(b => !OrbitedBodies().Contains().Random()
..........* <-- HERE
ContractConfigurator.ExpressionParser.ExpressionParser`1[T].ParseExpression (System.String key, System.String expression, ContractConfigurator.ExpressionParser.DataNode dataNode)
ContractConfigurator.ConfigNodeUtil.ParseSingleValue[CelestialBody] (System.String key, System.String stringValue, Boolean allowExpression)
ContractConfigurator.ConfigNodeUtil.ParseValue[CelestialBody] (.ConfigNode configNode, System.String key, Boolean allowExpression)
ContractConfigurator.ConfigNodeUtil.ParseValue[CelestialBody] (.ConfigNode configNode, System.String key, System.Action`1 setter, IContractConfiguratorFactory obj, .CelestialBody defaultValue, System.Func`2 validation)
UnityEngine.Debug:LogException(Exception)
ContractConfigurator.LoggingUtil:LogException(Exception)
ContractConfigurator.ConfigNodeUtil:ParseValue(ConfigNode, String, Action`1, IContractConfiguratorFactory, CelestialBody, Func`2)
ContractConfigurator.ConfigNodeUtil:ParseValue(ConfigNode, String, Action`1, IContractConfiguratorFactory, CelestialBody)
ContractConfigurator.ContractType:Load(ConfigNode)
ContractConfigurator.<LoadContractConfig>d__14:MoveNext()
ContractConfigurator.ContractConfigurator:Update()

Not sure if that's something you missed, or it was a transcription error when posting (the correct function is HomeWorld()). After I fixed that everything seemed to behave fine.

When you say unary not has the highest precedence, does that mean that the Where expression is saying "(not OrbitedBodes) contains"? That sounds like the opposite of what I want, which is "not (OrbitedBodies contains)".

Actually, I was referring to your second expression:

[COLOR=#3E3E3E]Homeworld().Children().Where(b => !OrbitedBodies().Contains().Count() > 0)[/COLOR]

And what I mean is that it is equivalent to:

[color=#3E3E3E]Homeworld().Children().Where(b => (!OrbitedBodies().Contains().Count()) > 0)[/color]

Which I think is why you see the double/bool conversion error (although I would've expected int, but whatever. :)

(Actually, it would be great if there were a way to poll the ships which orbit the various bodies -- then I could pick a body which doesn't have enough ships in orbit around it, or even not enough ships [i]with dishes[/i] in orbit, rather than just guessing that a body which has been orbited at some point probably has a relay.)

Well, there's AllVessels().Where(v => v.CelestialBody() == @targetBody), but nothing to go from body to vessels (I can add it if you need it). You can also do AllVessels().Where(v => v.Parts().Where(p => p....)).... hmm... that's not right. Realized that I don't have much in the way of functions for parts. I'll need to add at least part name. I don't not want to get into part modules though as that would be scary performance wise (I'm already worried about the AllVessels => Parts could be huge).

EDIT: Oh right, there's no name because you just convert it to a string to get the name. Note the expression below will only work on the dev build (quoted strings have only recently been introduced):

AllVessels().Where(v => v.Parts().Where(p => p == "SomeCoolAntenna").Count() > 0)

Link to comment
Share on other sites

(the correct function is HomeWorld()).

You got me. No fair misspelling "homeworld" in your API -- it's one word! ;)

Regarding the search-by-partmodule, it's not really necessary -- I see how it would eventually overwhelm performance. (Strictly speaking, I'd have to search by ships, parts, PartModules, and then identify which PartModules have enough range to reach back to the homeworldin case the user has parts from other mods, for extra CPU-meltage.) Counting ships should do the trick. Thanks!

Edited by Kerbas_ad_astra
Link to comment
Share on other sites

You got me. No fair misspelling "homeworld" in your API -- it's one word! ;)

Don't blame me, it's the spanish spelling. :D

In most cases, I opt for consistency with Squad over correctness. Except for the OnScienceRecieved event. That one drives me insane every time I see it. Also, they changed the function signature on that one twice recently (1.0 and 1.0.1), so they missed to opportunities to fix the typo (since they are breaking mods using it anyway).

Link to comment
Share on other sites

Don't blame me, it's the spanish spelling. :D

In most cases, I opt for consistency with Squad over correctness. Except for the OnScienceRecieved event. That one drives me insane every time I see it. Also, they changed the function signature on that one twice recently (1.0 and 1.0.1), so they missed to opportunities to fix the typo (since they are breaking mods using it anyway).

Fixing HomeWorld() helped, but I'm still not getting a body out of my functions (they return "empty"). The upper one is the one that I think I want in the end, and the lower one is a simpler one that I've tried for testing:


targetBody1 = HomeWorld().Children().Where(b => (AllVessels().Where( v => ( (v.CelestialBody() == && (v.IsOrbiting()) ) ).Count() < 4) ).Random()
targetBody1 = HomeWorld().Children().Where(b => !(OrbitedBodies().Contains() ).Random()

How complicated is the evaluation formula in a Where() statement allowed to get?

EDIT: Well, the debug menu didn't seem to evaluate the second one, but I got a contract with it, so now I'm trying the first, and we'll see how it goes...

EDIT 2: One more question. When setting an Orbit parameter, what's the difference between maxApA and maxAltitude?

Edited by Kerbas_ad_astra
Link to comment
Share on other sites

Decline other contracts until is shows back up.

The one in particular was to build a ground Mun station. I misclicked and declined it, but it has yet to show up again. I now have the "build a Minmus" base one, which I have accepted. Seems like I may have to go into my persistent file to get it back and I recall that it can be edited to have contracts reappear. Or is it permanently skipped as I've accepted the Minmus one (that's assuming that the progression happens to be linear).

Edited by Addesso
Link to comment
Share on other sites

Declining a mission doesn't stop it coming back. You just need to decline more missions so it has a chance of showing back up. Having said that none of the CC packs yet have ground bases yet (I believe) so that is a stock mission, and what I have said above is still true and there is almost no progression there. You could still get missions to make Kerbin stations in stock after having colonised the entire Jool system, in stock.

Link to comment
Share on other sites

Is there any ContractConfigurator mission so far, which deals with asteroids?

Eg defining the paramters to check whether docking with an asteroid is completed.

I can not spawn my own asteroid, as that would limit the timeframe of the mission.

Also I can not use asteroidSample to determine a successful asteroid mission, because I want the first mission to be completeable by probes.

Link to comment
Share on other sites

Fixing HomeWorld() helped, but I'm still not getting a body out of my functions (they return "empty"). The upper one is the one that I think I want in the end, and the lower one is a simpler one that I've tried for testing:


targetBody1 = HomeWorld().Children().Where(b => (AllVessels().Where( v => ( (v.CelestialBody() == && (v.IsOrbiting()) ) ).Count() < 4) ).Random()
targetBody1 = HomeWorld().Children().Where(b => !(OrbitedBodies().Contains() ).Random()

How complicated is the evaluation formula in a Where() statement allowed to get?

Well, there's no limits that Contract Configurator places on it, and as far as I know the text in a ConfigNode attribute doesn't have limits. So the limit is when KSP starts getting "chunky" when generating new contracts. And good test is to hit the "clear all active contracts" button in the debug menu - that'll cause a whole set to be regenerated.

EDIT: Well, the debug menu didn't seem to evaluate the second one, but I got a contract with it, so now I'm trying the first, and we'll see how it goes...

EDIT 2: One more question. When setting an Orbit parameter, what's the difference between maxApA and maxAltitude?

I had to look up the code, which is a sure sign that I need to fix the documentation. The following formulas are used to determine if the condition is met for altitude/ApA/PeA:

minAltitude <= PeA <= ApA <= maxAltitude

minApA <= ApA <= maxApA

minPeA <= PeA <= maxPeA

So basically, if you don't specify both a min/max then maxAltitude and maxApA are the same. If you specify a min/max then both the PeA and ApA must fall within the range. Think of it as a shortcut to specifying all four of [min/max][ApA/Pea].

Is there any ContractConfigurator mission so far, which deals with asteroids?

Eg defining the paramters to check whether docking with an asteroid is completed.

I can not spawn my own asteroid, as that would limit the timeframe of the mission.

Also I can not use asteroidSample to determine a successful asteroid mission, because I want the first mission to be completeable by probes.

When you say missions - then no, there's nothing out there in the wild using asteroids (well, I suppose there some minor stuff in Tourism Plus). If the goal is to grapple it with the claw, then it's fairly easy, you can just do a PartValidation that checks for the Asteroid module (this is done here as an example).

If you want to have a contract that says "rendezvous with any asteroid", then I think I may have a solution. Have a rendezvous with a "named" vessel, and have another parameter that sets the named vessel as any asteroid (it'll get set to the first asteroid the player rendezvous with anyway). Untested, but try this:

PARAMETER{
name = Asteroid
type = VesselParameterGroup


define = An Asteroid
title = Find an asteroid


PARAMETER
{
name = VesselIsType
type = VesselIsType


// Type of vessel to check for. Valid values are a subset from the
// VesselType enum:
// Base
// EVA
// Lander
// Probe
// Rover
// Ship
// Station
vesselType = SpaceObject
}
}


PARAMETER
{
name = RendezvousShip
type = VesselParameterGroup


title = Rendezvous with the asteroid


PARAMETER
{
name = Rendezvous
type = Rendezvous


// The vessel attribute is the *defined* name of the vessel that must
// participate in the rendezvous event. This is a name of a vessel
// defined either with the define attribute of a VesselParameterGroup
// parameter, or via a SpawnVessel.
//
// If this Rendezvous parameter is a child of a VesselParameterGroup
// parameter, then no more than *one* vessel should be provided (the
// other is the vessel being tracked under the VesselParameterGroup).
// If no vessel attributes are provided, the second vessel will match
// any vessel.
//
// If this Rendezvous parameter is NOT a child of a VesselParameterGroup,
// then *at least one* vessel must be provided. If only one vessel is
// provided, then the second vessel will match any vessel.
vessel = An Asteroid


// Distance in meters that defines a rendezvous as having occurred.
// Default = 2000.0
distance = 2500.0


// Text for the contract parameter.
// Default varies depending on the situation.
//title =
}
}

Note that the IsVessel documentation lies - you can use any value (so SpaceObject is valid). I'll fix that.

If you try that one out, let me know how it goes and whether you have to do weird stuff like cycling through vessels to get things to fire. Ideally you should be able to get the asteroid one to fire once you get in physics range of the asteroid without making it the active vessel... but I'm not 100% sure.

Link to comment
Share on other sites

Hey, just getting started diving into the Contract-Configurator! And really enjoying working out these new contracts.

Just wanted to drop a line and say a BIG THANK YOU to Nightingale (and anyone else who may have contributed) for the great documentation and well done wiki :D

Thanks again for putting this together.

Edited by rabidninjawombat
Link to comment
Share on other sites

Hey, just getting started diving into the Contract-Configurator! And really enjoying working out these new contracts.

Just wanted to drop a line and say a BIG THANK YOU to Nightingale (and anyone else who may have contributed) for the great documentation and well done wiki :D

Thanks again for putting this together.

Thanks, and I wish you best of luck in getting whatever it is your working on released! I've seen too many people with neat ideas that never quite made it to fruition.

And if you need assistance, you can always drop by the thread and I should be able to answer within a day (at least).

Link to comment
Share on other sites

Thanks, and I wish you best of luck in getting whatever it is your working on released! I've seen too many people with neat ideas that never quite made it to fruition.

And if you need assistance, you can always drop by the thread and I should be able to answer within a day (at least).

Thanks! I did have a quick question. Is there a PARAMETER for checking completion of a scan using the new stock orbital scanner parts that dropped with 1.0 yet? Or is there a possible way to detect completion even if their isnt?

Link to comment
Share on other sites

Thanks! I did have a quick question. Is there a PARAMETER for checking completion of a scan using the new stock orbital scanner parts that dropped with 1.0 yet? Or is there a possible way to detect completion even if their isnt?

There is not, but it's one of the things I meant to look at more closely with the 1.0 release but haven't yet. Raised [#210] to track - comment there if you have more specific requirements. Trying to get the next release out tomorrow (most of the bugs are squashed), so I should be able to throw something very basic together, basically it'll just be "is the planet scanned". I'll probably need to do one for the biome unlock thing too, not sure if I'll try to combine them into one parameter or have separate ones. And a couple expression functions for checking the same things. And requirements. Still, they're really simple checks, so it shouldn't take long. :)

EDIT: Oh, and no other way without someone coding something up, no.

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...