From 307e597079c59b34272b78d58caf61438ec4ae82 Mon Sep 17 00:00:00 2001 From: Ballatik <67292986+Ballatik@users.noreply.github.com> Date: Sat, 14 Oct 2023 10:11:42 -0400 Subject: [PATCH 01/27] Update Geo Program first pass Update program definition and description. Add optional Geosync contract Update FirstGEOSat orbit parameter and requirements Add required FirstTargetedGeo Update GeoComSatNetwork to require spacing Update GEORepeatComSats to require target --- .../Earth Satellites/FirstGEOSat.cfg | 61 ++--- .../Earth Satellites/FirstGeosync.cfg | 101 ++++++++ .../Earth Satellites/FirstTargetedGeo.cfg | 144 +++++++++++ .../Earth Satellites/GEORepeatComSats.cfg | 47 +++- .../Earth Satellites/GeoComSatNetwork.cfg | 231 ++++++++++++------ GameData/RP-1/Programs/Programs.cfg | 207 ++++++++-------- 6 files changed, 568 insertions(+), 223 deletions(-) create mode 100644 GameData/RP-1/Contracts/Earth Satellites/FirstGeosync.cfg create mode 100644 GameData/RP-1/Contracts/Earth Satellites/FirstTargetedGeo.cfg diff --git a/GameData/RP-1/Contracts/Earth Satellites/FirstGEOSat.cfg b/GameData/RP-1/Contracts/Earth Satellites/FirstGEOSat.cfg index fcfa92e894e..0b87ad48586 100644 --- a/GameData/RP-1/Contracts/Earth Satellites/FirstGEOSat.cfg +++ b/GameData/RP-1/Contracts/Earth Satellites/FirstGEOSat.cfg @@ -2,16 +2,13 @@ CONTRACT_TYPE { name = FirstGEOSat title = First Geostationary Satellite - group = TargetedSats + group = GEOCommNetwork agent = Federation Aeronautique Internationale - - tag = exclude_EarlySatellite - - description = Program: Targeted Satellites
Type: Required


A geostationary orbit is a circular orbit 35,786 km above the Earth's equator and following the direction of the Earth's rotation. An object in such an orbit has an orbital period equal to the Earth's rotational period (23 hours, 56 minutes, and 4.1 seconds) and thus will appear motionless at a fixed position in the sky to ground observers. &br;&br;Launch a satellite into a Geostationary Orbit. + description = Program: Geostationary Communication Network
Type: Required


Having a communication satellite that remains stationary relative to a ground station means that the antenna wouldn't need to track movements to stay connected. This would greatly simplify communication relay and mass transmission systems.
Historical example: Syncom 3 (39 kg, Thor-Delta) launched in August of 1964.

synopsis = Launch a satellite into a Geostationary Orbit - completedMessage = Success! The Geostationary orbit is the most commonly used orbit for communications satellites and other observation satellites. + completedMessage = Congratulations! The satellite is in orbit over a constant area. sortKey = 503 @@ -33,33 +30,32 @@ CONTRACT_TYPE rewardScience = 0 rewardFunds = 0 failureFunds = 0 - rewardReputation = 80 + rewardReputation = 40 failureReputation = 0 // was @rewardReputation - - // ************ REQUIREMENTS ************ REQUIREMENT { name = ProgramActive type = ProgramActive - program = TargetedSats + program = GEOCommNetwork } - - DATA + REQUIREMENT { - type = float - payload = 25 + name = AcceptContract + type = AcceptContract + contractType = FirstGeosync + invertRequirement = true } - + PARAMETER { name = GeostationarySat type = VesselParameterGroup title = Geostationary satellite define = Geostationary - + PARAMETER { name = NewVessel @@ -67,7 +63,7 @@ CONTRACT_TYPE title = Launch a new vessel hideChildren = true } - PARAMETER + PARAMETER { name = Crewmembers type = HasCrew @@ -81,19 +77,21 @@ CONTRACT_TYPE name = HasComSatPayload type = HasResource resource = ComSatPayload - minQuantity = @/payload-0.1 - title = Have a ComSatPayload of at least @/payload units on the craft + minQuantity = 49.9 + title = Have a ComSatPayload of at least 50 units on the craft hideChildren = true } PARAMETER { - name = ReachSpecificOrbit - type = ReachSpecificOrbit - displayNotes = true - index = 0 - title = Achieve geostationary orbit - deviationWindow = 5.0 - + name = Reach Specifit Orbit + type = Orbit + maxInclination = 2 + maxEccentricity = 0.01 + minPeriod = 23h 54m + maxPeriod = 23h 58m + disableOnStateChange = false + title = Achieve a Geostationary orbit within the stated parameters + PARAMETER { name = Duration @@ -107,15 +105,4 @@ CONTRACT_TYPE } } } - - - BEHAVIOUR - { - name = GeostationaryOrbit - type = OrbitGenerator - RANDOM_ORBIT - { - type = STATIONARY - } - } } diff --git a/GameData/RP-1/Contracts/Earth Satellites/FirstGeosync.cfg b/GameData/RP-1/Contracts/Earth Satellites/FirstGeosync.cfg new file mode 100644 index 00000000000..eb4777be149 --- /dev/null +++ b/GameData/RP-1/Contracts/Earth Satellites/FirstGeosync.cfg @@ -0,0 +1,101 @@ +CONTRACT_TYPE +{ + name = FirstGeosync + title = First Geosynchronous + group = GEOCommNetwork + agent = Federation Aeronautique Internationale + + description = Program: Geostationary Communications Network
Type: Optional


With an orbital period of an earth day, a satellite will remain above a constant longitude, appearing to drift north and south through the day. This will allow for constant connection to a ground station.
Historical example: Syncom 2 (39kg, Thor-Delta) launched in July of 1963.

+ + synopsis = Launch a geosynchronous satellite + + completedMessage = Congratulations! The satellite is in orbit and connected to the groundstation. + + sortKey = 409 + + cancellable = true + declinable = false + autoAccept = false + minExpiry = 0 + maxExpiry = 0 + maxCompletions = 1 + maxSimultaneous = 1 + deadline = 0 + + targetBody = HomeWorld() + + + // ************ REWARDS ************ + prestige = Trivial // 1.0x + advanceFunds = 0 + rewardScience = 0 + rewardFunds = 0 + failureFunds = 0 + rewardReputation = 40 + failureReputation = 0 // was @rewardReputation + + // ************ REQUIREMENTS ************ + + REQUIREMENT + { + name = ProgramActive + type = ProgramActive + program = GEOCommNetwork + } + + PARAMETER + { + name = FirstGeosync + type = VesselParameterGroup + title = Targeted Geostationary + define = FirstGeosync + + PARAMETER + { + name = NewVessel + type = NewVessel + title = Launch a new vessel + hideChildren = true + } + PARAMETER + { + name = Crewmembers + type = HasCrew + minCrew = 0 + maxCrew = 0 + title = Uncrewed + hideChildren = true + } + PARAMETER + { + name = HasComSatPayload + type = HasResource + resource = ComSatPayload + minQuantity = 49.9 + title = Have a ComSatPayload of at least 50 units on the craft + hideChildren = true + } + PARAMETER + { + name = Orbit + type = Orbit + maxEccentricity = 0.05 // fixme + minPeriod = 23h 54m + maxPeriod = 23h 58m + disableOnStateChange = false + title = Achieve a Geosynchronous orbit with low eccentricity + + PARAMETER + { + name = Duration + type = Duration + + duration = 2m + + preWaitText = Check for stable orbit + waitingText = Checking for stable orbit + completionText = Stable orbit: Confirmed + } + } + } +} diff --git a/GameData/RP-1/Contracts/Earth Satellites/FirstTargetedGeo.cfg b/GameData/RP-1/Contracts/Earth Satellites/FirstTargetedGeo.cfg new file mode 100644 index 00000000000..83b9a0244b4 --- /dev/null +++ b/GameData/RP-1/Contracts/Earth Satellites/FirstTargetedGeo.cfg @@ -0,0 +1,144 @@ +CONTRACT_TYPE +{ + name = FirstTargetedGeo + title = First Targeted Geostationary + group = GEOCommNetwork + agent = Federation Aeronautique Internationale + + description = Program: Geostationary Communications Network
Type: Required


Now that we have shown the benefits of Geostationary orbits, launch a satellite to cover a specific ground area.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.

+ + synopsis = Launch a geostationary satellite over the targeted point + + completedMessage = Congratulations! The satellite is in orbit and connected to the groundstation. + + sortKey = 410 + + cancellable = true + declinable = false + autoAccept = false + minExpiry = 0 + maxExpiry = 0 + maxCompletions = 1 + maxSimultaneous = 1 + deadline = 0 + + targetBody = HomeWorld() + + + // ************ REWARDS ************ + prestige = Trivial // 1.0x + advanceFunds = 0 + rewardScience = 0 + rewardFunds = 0 + failureFunds = 0 + rewardReputation = 40 + failureReputation = 0 // was @rewardReputation + + // ************ REQUIREMENTS ************ + + REQUIREMENT + { + name = ProgramActive + type = ProgramActive + program = GEOCommNetwork + } + REQUIREMENT + { + name = CompleteContract + type = CompleteContract + contractType = FirstGEOSat + } + + PARAMETER + { + name = TargetedGeo + type = VesselParameterGroup + title = Targeted Geostationary + define = TargetedGeo + + PARAMETER + { + name = NewVessel + type = NewVessel + title = Launch a new vessel + hideChildren = true + } + PARAMETER + { + name = Crewmembers + type = HasCrew + minCrew = 0 + maxCrew = 0 + title = Uncrewed + hideChildren = true + } + PARAMETER + { + name = HasComSatPayload + type = HasResource + resource = ComSatPayload + minQuantity = 49.9 + title = Have a ComSatPayload of at least 50 units on the craft + hideChildren = true + } + PARAMETER + { + name = Orbit + type = Orbit + maxInclination = 2 + maxEccentricity = 0.01 + minPeriod = 23h 54m + maxPeriod = 23h 58m + disableOnStateChange = false + title = Achieve a Geostationary orbit within the stated parameters near the waypoint + } + PARAMETER + { + name = VisitWaypoint + type = VisitWaypoint + index = 0 + //distance = 42736000 + horizontalDistance = 2000.0 + showMessages = true + disableOnStateChange = false + } + + } + BEHAVIOUR + { + name = WaypointGenerator + type = WaypointGenerator + + RANDOM_WAYPOINT + { + name = Geostationary Comm Satellite + icon = thermometer + altitude = 0 + forceEquatorial = true + } + } + BEHAVIOUR + { + name = TransferVessel + type = DestroyVessel + onState = CONTRACT_SUCCESS + vessel = FirstNavSat + } + + BEHAVIOUR + { + name = VesselDestroyed + type = DialogBox + DIALOG_BOX + { + title = Vessel Ownership Transferred + condition = CONTRACT_SUCCESS + position = CENTER + width = 0.5 + TEXT + { + text = The contract has been completed successfully and the satellite has been transferred to the customer. + } + } + } +} diff --git a/GameData/RP-1/Contracts/Earth Satellites/GEORepeatComSats.cfg b/GameData/RP-1/Contracts/Earth Satellites/GEORepeatComSats.cfg index d071836a9e9..821b10a8b25 100644 --- a/GameData/RP-1/Contracts/Earth Satellites/GEORepeatComSats.cfg +++ b/GameData/RP-1/Contracts/Earth Satellites/GEORepeatComSats.cfg @@ -3,11 +3,11 @@ CONTRACT_TYPE name = GEORepeatComSats title = Geostationary Commercial Communications Satellite group = GEOCommNetwork - agent = Satellites + agent = Federation Aeronautique Internationale tag = exclude_RepeatableComSat - - description = Program: Geostationary Communications Network
Type: Optional


We have a customer requesting a new Communications Satellite. Design a satellite within their specs and launch into an orbit with the proper orbital parameters as outlined in the contract.&br;&br;This contract can be completed as many times as you would like.&br;&br;NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.&br;&br;The reward of this contract will slowly increase over time but will be reset to 0 after each completion.&br;Current reward is at @rewardFactorPercent % of its nominal value. Elapsed/Expected Days: @elapsedDays / @RP0:expectedDays_GEORepeatComSats
Number of Contracts Completed: @index / unlimited
+ + description = Program: Geostationary Communications Network
Type: Optional


We have a customer requesting a new Communications Satellite over a specified area. Design a satellite within their specs and launch into an orbit with the proper orbital parameters as outlined in the contract.&br;&br;This contract can be completed as many times as you would like.&br;&br;NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.&br;&br;The reward of this contract will slowly increase over time but will be reset to 0 after each completion.&br;Current reward is at @rewardFactorPercent % of its nominal value. Elapsed/Expected Days: @elapsedDays / @RP0:expectedDays_GEORepeatComSats
Number of Contracts Completed: @index / unlimited
genericDescription = Put a satellite with the appropriate amount of communications satellite payload into geostationary orbit. synopsis = Launch a new Commercial Communications Satellite @@ -43,7 +43,14 @@ CONTRACT_TYPE type = ProgramActive program = GEOCommNetwork } - + + REQUIREMENT + { + name = CompleteContract + type = CompleteContract + contractType = FirstTargetedGeo + } + REQUIREMENT { name = AcceptContract @@ -51,7 +58,7 @@ CONTRACT_TYPE tag = exclude_SoundingRocket invertRequirement = true } - + REQUIREMENT { name = AcceptContract @@ -59,7 +66,7 @@ CONTRACT_TYPE tag = exclude_SoundingDownrange invertRequirement = true } - + REQUIREMENT { name = AcceptContract @@ -78,6 +85,20 @@ CONTRACT_TYPE type = STATIONARY } } + + BEHAVIOUR + { + name = WaypointGenerator + type = WaypointGenerator + + RANDOM_WAYPOINT + { + name = Geostationary Weather Satellite + icon = thermometer + altitude = 0 + forceEquatorial = true + } + } DATA { @@ -100,7 +121,7 @@ CONTRACT_TYPE RepeatSat_Completion = UniversalTime() } } - + DATA { type = int @@ -164,6 +185,18 @@ CONTRACT_TYPE index = 0 deviationWindow = 4 + PARAMETER + { + name = VisitWaypoint + type = VisitWaypoint + index = 0 + //distance = 42736000 + horizontalDistance = 2000.0 + showMessages = true + completeInSequence = true + disableOnStateChange = false + } + PARAMETER { name = Duration diff --git a/GameData/RP-1/Contracts/Earth Satellites/GeoComSatNetwork.cfg b/GameData/RP-1/Contracts/Earth Satellites/GeoComSatNetwork.cfg index f9e5fae7096..5f78ad93af0 100644 --- a/GameData/RP-1/Contracts/Earth Satellites/GeoComSatNetwork.cfg +++ b/GameData/RP-1/Contracts/Earth Satellites/GeoComSatNetwork.cfg @@ -3,18 +3,18 @@ CONTRACT_TYPE name = GeoComSatNetwork title = Geostationary Communications Network group = GEOCommNetwork - agent = Satellites + agent = Federation Aeronautique Internationale - description = Program: Geostationary Communications Network
Type: Required


Our previous Communications Network is showing its age. We want you to launch a Geostationary Communications Network to make sure that we have consistent coverage across the globe. + description = Program: Geostationary Communications Network
Type: Required


Through measuring the Doppler shift of radio signals transmitted from a satellite in a known orbit, it is possible for a receiver on the ground to establish their location, which would have many applications both civilian and military. To test the principle and develop receiver equipment, it is necessary to have a test navigational satellite in orbit.
Historical example: Transit 1B (119 kg, Thor-Ablestar).

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer. - synopsis = Launch a 4 Satellite Geostationary Communications Network + synopsis = Launch a 3 Satellite Geostationary Communications Network - completedMessage = Congratulations! This new high-tech network is working great! + completedMessage = Congratulations! The satellites are in orbit and spaced to provide complete coverage. sortKey = 903 cancellable = true - declinable = true + declinable = false autoAccept = false minExpiry = 0 maxExpiry = 0 @@ -29,7 +29,7 @@ CONTRACT_TYPE rewardScience = 0 rewardFunds = 0 failureFunds = 0 - rewardReputation = 400 + rewardReputation = 40 failureReputation = 0 // was @rewardReputation // ************ REQUIREMENTS ************ @@ -40,7 +40,19 @@ CONTRACT_TYPE type = ProgramActive program = GEOCommNetwork } - + REQUIREMENT + { + name = CompleteContract + type = CompleteContract + contractType = FirstTargetedGeo + } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = GEORepeatComSats + invertRequirement = true + } PARAMETER { @@ -66,36 +78,51 @@ CONTRACT_TYPE vessel = GEO CommSat III } - PARAMETER - { - name = IsNotVessel - type = IsNotVessel - - vessel = GEO CommSat IV - } - PARAMETER { name = HasComSatPayload type = HasResource resource = ComSatPayload - minQuantity = 314.9 - title = Have a ComSatPayload of at least 315 units on the craft - hideChildren = true + minQuantity = 124.9 + title = Have a ComSatPayload of at least 125 units on the craft + disableOnStateChange = false } PARAMETER { name = Orbit type = Orbit - maxEccentricity = 0.1 + maxInclination = 2 + maxEccentricity = 0.01 minPeriod = 23h 54m maxPeriod = 23h 58m - maxInclination = 1.0 - title = Reach an orbit with the specified parameters + disableOnStateChange = false + title = Achieve a Geostationary orbit within the stated parameters near the waypoint + PARAMETER + { + name = VisitWaypoint + type = VisitWaypoint + index = 0 + //distance = 42736000 + horizontalDistance = 1000000.0 // standard 1000km parking spot + showMessages = true + completeInSequence = true + disableOnStateChange = false + } + + PARAMETER + { + name = Duration + type = Duration + + duration = 2m + + preWaitText = Check for stable orbit + waitingText = Checking for stable orbit + completionText = Stable orbit: Confirmed + } } } - PARAMETER { name = GEOCommSat2 @@ -109,7 +136,7 @@ CONTRACT_TYPE name = IsNotVessel type = IsNotVessel - vessel = GEO CommSat III + vessel = GEO CommSat I } PARAMETER @@ -117,7 +144,7 @@ CONTRACT_TYPE name = IsNotVessel type = IsNotVessel - vessel = GEO CommSat IV + vessel = GEO CommSat III } PARAMETER @@ -125,23 +152,46 @@ CONTRACT_TYPE name = HasComSatPayload type = HasResource resource = ComSatPayload - minQuantity = 314.9 - title = Have a ComSatPayload of at least 315 units on the craft - hideChildren = true + minQuantity = 124.9 + title = Have a ComSatPayload of at least 125 units on the craft + disableOnStateChange = false } PARAMETER { name = Orbit type = Orbit - maxEccentricity = 0.1 + maxInclination = 2 + maxEccentricity = 0.01 minPeriod = 23h 54m maxPeriod = 23h 58m - maxInclination = 1.0 - title = Reach an orbit with the specified parameters + disableOnStateChange = false + title = Achieve a Geostationary orbit within the stated parameters near the waypoint + PARAMETER + { + name = VisitWaypoint + type = VisitWaypoint + index = 1 + //distance = 42736000 + horizontalDistance = 2000.0 + showMessages = true + completeInSequence = true + disableOnStateChange = false + } + + PARAMETER + { + name = Duration + type = Duration + + duration = 2m + + preWaitText = Check for stable orbit + waitingText = Checking for stable orbit + completionText = Stable orbit: Confirmed + } } } - PARAMETER { name = GEOCommSat3 @@ -163,7 +213,7 @@ CONTRACT_TYPE name = IsNotVessel type = IsNotVessel - vessel = GEO CommSat IV + vessel = GEO CommSat II } PARAMETER @@ -171,70 +221,101 @@ CONTRACT_TYPE name = HasComSatPayload type = HasResource resource = ComSatPayload - minQuantity = 314.9 - title = Have a ComSatPayload of at least 315 units on the craft - hideChildren = true + minQuantity = 124.9 + title = Have a ComSatPayload of at least 125 units on the craft + disableOnStateChange = false } PARAMETER { name = Orbit type = Orbit - maxEccentricity = 0.1 + maxInclination = 2 + maxEccentricity = 0.01 minPeriod = 23h 54m maxPeriod = 23h 58m - maxInclination = 1.0 - title = Reach an orbit with the specified parameters + disableOnStateChange = false + title = Achieve a Geostationary orbit within the stated parameters near the waypoint + PARAMETER + { + name = VisitWaypoint + type = VisitWaypoint + index = 2 + //distance = 42736000 + horizontalDistance = 2000.0 + showMessages = true + completeInSequence = true + disableOnStateChange = false + } + + PARAMETER + { + name = Duration + type = Duration + + duration = 2m + + preWaitText = Check for stable orbit + waitingText = Checking for stable orbit + completionText = Stable orbit: Confirmed + } } } - - PARAMETER + BEHAVIOUR { - name = GEOCommSat4 - type = VesselParameterGroup + name = WaypointGenerator + type = WaypointGenerator - define = GEO CommSat IV - disableOnStateChange = false - - PARAMETER + WAYPOINT { - name = IsNotVessel - type = IsNotVessel - - vessel = GEO CommSat II + name = Geostationary Ground Target I + icon = thermometer + altitude = 0 + latitude = 0 + longitude = 0 } - - PARAMETER + WAYPOINT { - name = HasComSatPayload - type = HasResource - resource = ComSatPayload - minQuantity = 314.9 - title = Have a ComSatPayload of at least 315 units on the craft - hideChildren = true + name = Geostationary Ground Target II + icon = thermometer + altitude = 0 + latitude = 0 + longitude = 120 } - - PARAMETER + WAYPOINT { - name = Orbit - type = Orbit - maxEccentricity = 0.1 - minPeriod = 23h 54m - maxPeriod = 23h 58m - maxInclination = 1.0 - title = Reach an orbit with the specified parameters + name = Geostationary Ground Target III + icon = thermometer + altitude = 0 + latitude = 0 + longitude = 240 } } - PARAMETER + BEHAVIOUR { - name = Duration - type = Duration - - duration = 2d + name = TransferVessel + type = DestroyVessel + onState = CONTRACT_SUCCESS + vessel = GEO CommSat I + vessel = GEO CommSat II + vessel = GEO CommSat III + } - preWaitText = Testing time after network up - waitingText = Performing shake-out testing - completionText = Shake-out testing completed + BEHAVIOUR + { + name = VesselDestroyed + type = DialogBox + DIALOG_BOX + { + title = Vessel Ownership Transferred + condition = CONTRACT_SUCCESS + position = CENTER + width = 0.5 + TEXT + { + text = The contract has been completed successfully and the satellites have been transferred to the customer. + } + } } } diff --git a/GameData/RP-1/Programs/Programs.cfg b/GameData/RP-1/Programs/Programs.cfg index a7a40cea4de..13e5bea18b8 100644 --- a/GameData/RP-1/Programs/Programs.cfg +++ b/GameData/RP-1/Programs/Programs.cfg @@ -39,7 +39,6 @@ RP0_PROGRAM name = XPlanesKarman } } - OPTIONALS { XPlanesSupersonicOptionalLow = true @@ -50,7 +49,6 @@ RP0_PROGRAM XPlanesSuborbital = true XPlanesHypersonicOptional = true } - CONFIDENCECOSTS { Normal = 350 @@ -78,13 +76,11 @@ RP0_PROGRAM complete_contract = DownrangeEarly complete_contract = Downrange } - OPTIONALS { DownrangeSoundingIntermediate = true DistanceSoundingDifficult = true } - CONFIDENCECOSTS { Normal = 150 @@ -111,23 +107,20 @@ RP0_PROGRAM { name = KarmanLine } - COMPLETE_CONTRACT { name = SoundingRocketFilm } - + COMPLETE_CONTRACT { name = SoundingRocketBio } - COMPLETE_CONTRACT { name = SoundingRocketAdvancedBio } } - OPTIONALS { SoundingDifficult = true @@ -136,7 +129,6 @@ RP0_PROGRAM SoundingRocketBioOptional = true SoundingRocketAdvancedBioOptional = true } - CONFIDENCECOSTS { Normal = 150 @@ -232,13 +224,12 @@ RP0_PROGRAM { EarlySatellites = true } - OPTIONALS { Downrange6000-Heavy = true Downrange7500-Heavy = true } - + CONFIDENCECOSTS { Normal = 600 @@ -278,7 +269,6 @@ RP0_PROGRAM complete_contract = FirstMolniyaSat complete_contract = FirstTundraSat } - OPTIONALS { ComTestSat = true @@ -295,7 +285,7 @@ RP0_PROGRAM { name = EarthObservationScience1 title = Early Earth Observation Satellites - description = Now that you have proven the ability to send satellites into orbit, the next step is to send them into more useful orbits with more beneficial payloads. This program will focus on satellites for observing the Earth and the space environment around it. This will advance scientific knowledge of not just physical processes within our atmosphere, but also those in space, all of which influence our lives here on Earth. + description = Now that you have proven the ability to send satellites into orbit, the next step is to send them into more useful orbits with more beneficial payloads. This program will focus on satellites for observing the Earth and the space environment around it. This will advance scientific knowledge of not just physical processes within our atmosphere, but also those in space, all of which influence our lives here on Earth. requirementsPrettyText = Complete Early Satellites program objectivesPrettyText = Launch satellites to photograph the Earth, analyze weather, measure solar wind and cosmic rays, and determine the extent of the Magnetosphere. nominalDurationYears = 4 @@ -323,7 +313,7 @@ RP0_PROGRAM complete_contract = first_OrbitRecover complete_contract = EOSCorona } - + OPTIONALS { EOSGrav1 = true @@ -343,9 +333,9 @@ RP0_PROGRAM { name = CommercialApplications1 title = Early Commercial Applications - description = Although the earliest satellites were launched through government programs, commercial uses had been envisioned for a long time. Through this program, you will launch the earliest iterations of commercial-use satellites. With wildly varying needs, each satellite is dedicated to a specific requirement, typically with far more focused requirements than the earlier, broader scientific satellites. + description = Although the earliest satellites were launched through government programs, commercial uses had been envisioned for a long time. Through this program, you will launch the earliest iterations of commercial-use satellites. With wildly varying needs, each satellite is dedicated to a specific requirement, typically with far more focused requirements than the earlier, broader scientific satellites. requirementsPrettyText = Complete Early Satellites program - objectivesPrettyText = Launch the first commercial-use satellites and build a satellite communication network. + objectivesPrettyText = Launch the first commercial-use satellites and build a satellite communication network. nominalDurationYears = 4 baseFunding = 560000 fundingCurve = MildRampupCurve @@ -377,7 +367,7 @@ RP0_PROGRAM complete_contract = EarlyComNetwork4-CA } } - + OPTIONALS { EarlyComSat-CA = true @@ -424,7 +414,7 @@ RP0_PROGRAM complete_contract = EarlyComNetwork4 } } - + OPTIONALS { ComTestSat = true @@ -441,8 +431,8 @@ RP0_PROGRAM RP0_PROGRAM { name = GEOCommNetwork - title = Geostationary Communication Network - description = With geostationary orbits, satellites can be placed at specific spots over the equator where they will stay. This allows communications satellites to be put exactly where they will have the greatest benefit. This program tasks you with creating a 4-satellite Geostationary Network for communication. Each satellite will require 315 units of ComSatPayload. + title = Geostationary Communication Network + description = Geosynchronous, Geostationary, and Molniya orbits have the potential to improve satellite coverage and simplify ground antenna tracking. This program tasks you with creating a 3-satellite Geostationary or Molniya Network for communication. requirementsPrettyText = Complete the Targeted Satellites Program objectivesPrettyText = Complete the Geostationary Communications Network. nominalDurationYears = 2 @@ -452,31 +442,40 @@ RP0_PROGRAM repPenaltyPerYearLate = 420 slots = 2 - REQUIREMENTS - { - ANY + // REQUIREMENTS + // { + // ANY + // { + // complete_program = TargetedSats + // complete_program = CommercialApplications1 + // } + // } + + OBJECTIVES { - complete_program = TargetedSats - complete_program = CommercialApplications1 + complete_contract = FirstGEOSat + complete_contract = FirstTargetedGeo + ANY + { + complete_contract = GeoComSatNetwork + // complete_contract = MolniyaArray + + } } - } - OBJECTIVES - { - complete_contract = GeoComSatNetwork - } - - OPTIONALS - { - GEORepeatComSats = true - } - - CONFIDENCECOSTS - { - Normal = 450 - Fast = 900 + OPTIONALS + { + FirstGeosync = true + GEORepeatComSats = true + // MolniyaRep = true + } + + CONFIDENCECOSTS + { + Normal = 450 + Fast = 900 + } } -} RP0_PROGRAM { name = EarlyLunarProbes @@ -491,7 +490,7 @@ RP0_PROGRAM slots = 2 REQUIREMENTS - { + { ANY { complete_contract = FirstScienceSat @@ -515,13 +514,13 @@ RP0_PROGRAM complete_contract = LunarImpactor complete_contract = LunarOrbiter } - + OPTIONALS { LunarImpactorOptional = true LunarOrbiterOptional = true } - + CONFIDENCECOSTS { Normal = 550 @@ -533,7 +532,7 @@ RP0_PROGRAM { name = UncrewedLunarSurface title = Uncrewed Lunar Surface Exploration - description = Landing uncrewed probes on the Moon is the next step in exploring the Solar System. Successfully landing on the Moon is a difficult problem to solve. You will need to develop even more capable launch vehicles to be able to launch a large enough payload. These uncrewed landings will give you the data you need to plan for your crewed landings to follow. You will need to research deeply-throttleable engines from the Early Landing node (recommended) or figure out how to perform a landing with RCS. + description = Landing uncrewed probes on the Moon is the next step in exploring the Solar System. Successfully landing on the Moon is a difficult problem to solve. You will need to develop even more capable launch vehicles to be able to launch a large enough payload. These uncrewed landings will give you the data you need to plan for your crewed landings to follow. You will need to research deeply-throttleable engines from the Early Landing node (recommended) or figure out how to perform a landing with RCS. requirementsPrettyText = Complete the Early Lunar Probes program objectivesPrettyText = Land probes on the Moon. nominalDurationYears = 5 @@ -555,7 +554,7 @@ RP0_PROGRAM complete_contract = MoonOrbiter complete_contract = MoonLandingFarSide } - + OPTIONALS { MoonLandingOptional = true @@ -564,7 +563,7 @@ RP0_PROGRAM MoonRover = true MoonLandingReturn = true } - + CONFIDENCECOSTS { Normal = 900 @@ -588,7 +587,7 @@ RP0_PROGRAM repPenaltyPerYearLate = 895 repToConfidence = 3 slots = 3 - + REQUIREMENTS { ANY @@ -612,7 +611,7 @@ RP0_PROGRAM complete_contract = Rendezvous complete_contract = first_Docking } - + CONFIDENCECOSTS { Normal = 2400 @@ -646,7 +645,7 @@ RP0_PROGRAM repPenaltyPerYearLate = 315 repToConfidence = 3 slots = 3 - + REQUIREMENTS { ANY @@ -663,7 +662,7 @@ RP0_PROGRAM complete_contract = first_OrbitCrewed complete_contract = CollectCrewedScienceBasic } - + CONFIDENCECOSTS { Normal = 800 @@ -697,7 +696,7 @@ RP0_PROGRAM repPenaltyPerYearLate = 575 repToConfidence = 3 slots = 3 - + REQUIREMENTS { complete_program = CrewedOrbitEarly @@ -714,7 +713,7 @@ RP0_PROGRAM complete_contract = Rendezvous complete_contract = first_Docking } - + CONFIDENCECOSTS { Normal = 1450 @@ -767,7 +766,7 @@ RP0_PROGRAM OrbitalPlane3 = true CrewedSpaceplaneSuborbital = true } - + CONFIDENCECOSTS { Normal = 2500 @@ -778,7 +777,7 @@ RP0_PROGRAM RP0_PROGRAM { name = EarlyInnerPlanetProbes - title = Early Inner Planet Probes + title = Early Inner Planet Probes description = This program tasks you with exploring Venus and Mars. Though these may be Earth's closest neighbors, the distance between us and them still averages in the hundreds of millions of kilometers. Staying in contact with these probes will require advances in communication technology. Maintaining functionality and power over such great distances and long times will present new challenges in spacecraft design. requirementsPrettyText = Complete contracts X and Y objectivesPrettyText = Orbit Venus and Mars. @@ -806,13 +805,13 @@ RP0_PROGRAM complete_contract = orbitMars complete_contract = orbitVenus } - + CONFIDENCECOSTS { Normal = 1300 Fast = 2600 } - + OPTIONALS { MarsOrbitRepeatable = true @@ -827,7 +826,7 @@ RP0_PROGRAM title = Crewed Lunar Exploration description = You are tasked with sending to the Moon, 240,000 miles away from the control station in Houston, a giant rocket more than 300 feet tall, made of new metal alloys, some of which have not yet been invented, capable of standing heat and stresses several times more than have ever been experienced, fitted together with a precision better than the finest watch, carrying all the equipment needed for propulsion, guidance, control, communications, food, and survival, on an untried mission, to an unknown celestial body, and then return it safely to earth, reentering the atmosphere at speeds of over 25,000 miles per hour, causing heat about half that of the temperature of the sun. Alternatively, this could be an opportunity for some command chair antics. But a proper rocket is probably your best bet. You will need to upgrade your astronaut complex to level three to plant a flag on the Moon and complete the first crewed landing contract. requirementsPrettyText = Complete contracts X and Y - objectivesPrettyText = Send crew to flyby, orbit, and land on the Moon. + objectivesPrettyText = Send crew to flyby, orbit, and land on the Moon. nominalDurationYears = 12 baseFunding = 15720000 fundingCurve = MildMidFundingCurve @@ -861,12 +860,12 @@ RP0_PROGRAM { name = first_MoonFlybyCrewed } - + COMPLETE_CONTRACT { name = FirstCrewedLunarOrbit } - + ANY { complete_contract = first_MoonLandingCrewed @@ -879,13 +878,13 @@ RP0_PROGRAM minCount = 2 } } - + CONFIDENCECOSTS { Normal = 5250 Fast = 10500 } - + OPTIONALS { MoonExtendedStayCrew = true @@ -919,7 +918,7 @@ disabled_RP0_PROGRAM complete_contract = first_ISScrew complete_contract = second_ISScrew } - + CONFIDENCECOSTS { Normal = 5000 @@ -930,10 +929,10 @@ disabled_RP0_PROGRAM RP0_PROGRAM { name = MarsSurfaceExp - title = Mars Surface Exploration - description = Send probes to Mars to survey its atmosphere, land on the surface, and even drive around with a rover. The thin atmosphere of Mars is enough to produce quite a bit of reentry heating, but it's not thick enough to safely land with only parachutes. + title = Mars Surface Exploration + description = Send probes to Mars to survey its atmosphere, land on the surface, and even drive around with a rover. The thin atmosphere of Mars is enough to produce quite a bit of reentry heating, but it's not thick enough to safely land with only parachutes. requirementsPrettyText = Complete contracts X and Y - objectivesPrettyText = Complete the program by sending a rover to Mars. + objectivesPrettyText = Complete the program by sending a rover to Mars. nominalDurationYears = 8 baseFunding = 4800000 repDeltaOnCompletePerYearEarly = 620 @@ -951,13 +950,13 @@ RP0_PROGRAM complete_contract = landingMars complete_contract = roverMars } - + CONFIDENCECOSTS { Normal = 2500 Fast = 5000 } - + OPTIONALS { flybyDeimos = true @@ -968,13 +967,13 @@ RP0_PROGRAM samplesPhobos = true MarsOrbitRepeatable = true } - + } RP0_PROGRAM { name = VenusSurfaceExp - title = Venus Surface Exploration + title = Venus Surface Exploration description = Send probes to Venus to see what the surface and atmosphere are really like. The dense clouds hide the surface from view, while the corrosive atmosphere and high heat present challenges for anything trying to descend to the surface. Keeping a probe operational for any length of time presents significant challenges. Even with heat-resistant materials, nothing seems able to survive for more than a few hours. requirementsPrettyText = Complete contracts X and Y objectivesPrettyText = Land a probe on Venus. @@ -995,13 +994,13 @@ RP0_PROGRAM complete_contract = landingVenus minCount = 3 } - + CONFIDENCECOSTS { Normal = 1800 Fast = 3600 } - + OPTIONALS { probeVenus = true @@ -1037,7 +1036,7 @@ RP0_PROGRAM complete_contract = flybyVesta } } - + CONFIDENCECOSTS { Normal = 2650 @@ -1051,7 +1050,7 @@ RP0_PROGRAM title = Mercury Exploration description = Mercury is the least explored of the inner planets, due to the difficulty of orbiting it. Send some probes there to find out more about it. Current data suggests that Mercury is tidally locked with the Sun. How will this affect its surface? Or did we just flyby it at remarkably synchronized times? Either way, sending probes to orbit and land on Mercury will provide fascinating data on the closest planet to the Sun. requirementsPrettyText = Do this and that - objectivesPrettyText = Orbit and land on Mercury. + objectivesPrettyText = Orbit and land on Mercury. nominalDurationYears = 8 baseFunding = 4800000 repDeltaOnCompletePerYearEarly = 415 @@ -1069,13 +1068,13 @@ RP0_PROGRAM complete_contract = orbitMercury complete_contract = landingMercury } - + CONFIDENCECOSTS { Normal = 3200 Fast = 6400 } - + OPTIONALS { orbitMercury_Rep = true @@ -1107,13 +1106,13 @@ RP0_PROGRAM complete_contract = orbitCeres complete_contract = orbitVesta } - + CONFIDENCECOSTS { Normal = 5600 Fast = 11200 } - + OPTIONALS { orbitCeres_Rep = true @@ -1127,7 +1126,7 @@ RP0_PROGRAM { name = JupiterObservation title = Jupiter Observation - description = Jupiter presents many opportunities for exploration, but also many challenges: it requires almost the same amount of energy for a spacecraft to reach Jupiter from Earth's orbit as it does to lift it into orbit in the first place. Gravity assists can be used to save delta-v at the cost of flight duration. Once there, a rich and diverse system awaits any explorer. Along with the largest planet in the Solar System, the Jovian system is also home to the largest moon, Ganymede, a planetary-mass moon. This program will send uncrewed scientific probes to Jupiter and its moons.

Historically, Jupiter is the most-visited outer planet, with 9 missions having completed flybys or entered orbits, most notably by the Voyager missions in 1979 on their flybys towards the outer Solar System, and by the Juno orbiter whose mission continues today. Most recently, ESA's JUICE mission departed in 2023 enroute to the Galilean moons. + description = Jupiter presents many opportunities for exploration, but also many challenges: it requires almost the same amount of energy for a spacecraft to reach Jupiter from Earth's orbit as it does to lift it into orbit in the first place. Gravity assists can be used to save delta-v at the cost of flight duration. Once there, a rich and diverse system awaits any explorer. Along with the largest planet in the Solar System, the Jovian system is also home to the largest moon, Ganymede, a planetary-mass moon. This program will send uncrewed scientific probes to Jupiter and its moons.

Historically, Jupiter is the most-visited outer planet, with 9 missions having completed flybys or entered orbits, most notably by the Voyager missions in 1979 on their flybys towards the outer Solar System, and by the Juno orbiter whose mission continues today. Most recently, ESA's JUICE mission departed in 2023 enroute to the Galilean moons. requirementsPrettyText = Complete contracts X and Y objectivesPrettyText = Orbit Jupiter and flyby at least two Galilean moons. nominalDurationYears = 8 @@ -1157,13 +1156,13 @@ RP0_PROGRAM } } } - + CONFIDENCECOSTS { Normal = 2650 Fast = 5300 } - + OPTIONALS { orbitJupiter_Rep = true @@ -1188,7 +1187,7 @@ disabled_RP0_PROGRAM { complete_program = JupiterObservation } - + OBJECTIVES { ATLEAST @@ -1200,13 +1199,13 @@ disabled_RP0_PROGRAM complete_contract = landingGanymede } } - + CONFIDENCECOSTS { Normal = 9600 Fast = 19200 } - + OPTIONALS { orbitJupiter_Rep = true @@ -1217,7 +1216,7 @@ RP0_PROGRAM { name = SaturnObservation title = Saturn Observation - description = Known for its photogenic rings, Saturn has long been a subject of observation and exploration. Visible from Earth with little more than a set of binoculars, Saturn's rings have intrigued observers for centuries. Further, with the highest number of moons in the entire Solar System, and more discovered with each additional mission, the Saturn system is a destination with extensive exploration opportunities. Titan, the largest moon of Saturn, may have an atmosphere conducive to life, while Enceladus is thought to contain liquid water below its icy exterior. Explore the Saturn system with uncrewed probes, analyzing the atmospheres of Saturn and Titan, and take a closer look at the larger moons of the system.

Historical missions to Saturn include flybys from Pioneer 11 and both Voyagers, while the Cassini orbiter mission operated from 2004 to 2017. + description = Known for its photogenic rings, Saturn has long been a subject of observation and exploration. Visible from Earth with little more than a set of binoculars, Saturn's rings have intrigued observers for centuries. Further, with the highest number of moons in the entire Solar System, and more discovered with each additional mission, the Saturn system is a destination with extensive exploration opportunities. Titan, the largest moon of Saturn, may have an atmosphere conducive to life, while Enceladus is thought to contain liquid water below its icy exterior. Explore the Saturn system with uncrewed probes, analyzing the atmospheres of Saturn and Titan, and take a closer look at the larger moons of the system.

Historical missions to Saturn include flybys from Pioneer 11 and both Voyagers, while the Cassini orbiter mission operated from 2004 to 2017. requirementsPrettyText = Complete contracts X and Y objectivesPrettyText = Send an orbiter to Saturn, an atmospheric probe to Titan or Saturn, and flyby two more moons in addition to Titan. @@ -1256,13 +1255,13 @@ RP0_PROGRAM } } } - + CONFIDENCECOSTS { Normal = 3650 Fast = 7300 } - + OPTIONALS { orbitSaturn_Rep = true @@ -1302,13 +1301,13 @@ disabled_RP0_PROGRAM complete_contract = landingRhea } } - + CONFIDENCECOSTS { Normal = 14400 Fast = 28800 } - + OPTIONALS { orbitSaturn_Rep = true @@ -1333,7 +1332,7 @@ RP0_PROGRAM { complete_program = EarlyInnerPlanetProbes } - + OBJECTIVES { ATLEAST @@ -1346,13 +1345,13 @@ RP0_PROGRAM complete_contract = flybyPluto } } - + CONFIDENCECOSTS { Normal = 3600 Fast = 7200 } - + OPTIONALS { flybyCharon = true @@ -1362,7 +1361,7 @@ RP0_PROGRAM RP0_PROGRAM { name = OuterGasGiantSurvey - title = Outer Gas Giant Survey + title = Outer Gas Giant Survey description = Pictures can help expand our knowledge of the outer Solar System, but scientific instruments and dwell times much longer than a hasty flyby are necessary to increase our understanding of these distant neighbors. Send orbiters to the two furthest gas giants and probe their atmospheres. While in the furthest reaches of our system, explore the moons of these giants as well. An upgraded Tracking Station and higher level comm tech will be necessary in order to receive scientific data over such great distances. requirementsPrettyText = Complete contracts X and Y objectivesPrettyText = Do this and that @@ -1377,10 +1376,10 @@ RP0_PROGRAM { complete_program = OuterPlanetFlyby } - + OBJECTIVES { - All + All { complete_contract = orbitUranus Any @@ -1400,13 +1399,13 @@ RP0_PROGRAM } } } - + CONFIDENCECOSTS { Normal = 7200 Fast = 14400 } - + OPTIONALS { orbitNeptune_Rep = true @@ -1418,7 +1417,7 @@ RP0_PROGRAM RP0_PROGRAM { name = PlutoLandings - title = Plutonian Landings + title = Plutonian Landings description = The only known double planetary system in the Solar System, Pluto and Charon have been tidally locked in orbit of each other in the darkest, coldest reaches of our system for eons. It is now time for you to land on them, quite possibly within a century of their discovery. Very little is known about these distant, icy worlds. Historically, even our most advanced probes have returned relatively little data compared to what we know about our closer neighbors. Explore the furthest reaches of the Solar System and land on this intriguing pair of dwarf planets. requirementsPrettyText = Complete contracts X and Y objectivesPrettyText = Land on Pluto and Charon. @@ -1440,13 +1439,13 @@ RP0_PROGRAM complete_contract = landingPluto complete_contract = landingCharon } - + CONFIDENCECOSTS { Normal = 16800 Fast = 33600 } - + OPTIONALS { roverPluto = true @@ -1482,7 +1481,7 @@ disabled_RP0_PROGRAM { complete_contract = TODO } - + CONFIDENCECOSTS { Normal = 13350 @@ -1514,7 +1513,7 @@ disabled_RP0_PROGRAM { complete_contract = TODO } - + CONFIDENCECOSTS { Normal = 28000 @@ -1546,7 +1545,7 @@ disabled_RP0_PROGRAM { complete_contract = TODO } - + CONFIDENCECOSTS { Normal = 10000 @@ -1578,7 +1577,7 @@ disabled_RP0_PROGRAM { complete_contract = TODO } - + CONFIDENCECOSTS { Normal = 40000 From 689e88a86eb943413627915e39e496f85f6bca93 Mon Sep 17 00:00:00 2001 From: Ballatik <67292986+Ballatik@users.noreply.github.com> Date: Sat, 14 Oct 2023 12:09:06 -0400 Subject: [PATCH 02/27] Remove ComSatPayload from early contracts Replacing comsatpayload with antenna parameter since testing satellites are kept by the player. Makes more sense to give them a possibly useful relay instead of a customer bus. --- .../Contracts/Earth Satellites/FirstGEOSat.cfg | 8 ++++---- .../Contracts/Earth Satellites/FirstGeosync.cfg | 17 ++++++++++++----- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/GameData/RP-1/Contracts/Earth Satellites/FirstGEOSat.cfg b/GameData/RP-1/Contracts/Earth Satellites/FirstGEOSat.cfg index 0b87ad48586..a56b5214e3b 100644 --- a/GameData/RP-1/Contracts/Earth Satellites/FirstGEOSat.cfg +++ b/GameData/RP-1/Contracts/Earth Satellites/FirstGEOSat.cfg @@ -74,11 +74,11 @@ CONTRACT_TYPE } PARAMETER { - name = HasComSatPayload - type = HasResource - resource = ComSatPayload + name = HasAntenna + type = HasAntenna + minAntennaPower = 100.0 minQuantity = 49.9 - title = Have a ComSatPayload of at least 50 units on the craft + title = Have an antenna hideChildren = true } PARAMETER diff --git a/GameData/RP-1/Contracts/Earth Satellites/FirstGeosync.cfg b/GameData/RP-1/Contracts/Earth Satellites/FirstGeosync.cfg index eb4777be149..76a8f1b44e6 100644 --- a/GameData/RP-1/Contracts/Earth Satellites/FirstGeosync.cfg +++ b/GameData/RP-1/Contracts/Earth Satellites/FirstGeosync.cfg @@ -42,6 +42,13 @@ CONTRACT_TYPE type = ProgramActive program = GEOCommNetwork } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = FirstGEOSat + invertRequirement = true + } PARAMETER { @@ -68,18 +75,18 @@ CONTRACT_TYPE } PARAMETER { - name = HasComSatPayload - type = HasResource - resource = ComSatPayload + name = HasAntenna + type = HasAntenna + minAntennaPower = 100.0 minQuantity = 49.9 - title = Have a ComSatPayload of at least 50 units on the craft + title = Have an antenna hideChildren = true } PARAMETER { name = Orbit type = Orbit - maxEccentricity = 0.05 // fixme + maxEccentricity = 0.05 minPeriod = 23h 54m maxPeriod = 23h 58m disableOnStateChange = false From 12b78ead187d7e8b0ad6a591d1143a9ec0a23ec2 Mon Sep 17 00:00:00 2001 From: Ballatik <67292986+Ballatik@users.noreply.github.com> Date: Sat, 14 Oct 2023 12:26:37 -0400 Subject: [PATCH 03/27] Initial balance pass Bring funding inline with CA, leave duration at 2 years. Change reputation values from placeholders. Loosen location parameter for network to reduce tedium. --- GameData/RP-1/Contracts/Earth Satellites/FirstGEOSat.cfg | 2 +- .../RP-1/Contracts/Earth Satellites/FirstTargetedGeo.cfg | 4 ++-- .../RP-1/Contracts/Earth Satellites/GEORepeatComSats.cfg | 2 +- .../RP-1/Contracts/Earth Satellites/GeoComSatNetwork.cfg | 8 ++++---- GameData/RP-1/Programs/Programs.cfg | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/GameData/RP-1/Contracts/Earth Satellites/FirstGEOSat.cfg b/GameData/RP-1/Contracts/Earth Satellites/FirstGEOSat.cfg index a56b5214e3b..413e2f02e22 100644 --- a/GameData/RP-1/Contracts/Earth Satellites/FirstGEOSat.cfg +++ b/GameData/RP-1/Contracts/Earth Satellites/FirstGEOSat.cfg @@ -30,7 +30,7 @@ CONTRACT_TYPE rewardScience = 0 rewardFunds = 0 failureFunds = 0 - rewardReputation = 40 + rewardReputation = 60 failureReputation = 0 // was @rewardReputation // ************ REQUIREMENTS ************ diff --git a/GameData/RP-1/Contracts/Earth Satellites/FirstTargetedGeo.cfg b/GameData/RP-1/Contracts/Earth Satellites/FirstTargetedGeo.cfg index 83b9a0244b4..d458d9203d9 100644 --- a/GameData/RP-1/Contracts/Earth Satellites/FirstTargetedGeo.cfg +++ b/GameData/RP-1/Contracts/Earth Satellites/FirstTargetedGeo.cfg @@ -9,7 +9,7 @@ CONTRACT_TYPE synopsis = Launch a geostationary satellite over the targeted point - completedMessage = Congratulations! The satellite is in orbit and connected to the groundstation. + completedMessage = Congratulations! The satellite has been placed in the customer's desired location. sortKey = 410 @@ -31,7 +31,7 @@ CONTRACT_TYPE rewardScience = 0 rewardFunds = 0 failureFunds = 0 - rewardReputation = 40 + rewardReputation = 80 failureReputation = 0 // was @rewardReputation // ************ REQUIREMENTS ************ diff --git a/GameData/RP-1/Contracts/Earth Satellites/GEORepeatComSats.cfg b/GameData/RP-1/Contracts/Earth Satellites/GEORepeatComSats.cfg index 821b10a8b25..7a4f0a6b089 100644 --- a/GameData/RP-1/Contracts/Earth Satellites/GEORepeatComSats.cfg +++ b/GameData/RP-1/Contracts/Earth Satellites/GEORepeatComSats.cfg @@ -85,7 +85,7 @@ CONTRACT_TYPE type = STATIONARY } } - + BEHAVIOUR { name = WaypointGenerator diff --git a/GameData/RP-1/Contracts/Earth Satellites/GeoComSatNetwork.cfg b/GameData/RP-1/Contracts/Earth Satellites/GeoComSatNetwork.cfg index 5f78ad93af0..cbc65147d91 100644 --- a/GameData/RP-1/Contracts/Earth Satellites/GeoComSatNetwork.cfg +++ b/GameData/RP-1/Contracts/Earth Satellites/GeoComSatNetwork.cfg @@ -29,7 +29,7 @@ CONTRACT_TYPE rewardScience = 0 rewardFunds = 0 failureFunds = 0 - rewardReputation = 40 + rewardReputation = 200 failureReputation = 0 // was @rewardReputation // ************ REQUIREMENTS ************ @@ -104,7 +104,7 @@ CONTRACT_TYPE type = VisitWaypoint index = 0 //distance = 42736000 - horizontalDistance = 1000000.0 // standard 1000km parking spot + horizontalDistance = 4000 showMessages = true completeInSequence = true disableOnStateChange = false @@ -173,7 +173,7 @@ CONTRACT_TYPE type = VisitWaypoint index = 1 //distance = 42736000 - horizontalDistance = 2000.0 + horizontalDistance = 4000.0 showMessages = true completeInSequence = true disableOnStateChange = false @@ -242,7 +242,7 @@ CONTRACT_TYPE type = VisitWaypoint index = 2 //distance = 42736000 - horizontalDistance = 2000.0 + horizontalDistance = 4000.0 showMessages = true completeInSequence = true disableOnStateChange = false diff --git a/GameData/RP-1/Programs/Programs.cfg b/GameData/RP-1/Programs/Programs.cfg index 13e5bea18b8..73c110c8084 100644 --- a/GameData/RP-1/Programs/Programs.cfg +++ b/GameData/RP-1/Programs/Programs.cfg @@ -436,7 +436,7 @@ RP0_PROGRAM requirementsPrettyText = Complete the Targeted Satellites Program objectivesPrettyText = Complete the Geostationary Communications Network. nominalDurationYears = 2 - baseFunding = 700000 + baseFunding = 560000 fundingCurve = MildBackloadedFundingCurve repDeltaOnCompletePerYearEarly = 420 repPenaltyPerYearLate = 420 From 60a0dd3dc35052775ed305e28517ed3a773fdd69 Mon Sep 17 00:00:00 2001 From: Ballatik <67292986+Ballatik@users.noreply.github.com> Date: Sun, 15 Oct 2023 22:09:19 -0400 Subject: [PATCH 04/27] Various testing fixes, add network contracts Fix contract requirements/disallows Replace antenna requirements with positive power Add optional bonus for being closer to targets 9need fixing) --- .../EarlyMolniyaSat.cfg | 16 +- .../Earth Satellites/FirstGEOSat.cfg | 11 +- .../Earth Satellites/FirstGeosync.cfg | 18 +- .../Earth Satellites/FirstTargetedGeo.cfg | 36 +- .../Earth Satellites/GEORepeatComSats.cfg | 90 ++-- ...omSatNetwork.cfg => GeoComSatNetwork3.cfg} | 28 +- .../Earth Satellites/GeoComSatNetwork4.cfg | 415 ++++++++++++++++++ .../Earth Satellites/MolniyaNetwork3.cfg | 279 ++++++++++++ GameData/RP-1/Programs/Programs.cfg | 8 +- 9 files changed, 833 insertions(+), 68 deletions(-) rename GameData/RP-1/Contracts/Earth Satellites/{GeoComSatNetwork.cfg => GeoComSatNetwork3.cfg} (88%) create mode 100644 GameData/RP-1/Contracts/Earth Satellites/GeoComSatNetwork4.cfg create mode 100644 GameData/RP-1/Contracts/Earth Satellites/MolniyaNetwork3.cfg diff --git a/GameData/RP-1/Contracts/Commercial Applications 1/EarlyMolniyaSat.cfg b/GameData/RP-1/Contracts/Commercial Applications 1/EarlyMolniyaSat.cfg index 93f337abf5a..f185adc42e7 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 1/EarlyMolniyaSat.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 1/EarlyMolniyaSat.cfg @@ -2,7 +2,7 @@ CONTRACT_TYPE { name = EarlyMolniyaSat title = Molniya Communications Satellite (Early) - group = CommApp + group = CommApp description = Program: Early Commercial Applications
Type: Optional


Now that satellite communications technology has been proven, launch more capable satellites to expand communication coverage further around Earth. Some customers want satellites that dwell longer over the higher latitudes using Molniya orbits. Launch a new communications satellite with the required specifications with the unique Molniya orbital parameters.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.

The reward of this contract will slowly increase over time but will be reset to 0 after each completion.&br;Current reward is at @rewardFactorPercent % of its nominal value. Elapsed/Expected Days: @elapsedDays / @RP0:expectedDays_EarlyComSat
Number of Contracts Completed: @index / unlimited
genericDescription = Put a satellite with the required amount of communications satellite payload into the desired orbit. @@ -38,11 +38,23 @@ CONTRACT_TYPE REQUIREMENT { + name = CommApp or GEOComm active + type = Any + + REQUIREMENT + { + name = ProgramActive + type = ProgramActive + program = GEOCommNetwork + } + REQUIREMENT + { name = ProgramActive type = ProgramActive program = CommercialApplications1 + } } - + REQUIREMENT { name = CompleteContract diff --git a/GameData/RP-1/Contracts/Earth Satellites/FirstGEOSat.cfg b/GameData/RP-1/Contracts/Earth Satellites/FirstGEOSat.cfg index 413e2f02e22..5bf717ccca4 100644 --- a/GameData/RP-1/Contracts/Earth Satellites/FirstGEOSat.cfg +++ b/GameData/RP-1/Contracts/Earth Satellites/FirstGEOSat.cfg @@ -74,12 +74,11 @@ CONTRACT_TYPE } PARAMETER { - name = HasAntenna - type = HasAntenna - minAntennaPower = 100.0 - minQuantity = 49.9 - title = Have an antenna - hideChildren = true + name = ResourceConsumption + type = ResourceConsumption + resource = ElectricCharge + minRate = -0.1 + title = Have positive electricity production } PARAMETER { diff --git a/GameData/RP-1/Contracts/Earth Satellites/FirstGeosync.cfg b/GameData/RP-1/Contracts/Earth Satellites/FirstGeosync.cfg index 76a8f1b44e6..ac0b9b4f0bb 100644 --- a/GameData/RP-1/Contracts/Earth Satellites/FirstGeosync.cfg +++ b/GameData/RP-1/Contracts/Earth Satellites/FirstGeosync.cfg @@ -49,6 +49,13 @@ CONTRACT_TYPE contractType = FirstGEOSat invertRequirement = true } + REQUIREMENT + { + name = CompleteContract + type = CompleteContract + contractType = FirstGEOSat + invertRequirement = true + } PARAMETER { @@ -75,12 +82,11 @@ CONTRACT_TYPE } PARAMETER { - name = HasAntenna - type = HasAntenna - minAntennaPower = 100.0 - minQuantity = 49.9 - title = Have an antenna - hideChildren = true + name = ResourceConsumption + type = ResourceConsumption + resource = ElectricCharge + minRate = -0.1 + title = Have positive electricity production } PARAMETER { diff --git a/GameData/RP-1/Contracts/Earth Satellites/FirstTargetedGeo.cfg b/GameData/RP-1/Contracts/Earth Satellites/FirstTargetedGeo.cfg index d458d9203d9..8058cc39420 100644 --- a/GameData/RP-1/Contracts/Earth Satellites/FirstTargetedGeo.cfg +++ b/GameData/RP-1/Contracts/Earth Satellites/FirstTargetedGeo.cfg @@ -31,7 +31,7 @@ CONTRACT_TYPE rewardScience = 0 rewardFunds = 0 failureFunds = 0 - rewardReputation = 80 + rewardReputation = 60 failureReputation = 0 // was @rewardReputation // ************ REQUIREMENTS ************ @@ -98,11 +98,41 @@ CONTRACT_TYPE type = VisitWaypoint index = 0 //distance = 42736000 - horizontalDistance = 2000.0 + horizontalDistance = 4000.0 showMessages = true disableOnStateChange = false } + PARAMETER + { + name = Duration + type = Duration + + duration = 2m + preWaitText = Check for stable orbit + waitingText = Checking for stable orbit + completionText = Stable orbit: Confirmed + } + PARAMETER + { + name = OptVesselGroup + type = VesselParameterGroup + title = Obtain a more precise orbit + rewardReputation = 20 + optional = true + hideChildren = true + + PARAMETER + { + name = VisitWaypoint + type = VisitWaypoint + index = 0 + //distance = 42736000 + horizontalDistance = 2000.0 + showMessages = true + disableOnStateChange = false + } + } } BEHAVIOUR { @@ -122,7 +152,7 @@ CONTRACT_TYPE name = TransferVessel type = DestroyVessel onState = CONTRACT_SUCCESS - vessel = FirstNavSat + vessel = TargetedGeo } BEHAVIOUR diff --git a/GameData/RP-1/Contracts/Earth Satellites/GEORepeatComSats.cfg b/GameData/RP-1/Contracts/Earth Satellites/GEORepeatComSats.cfg index 7a4f0a6b089..703b8662885 100644 --- a/GameData/RP-1/Contracts/Earth Satellites/GEORepeatComSats.cfg +++ b/GameData/RP-1/Contracts/Earth Satellites/GEORepeatComSats.cfg @@ -32,7 +32,7 @@ CONTRACT_TYPE rewardScience = 0 rewardFunds = 0 failureFunds = 0 - rewardReputation = Round(110 * Pow((@AdvComSat/HasComSatPayload/minQuantity / 350), 0.5) * @rewardFactor, 1) + rewardReputation = Round(80 * Pow((@AdvComSat/HasComSatPayload/minQuantity / 350), 0.5) * @rewardFactor, 1) failureReputation = 0 // was @rewardReputation // ************ REQUIREMENTS ************ @@ -74,16 +74,19 @@ CONTRACT_TYPE tag = exclude_RepeatableComSat invertRequirement = true } - - BEHAVIOUR + REQUIREMENT { - name = OrbitGenerator - type = OrbitGenerator - - RANDOM_ORBIT - { - type = STATIONARY - } + name = AcceptContract + type = AcceptContract + contractType = GeoComSatNetwork3 + invertRequirement = true + } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = GeoComSatNetwork4 + invertRequirement = true } BEHAVIOUR @@ -93,7 +96,7 @@ CONTRACT_TYPE RANDOM_WAYPOINT { - name = Geostationary Weather Satellite + name = Geostationary Comm Satellite icon = thermometer altitude = 0 forceEquatorial = true @@ -179,12 +182,46 @@ CONTRACT_TYPE } PARAMETER { - name = ReachSpecificOrbit - type = ReachSpecificOrbit - displayNotes = true + name = Orbit + type = Orbit + maxInclination = 2 + maxEccentricity = 0.01 + minPeriod = 23h 54m + maxPeriod = 23h 58m + disableOnStateChange = false + title = Achieve a Geostationary orbit within the stated parameters near the waypoint + } + PARAMETER + { + name = VisitWaypoint + type = VisitWaypoint index = 0 - deviationWindow = 4 + //distance = 42736000 + horizontalDistance = 4000.0 + showMessages = true + disableOnStateChange = false + } + PARAMETER + { + name = OptVesselGroup + type = VesselParameterGroup + title = Obtain a more precise orbit + rewardReputation = 20 + optional = true + completeInSequence = true + hideChildren = true + PARAMETER + { + name = Orbit + type = Orbit + maxInclination = 2 + maxEccentricity = 0.01 + minPeriod = 23h 54m + maxPeriod = 23h 58m + disableOnStateChange = false + title = Achieve a Geostationary orbit in an ideal location above waypoint + } PARAMETER { name = VisitWaypoint @@ -192,22 +229,17 @@ CONTRACT_TYPE index = 0 //distance = 42736000 horizontalDistance = 2000.0 - showMessages = true - completeInSequence = true disableOnStateChange = false } - - PARAMETER - { - name = Duration - type = Duration - - duration = 2m - - preWaitText = Check for stable orbit - waitingText = Checking for stable orbit - completionText = Stable orbit: Confirmed - } + } + PARAMETER + { + name = Duration + type = Duration + duration = 2m + preWaitText = Check for stable orbit + waitingText = Checking for stable orbit + completionText = Stable orbit: Confirmed } } diff --git a/GameData/RP-1/Contracts/Earth Satellites/GeoComSatNetwork.cfg b/GameData/RP-1/Contracts/Earth Satellites/GeoComSatNetwork3.cfg similarity index 88% rename from GameData/RP-1/Contracts/Earth Satellites/GeoComSatNetwork.cfg rename to GameData/RP-1/Contracts/Earth Satellites/GeoComSatNetwork3.cfg index cbc65147d91..c2a7bcc3621 100644 --- a/GameData/RP-1/Contracts/Earth Satellites/GeoComSatNetwork.cfg +++ b/GameData/RP-1/Contracts/Earth Satellites/GeoComSatNetwork3.cfg @@ -1,11 +1,11 @@ CONTRACT_TYPE { - name = GeoComSatNetwork - title = Geostationary Communications Network + name = GeoComSatNetwork3 + title = Geostationary Communications Network (3 Satellites) group = GEOCommNetwork agent = Federation Aeronautique Internationale - description = Program: Geostationary Communications Network
Type: Required


Through measuring the Doppler shift of radio signals transmitted from a satellite in a known orbit, it is possible for a receiver on the ground to establish their location, which would have many applications both civilian and military. To test the principle and develop receiver equipment, it is necessary to have a test navigational satellite in orbit.
Historical example: Transit 1B (119 kg, Thor-Ablestar).

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer. + description = Program: Geostationary Communications Network
Type: Required


A geostationary satellite can provide continuous coverage for a large section of Earth, but to transmit everywhere requires more than one. Launch 3 satellites into geostationary orbits spaced 120 degrees apart.
Historical example: Syncom 4 (1-5) (1.3t, Shuttle Discovery) lanched starting in August of 1984.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer. synopsis = Launch a 3 Satellite Geostationary Communications Network @@ -53,12 +53,18 @@ CONTRACT_TYPE contractType = GEORepeatComSats invertRequirement = true } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = GeoComSatNetwork4 + invertRequirement = true + } PARAMETER { name = GEOCommSat1 type = VesselParameterGroup - define = GEO CommSat I disableOnStateChange = false @@ -66,7 +72,6 @@ CONTRACT_TYPE { name = IsNotVessel type = IsNotVessel - vessel = GEO CommSat II } @@ -74,7 +79,6 @@ CONTRACT_TYPE { name = IsNotVessel type = IsNotVessel - vessel = GEO CommSat III } @@ -114,9 +118,7 @@ CONTRACT_TYPE { name = Duration type = Duration - duration = 2m - preWaitText = Check for stable orbit waitingText = Checking for stable orbit completionText = Stable orbit: Confirmed @@ -127,7 +129,6 @@ CONTRACT_TYPE { name = GEOCommSat2 type = VesselParameterGroup - define = GEO CommSat II disableOnStateChange = false @@ -135,7 +136,6 @@ CONTRACT_TYPE { name = IsNotVessel type = IsNotVessel - vessel = GEO CommSat I } @@ -143,7 +143,6 @@ CONTRACT_TYPE { name = IsNotVessel type = IsNotVessel - vessel = GEO CommSat III } @@ -183,9 +182,7 @@ CONTRACT_TYPE { name = Duration type = Duration - duration = 2m - preWaitText = Check for stable orbit waitingText = Checking for stable orbit completionText = Stable orbit: Confirmed @@ -196,7 +193,6 @@ CONTRACT_TYPE { name = GEOCommSat3 type = VesselParameterGroup - define = GEO CommSat III disableOnStateChange = false @@ -204,7 +200,6 @@ CONTRACT_TYPE { name = IsNotVessel type = IsNotVessel - vessel = GEO CommSat I } @@ -212,7 +207,6 @@ CONTRACT_TYPE { name = IsNotVessel type = IsNotVessel - vessel = GEO CommSat II } @@ -252,9 +246,7 @@ CONTRACT_TYPE { name = Duration type = Duration - duration = 2m - preWaitText = Check for stable orbit waitingText = Checking for stable orbit completionText = Stable orbit: Confirmed diff --git a/GameData/RP-1/Contracts/Earth Satellites/GeoComSatNetwork4.cfg b/GameData/RP-1/Contracts/Earth Satellites/GeoComSatNetwork4.cfg new file mode 100644 index 00000000000..1ee2c345950 --- /dev/null +++ b/GameData/RP-1/Contracts/Earth Satellites/GeoComSatNetwork4.cfg @@ -0,0 +1,415 @@ +CONTRACT_TYPE +{ + name = GeoComSatNetwork4 + title = Geostationary Communications Network (4 Satellites) + group = GEOCommNetwork + agent = Federation Aeronautique Internationale + + description = Program: Geostationary Communications Network
Type: Required


A geostationary satellite can provide continuous coverage for a large section of Earth, but to transmit to every longitude requires more than one. Launch 4 satellites into geostationary orbits spaced 90 degrees apart.
Historical example: Syncom 4 (1-5) (1.3t, Shuttle Discovery) lanched starting in August of 1984.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer. + + synopsis = Launch a 3 Satellite Geostationary Communications Network + + completedMessage = Congratulations! The satellites are in orbit and spaced to provide complete coverage. + + sortKey = 903 + + cancellable = true + declinable = false + autoAccept = false + minExpiry = 0 + maxExpiry = 0 + maxCompletions = 1 + maxSimultaneous = 1 + deadline = 0 + targetBody = HomeWorld() + + // ************ REWARDS ************ + prestige = Trivial // 1.0x + advanceFunds = 0 + rewardScience = 0 + rewardFunds = 0 + failureFunds = 0 + rewardReputation = 260 + failureReputation = 0 // was @rewardReputation + + // ************ REQUIREMENTS ************ + + REQUIREMENT + { + name = ProgramActive + type = ProgramActive + program = GEOCommNetwork + } + REQUIREMENT + { + name = CompleteContract + type = CompleteContract + contractType = FirstTargetedGeo + } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = GEORepeatComSats + invertRequirement = true + } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = GeoComSatNetwork3 + invertRequirement = true + } + + PARAMETER + { + name = GEOCommSat1 + type = VesselParameterGroup + define = GEO CommSat I + disableOnStateChange = false + + PARAMETER + { + name = IsNotVessel + type = IsNotVessel + vessel = GEO CommSat II + } + + PARAMETER + { + name = IsNotVessel + type = IsNotVessel + vessel = GEO CommSat III + } + + PARAMETER + { + name = IsNotVessel + type = IsNotVessel + vessel = GEO CommSat IV + } + + PARAMETER + { + name = HasComSatPayload + type = HasResource + resource = ComSatPayload + minQuantity = 124.9 + title = Have a ComSatPayload of at least 125 units on the craft + disableOnStateChange = false + } + + PARAMETER + { + name = Orbit + type = Orbit + maxInclination = 2 + maxEccentricity = 0.01 + minPeriod = 23h 54m + maxPeriod = 23h 58m + disableOnStateChange = false + title = Achieve a Geostationary orbit within the stated parameters near the waypoint + PARAMETER + { + name = VisitWaypoint + type = VisitWaypoint + index = 0 + //distance = 42736000 + horizontalDistance = 4000 + showMessages = true + completeInSequence = true + disableOnStateChange = false + } + + PARAMETER + { + name = Duration + type = Duration + duration = 2m + preWaitText = Check for stable orbit + waitingText = Checking for stable orbit + completionText = Stable orbit: Confirmed + } + } + } + PARAMETER + { + name = GEOCommSat2 + type = VesselParameterGroup + define = GEO CommSat II + disableOnStateChange = false + + PARAMETER + { + name = IsNotVessel + type = IsNotVessel + vessel = GEO CommSat I + } + + PARAMETER + { + name = IsNotVessel + type = IsNotVessel + vessel = GEO CommSat III + } + + PARAMETER + { + name = IsNotVessel + type = IsNotVessel + vessel = GEO CommSat IV + } + + PARAMETER + { + name = HasComSatPayload + type = HasResource + resource = ComSatPayload + minQuantity = 124.9 + title = Have a ComSatPayload of at least 125 units on the craft + disableOnStateChange = false + } + + PARAMETER + { + name = Orbit + type = Orbit + maxInclination = 2 + maxEccentricity = 0.01 + minPeriod = 23h 54m + maxPeriod = 23h 58m + disableOnStateChange = false + title = Achieve a Geostationary orbit within the stated parameters near the waypoint + PARAMETER + { + name = VisitWaypoint + type = VisitWaypoint + index = 1 + //distance = 42736000 + horizontalDistance = 4000.0 + showMessages = true + completeInSequence = true + disableOnStateChange = false + } + + PARAMETER + { + name = Duration + type = Duration + duration = 2m + preWaitText = Check for stable orbit + waitingText = Checking for stable orbit + completionText = Stable orbit: Confirmed + } + } + } + PARAMETER + { + name = GEOCommSat3 + type = VesselParameterGroup + + define = GEO CommSat III + disableOnStateChange = false + + PARAMETER + { + name = IsNotVessel + type = IsNotVessel + vessel = GEO CommSat I + } + + PARAMETER + { + name = IsNotVessel + type = IsNotVessel + vessel = GEO CommSat II + } + + PARAMETER + { + name = IsNotVessel + type = IsNotVessel + vessel = GEO CommSat IV + } + + PARAMETER + { + name = HasComSatPayload + type = HasResource + resource = ComSatPayload + minQuantity = 124.9 + title = Have a ComSatPayload of at least 125 units on the craft + disableOnStateChange = false + } + + PARAMETER + { + name = Orbit + type = Orbit + maxInclination = 2 + maxEccentricity = 0.01 + minPeriod = 23h 54m + maxPeriod = 23h 58m + disableOnStateChange = false + title = Achieve a Geostationary orbit within the stated parameters near the waypoint + PARAMETER + { + name = VisitWaypoint + type = VisitWaypoint + index = 2 + //distance = 42736000 + horizontalDistance = 4000.0 + showMessages = true + completeInSequence = true + disableOnStateChange = false + } + + PARAMETER + { + name = Duration + type = Duration + duration = 2m + preWaitText = Check for stable orbit + waitingText = Checking for stable orbit + completionText = Stable orbit: Confirmed + } + } + } + PARAMETER + { + name = GEOCommSat4 + type = VesselParameterGroup + define = GEO CommSat IV + disableOnStateChange = false + + PARAMETER + { + name = IsNotVessel + type = IsNotVessel + vessel = GEO CommSat I + } + + PARAMETER + { + name = IsNotVessel + type = IsNotVessel + vessel = GEO CommSat II + } + + PARAMETER + { + name = IsNotVessel + type = IsNotVessel + vessel = GEO CommSat III + } + + PARAMETER + { + name = HasComSatPayload + type = HasResource + resource = ComSatPayload + minQuantity = 124.9 + title = Have a ComSatPayload of at least 125 units on the craft + disableOnStateChange = false + } + + PARAMETER + { + name = Orbit + type = Orbit + maxInclination = 2 + maxEccentricity = 0.01 + minPeriod = 23h 54m + maxPeriod = 23h 58m + disableOnStateChange = false + title = Achieve a Geostationary orbit within the stated parameters near the waypoint + PARAMETER + { + name = VisitWaypoint + type = VisitWaypoint + index = 2 + //distance = 42736000 + horizontalDistance = 4000.0 + showMessages = true + completeInSequence = true + disableOnStateChange = false + } + + PARAMETER + { + name = Duration + type = Duration + duration = 2m + preWaitText = Check for stable orbit + waitingText = Checking for stable orbit + completionText = Stable orbit: Confirmed + } + } + } + BEHAVIOUR + { + name = WaypointGenerator + type = WaypointGenerator + + WAYPOINT + { + name = Geostationary Ground Target I + icon = thermometer + altitude = 0 + latitude = 0 + longitude = 0 + } + WAYPOINT + { + name = Geostationary Ground Target II + icon = thermometer + altitude = 0 + latitude = 0 + longitude = 90 + } + WAYPOINT + { + name = Geostationary Ground Target III + icon = thermometer + altitude = 0 + latitude = 0 + longitude = 180 + } + WAYPOINT + { + name = Geostationary Ground Target III + icon = thermometer + altitude = 0 + latitude = 0 + longitude = 270 + } + } + + BEHAVIOUR + { + name = TransferVessel + type = DestroyVessel + onState = CONTRACT_SUCCESS + vessel = GEO CommSat I + vessel = GEO CommSat II + vessel = GEO CommSat III + vessel = GEO CommSat IV + } + + BEHAVIOUR + { + name = VesselDestroyed + type = DialogBox + DIALOG_BOX + { + title = Vessel Ownership Transferred + condition = CONTRACT_SUCCESS + position = CENTER + width = 0.5 + TEXT + { + text = The contract has been completed successfully and the satellites have been transferred to the customer. + } + } + } +} diff --git a/GameData/RP-1/Contracts/Earth Satellites/MolniyaNetwork3.cfg b/GameData/RP-1/Contracts/Earth Satellites/MolniyaNetwork3.cfg new file mode 100644 index 00000000000..2ef3d3bae6d --- /dev/null +++ b/GameData/RP-1/Contracts/Earth Satellites/MolniyaNetwork3.cfg @@ -0,0 +1,279 @@ +CONTRACT_TYPE +{ + name = MolniyaNetwork3 + title = Molniya Communications Network (3 Satellites) + group = GEOCommNetwork + agent = Federation Aeronautique Internationale + + description = Program: Geostationary Communications Network
Type: Required


Geostationary satellites do not provide good coverage in the higher latitudes. Molniya orbits loiter over those latitudes for longer periods, to provide constant coverage with fewer satellites.
Historical example: Molniya 1-1 (1.6t, Molniya 8K78) launched starting in April of 1965.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.

NOTE: If you are completing this with a single launch, you must separate the 3 vessels before entering the specified orbit. + + synopsis = Launch a 3 Satellite Molniya Communications Network + + completedMessage = Congratulations! The satellites are in orbit and spaced to provide complete coverage. + + sortKey = 903 + + cancellable = true + declinable = false + autoAccept = false + minExpiry = 0 + maxExpiry = 0 + maxCompletions = 1 + maxSimultaneous = 1 + deadline = 0 + targetBody = HomeWorld() + + // ************ REWARDS ************ + prestige = Trivial // 1.0x + advanceFunds = 0 + rewardScience = 0 + rewardFunds = 0 + failureFunds = 0 + rewardReputation = 160 + failureReputation = 0 // was @rewardReputation + + // ************ REQUIREMENTS ************ + + REQUIREMENT + { + name = ProgramActive + type = ProgramActive + program = GEOCommNetwork + } + REQUIREMENT + { + name = CompleteContract + type = CompleteContract + contractType = FirstMolniyaSat-CA + } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = EarlyMolniyaSat + invertRequirement = true + } + + PARAMETER + { + name = MolniyaCom1 + type = VesselParameterGroup + define = MolniyaCom1 + dissassociateVesselsOnContractCompletion = true + title = Molniya Network Sat I + + PARAMETER + { + name = IsNotVessel + type = IsNotVessel + + vessel = Molniya Network Sat II + } + + PARAMETER + { + name = IsNotVessel + type = IsNotVessel + + vessel = Molniya Network Sat III + } + + PARAMETER + { + name = NewVessel + type = NewVessel + title = Launch a new vessel + hideChildren = true + } + PARAMETER + { + name = Crewmembers + type = HasCrew + minCrew = 0 + maxCrew = 0 + title = Uncrewed + hideChildren = true + } + PARAMETER + { + name = HasComSatPayload + type = HasResource + resource = ComSatPayload + minQuantity = 124.9 + title = Have a ComSatPayload of at least 125 units on the craft + disableOnStateChange = false + } + PARAMETER + { + name = ReachOrbit + type = Orbit + title = Reach the correct orbit within the parameters. Note, the argument of periapsis values mean that the apogee needs to be high in the northern latitudes. + minInclination = 61.4 + maxInclination = 65.4 + minEccentricity = 0.7 + minArgumentOfPeriapsis = 220 + maxArgumentOfPeriapsis = 320 + minPeA = 500000 + minPeriod = 11h 56m 2s + maxPeriod = 12h 00m 2s + disableOnStateChange = true + } + } + PARAMETER + { + name = MolniyaCom2 + type = VesselParameterGroup + define = MolniyaCom2 + dissassociateVesselsOnContractCompletion = true + title = Molniya Network Sat II + + PARAMETER + { + name = IsNotVessel + type = IsNotVessel + + vessel = Molniya Network Sat I + } + + PARAMETER + { + name = IsNotVessel + type = IsNotVessel + + vessel = Molniya Network Sat III + } + + PARAMETER + { + name = NewVessel + type = NewVessel + title = Launch a new vessel + hideChildren = true + } + PARAMETER + { + name = Crewmembers + type = HasCrew + minCrew = 0 + maxCrew = 0 + title = Uncrewed + hideChildren = true + } + PARAMETER + { + name = HasComSatPayload + type = HasResource + resource = ComSatPayload + minQuantity = 124.9 + title = Have a ComSatPayload of at least 125 units on the craft + disableOnStateChange = false + } + PARAMETER + { + name = ReachOrbit + type = Orbit + title = Reach the correct orbit within the parameters. Note, the argument of periapsis values mean that the apogee needs to be high in the northern latitudes. + minInclination = 61.4 + maxInclination = 65.4 + minEccentricity = 0.7 + minArgumentOfPeriapsis = 220 + maxArgumentOfPeriapsis = 320 + minPeA = 500000 + minPeriod = 11h 56m 2s + maxPeriod = 12h 00m 2s + disableOnStateChange = true + } + } + PARAMETER + { + name = MolniyaCom3 + type = VesselParameterGroup + define = MolniyaCom3 + dissassociateVesselsOnContractCompletion = true + title = Molniya Network Sat III + + PARAMETER + { + name = IsNotVessel + type = IsNotVessel + + vessel = Molniya Network Sat I + } + + PARAMETER + { + name = IsNotVessel + type = IsNotVessel + + vessel = Molniya Network Sat II + } + + PARAMETER + { + name = NewVessel + type = NewVessel + title = Launch a new vessel + hideChildren = true + } + PARAMETER + { + name = Crewmembers + type = HasCrew + minCrew = 0 + maxCrew = 0 + title = Uncrewed + hideChildren = true + } + PARAMETER + { + name = HasComSatPayload + type = HasResource + resource = ComSatPayload + minQuantity = 124.9 + title = Have a ComSatPayload of at least 125 units on the craft + disableOnStateChange = false + } + PARAMETER + { + name = ReachOrbit + type = Orbit + title = Reach the correct orbit within the parameters. Note, the argument of periapsis values mean that the apogee needs to be high in the northern latitudes. + minInclination = 61.4 + maxInclination = 65.4 + minEccentricity = 0.7 + minArgumentOfPeriapsis = 220 + maxArgumentOfPeriapsis = 320 + minPeA = 500000 + minPeriod = 11h 56m 2s + maxPeriod = 12h 00m 2s + disableOnStateChange = true + } + } + + BEHAVIOUR + { + name = TransferVessel + type = DestroyVessel + onState = CONTRACT_SUCCESS + vessel = GEO CommSat I + vessel = GEO CommSat II + vessel = GEO CommSat III + } + + BEHAVIOUR + { + name = VesselDestroyed + type = DialogBox + DIALOG_BOX + { + title = Vessel Ownership Transferred + condition = CONTRACT_SUCCESS + position = CENTER + width = 0.5 + TEXT + { + text = The contract has been completed successfully and the satellites have been transferred to the customer. + } + } + } +} diff --git a/GameData/RP-1/Programs/Programs.cfg b/GameData/RP-1/Programs/Programs.cfg index 73c110c8084..b52d487772a 100644 --- a/GameData/RP-1/Programs/Programs.cfg +++ b/GameData/RP-1/Programs/Programs.cfg @@ -457,9 +457,9 @@ RP0_PROGRAM complete_contract = FirstTargetedGeo ANY { - complete_contract = GeoComSatNetwork - // complete_contract = MolniyaArray - + complete_contract = GeoComSatNetwork3 + complete_contract = GeoComSatNetwork4 + complete_contract = MolniyaNetwork3 } } @@ -467,7 +467,7 @@ RP0_PROGRAM { FirstGeosync = true GEORepeatComSats = true - // MolniyaRep = true + EarlyMolniyaSat = true } CONFIDENCECOSTS From 44271141314cb0dd5259959e5b11568ed2bcb538 Mon Sep 17 00:00:00 2001 From: Ballatik <67292986+Ballatik@users.noreply.github.com> Date: Tue, 17 Oct 2023 16:05:05 -0400 Subject: [PATCH 05/27] Various Fixes Fix bonus for precise targeting Adjust reward to account for bonus --- .../Earth Satellites/FirstGEOSat.cfg | 1 + .../Earth Satellites/FirstGeosync.cfg | 1 + .../Earth Satellites/FirstTargetedGeo.cfg | 36 ++++++++++++------- .../Earth Satellites/GEORepeatComSats.cfg | 6 ++-- 4 files changed, 27 insertions(+), 17 deletions(-) diff --git a/GameData/RP-1/Contracts/Earth Satellites/FirstGEOSat.cfg b/GameData/RP-1/Contracts/Earth Satellites/FirstGEOSat.cfg index 5bf717ccca4..f39754d84e2 100644 --- a/GameData/RP-1/Contracts/Earth Satellites/FirstGEOSat.cfg +++ b/GameData/RP-1/Contracts/Earth Satellites/FirstGEOSat.cfg @@ -55,6 +55,7 @@ CONTRACT_TYPE type = VesselParameterGroup title = Geostationary satellite define = Geostationary + dissassociateVesselsOnContractCompletion = true PARAMETER { diff --git a/GameData/RP-1/Contracts/Earth Satellites/FirstGeosync.cfg b/GameData/RP-1/Contracts/Earth Satellites/FirstGeosync.cfg index ac0b9b4f0bb..44e0593b7ad 100644 --- a/GameData/RP-1/Contracts/Earth Satellites/FirstGeosync.cfg +++ b/GameData/RP-1/Contracts/Earth Satellites/FirstGeosync.cfg @@ -63,6 +63,7 @@ CONTRACT_TYPE type = VesselParameterGroup title = Targeted Geostationary define = FirstGeosync + dissassociateVesselsOnContractCompletion = true PARAMETER { diff --git a/GameData/RP-1/Contracts/Earth Satellites/FirstTargetedGeo.cfg b/GameData/RP-1/Contracts/Earth Satellites/FirstTargetedGeo.cfg index 8058cc39420..e0b032b2b08 100644 --- a/GameData/RP-1/Contracts/Earth Satellites/FirstTargetedGeo.cfg +++ b/GameData/RP-1/Contracts/Earth Satellites/FirstTargetedGeo.cfg @@ -103,25 +103,25 @@ CONTRACT_TYPE disableOnStateChange = false } PARAMETER - { - name = Duration - type = Duration - - duration = 2m - - preWaitText = Check for stable orbit - waitingText = Checking for stable orbit - completionText = Stable orbit: Confirmed - } - PARAMETER { name = OptVesselGroup type = VesselParameterGroup title = Obtain a more precise orbit rewardReputation = 20 optional = true - hideChildren = true + completeInSequence = true + PARAMETER + { + name = Orbit + type = Orbit + maxInclination = 2 + maxEccentricity = 0.01 + minPeriod = 23h 54m + maxPeriod = 23h 58m + disableOnStateChange = false + title = Achieve a Geostationary orbit in an ideal location above waypoint + } PARAMETER { name = VisitWaypoint @@ -129,10 +129,20 @@ CONTRACT_TYPE index = 0 //distance = 42736000 horizontalDistance = 2000.0 - showMessages = true disableOnStateChange = false } } + PARAMETER + { + name = Duration + type = Duration + + duration = 2m + + preWaitText = Check for stable orbit + waitingText = Checking for stable orbit + completionText = Stable orbit: Confirmed + } } BEHAVIOUR { diff --git a/GameData/RP-1/Contracts/Earth Satellites/GEORepeatComSats.cfg b/GameData/RP-1/Contracts/Earth Satellites/GEORepeatComSats.cfg index 703b8662885..67b183826c2 100644 --- a/GameData/RP-1/Contracts/Earth Satellites/GEORepeatComSats.cfg +++ b/GameData/RP-1/Contracts/Earth Satellites/GEORepeatComSats.cfg @@ -32,7 +32,7 @@ CONTRACT_TYPE rewardScience = 0 rewardFunds = 0 failureFunds = 0 - rewardReputation = Round(80 * Pow((@AdvComSat/HasComSatPayload/minQuantity / 350), 0.5) * @rewardFactor, 1) + rewardReputation = Round(60 * Pow((@AdvComSat/HasComSatPayload/minQuantity / 350), 0.5) * @rewardFactor, 1) failureReputation = 0 // was @rewardReputation // ************ REQUIREMENTS ************ @@ -152,7 +152,6 @@ CONTRACT_TYPE name = AdvComSat type = VesselParameterGroup define = AdvComSatellite - dissassociateVesselsOnContractCompletion = true title = Commercial communications satellite PARAMETER @@ -206,10 +205,9 @@ CONTRACT_TYPE name = OptVesselGroup type = VesselParameterGroup title = Obtain a more precise orbit - rewardReputation = 20 + rewardReputation = Round(20 * Pow((@AdvComSat/HasComSatPayload/minQuantity / 350), 0.5) * @rewardFactor, 1) optional = true completeInSequence = true - hideChildren = true PARAMETER { From 4ffc9508aff6599609cf52e726545d2987b71e0e Mon Sep 17 00:00:00 2001 From: Ballatik <67292986+Ballatik@users.noreply.github.com> Date: Wed, 18 Oct 2023 07:29:24 -0400 Subject: [PATCH 06/27] One fix, and moving to program testing Fixed bonus scaling in GEORepeatSats Uncommented program requirement for program so I can test it all in sequence --- .../Earth Satellites/GEORepeatComSats.cfg | 2 +- GameData/RP-1/Programs/Programs.cfg | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/GameData/RP-1/Contracts/Earth Satellites/GEORepeatComSats.cfg b/GameData/RP-1/Contracts/Earth Satellites/GEORepeatComSats.cfg index 67b183826c2..edddb756ebb 100644 --- a/GameData/RP-1/Contracts/Earth Satellites/GEORepeatComSats.cfg +++ b/GameData/RP-1/Contracts/Earth Satellites/GEORepeatComSats.cfg @@ -205,7 +205,7 @@ CONTRACT_TYPE name = OptVesselGroup type = VesselParameterGroup title = Obtain a more precise orbit - rewardReputation = Round(20 * Pow((@AdvComSat/HasComSatPayload/minQuantity / 350), 0.5) * @rewardFactor, 1) + rewardReputation = Round(20 * @rewardFactor, 1) optional = true completeInSequence = true diff --git a/GameData/RP-1/Programs/Programs.cfg b/GameData/RP-1/Programs/Programs.cfg index b52d487772a..8fc93489f52 100644 --- a/GameData/RP-1/Programs/Programs.cfg +++ b/GameData/RP-1/Programs/Programs.cfg @@ -432,7 +432,7 @@ RP0_PROGRAM { name = GEOCommNetwork title = Geostationary Communication Network - description = Geosynchronous, Geostationary, and Molniya orbits have the potential to improve satellite coverage and simplify ground antenna tracking. This program tasks you with creating a 3-satellite Geostationary or Molniya Network for communication. + description = Geosynchronous, Geostationary, and Molniya orbits have the potential to improve satellite coverage and simplify ground antenna tracking. This program tasks you with creating a 3 or 4 satellite Geostationary or Molniya Network for communication. requirementsPrettyText = Complete the Targeted Satellites Program objectivesPrettyText = Complete the Geostationary Communications Network. nominalDurationYears = 2 @@ -442,14 +442,14 @@ RP0_PROGRAM repPenaltyPerYearLate = 420 slots = 2 - // REQUIREMENTS - // { - // ANY - // { - // complete_program = TargetedSats - // complete_program = CommercialApplications1 - // } - // } + REQUIREMENTS + { + ANY + { + complete_program = TargetedSats + complete_program = CommercialApplications1 + } + } OBJECTIVES { From 4626fb75fd0be4c63f540411d126698eb3d2ac0f Mon Sep 17 00:00:00 2001 From: Ballatik <67292986+Ballatik@users.noreply.github.com> Date: Wed, 18 Oct 2023 18:21:31 -0400 Subject: [PATCH 07/27] Update MolniyaNetwork3.cfg Added max payload and an intermediate orbit as a way to force at least some spacing when all 3 are launched at once. Also fixed naming issue. --- .../Earth Satellites/MolniyaNetwork3.cfg | 84 ++++++++++++++++--- 1 file changed, 72 insertions(+), 12 deletions(-) diff --git a/GameData/RP-1/Contracts/Earth Satellites/MolniyaNetwork3.cfg b/GameData/RP-1/Contracts/Earth Satellites/MolniyaNetwork3.cfg index 2ef3d3bae6d..5ba9e0269b2 100644 --- a/GameData/RP-1/Contracts/Earth Satellites/MolniyaNetwork3.cfg +++ b/GameData/RP-1/Contracts/Earth Satellites/MolniyaNetwork3.cfg @@ -58,9 +58,8 @@ CONTRACT_TYPE { name = MolniyaCom1 type = VesselParameterGroup - define = MolniyaCom1 + define = Molniya Network Sat I dissassociateVesselsOnContractCompletion = true - title = Molniya Network Sat I PARAMETER { @@ -100,10 +99,21 @@ CONTRACT_TYPE type = HasResource resource = ComSatPayload minQuantity = 124.9 + maxQuantity = 249.0 title = Have a ComSatPayload of at least 125 units on the craft disableOnStateChange = false } PARAMETER + { + name = ReachOrbit + type = Orbit + title = Reach an intermediate orbit with a single satellite. + minPeriod = 1h + maxPeriod = 6h + completeInSequence = true + disableOnStateChange = true + } + PARAMETER { name = ReachOrbit type = Orbit @@ -116,16 +126,25 @@ CONTRACT_TYPE minPeA = 500000 minPeriod = 11h 56m 2s maxPeriod = 12h 00m 2s - disableOnStateChange = true + disableOnStateChange = false + + PARAMETER + { + name = Duration + type = Duration + duration = 2m + preWaitText = Check for stable orbit + waitingText = Checking for stable orbit + completionText = Stable orbit: Confirmed + } } } PARAMETER { name = MolniyaCom2 type = VesselParameterGroup - define = MolniyaCom2 + define = Molniya Network Sat II dissassociateVesselsOnContractCompletion = true - title = Molniya Network Sat II PARAMETER { @@ -165,10 +184,21 @@ CONTRACT_TYPE type = HasResource resource = ComSatPayload minQuantity = 124.9 + maxQuantity = 249.0 title = Have a ComSatPayload of at least 125 units on the craft disableOnStateChange = false } PARAMETER + { + name = ReachOrbit + type = Orbit + title = Reach an intermediate orbit with a single satellite. + minPeriod = 1h + maxPeriod = 6h + completeInSequence = true + disableOnStateChange = true + } + PARAMETER { name = ReachOrbit type = Orbit @@ -181,16 +211,25 @@ CONTRACT_TYPE minPeA = 500000 minPeriod = 11h 56m 2s maxPeriod = 12h 00m 2s - disableOnStateChange = true + disableOnStateChange = false + + PARAMETER + { + name = Duration + type = Duration + duration = 2m + preWaitText = Check for stable orbit + waitingText = Checking for stable orbit + completionText = Stable orbit: Confirmed + } } } PARAMETER { name = MolniyaCom3 type = VesselParameterGroup - define = MolniyaCom3 + define = Molniya Network Sat III dissassociateVesselsOnContractCompletion = true - title = Molniya Network Sat III PARAMETER { @@ -230,10 +269,21 @@ CONTRACT_TYPE type = HasResource resource = ComSatPayload minQuantity = 124.9 + maxQuantity = 249.0 title = Have a ComSatPayload of at least 125 units on the craft disableOnStateChange = false } PARAMETER + { + name = ReachOrbit + type = Orbit + title = Reach an intermediate orbit with a single satellite. + minPeriod = 1h + maxPeriod = 6h + completeInSequence = true + disableOnStateChange = true + } + PARAMETER { name = ReachOrbit type = Orbit @@ -246,7 +296,17 @@ CONTRACT_TYPE minPeA = 500000 minPeriod = 11h 56m 2s maxPeriod = 12h 00m 2s - disableOnStateChange = true + disableOnStateChange = false + + PARAMETER + { + name = Duration + type = Duration + duration = 2m + preWaitText = Check for stable orbit + waitingText = Checking for stable orbit + completionText = Stable orbit: Confirmed + } } } @@ -255,9 +315,9 @@ CONTRACT_TYPE name = TransferVessel type = DestroyVessel onState = CONTRACT_SUCCESS - vessel = GEO CommSat I - vessel = GEO CommSat II - vessel = GEO CommSat III + vessel = Molniya Network Sat I + vessel = Molniya Network Sat II + vessel = Molniya Network Sat III } BEHAVIOUR From bf5a812603b17ae08bfb8aefc2ea08e484176ea7 Mon Sep 17 00:00:00 2001 From: Ballatik <67292986+Ballatik@users.noreply.github.com> Date: Sat, 21 Oct 2023 11:17:51 -0400 Subject: [PATCH 08/27] Switch to ComApp2 Disable GEOCommNetwork Program, add ComApp2 program Change references from GEOCommNetwork to CommercialApplications2 Move contracts from EarthSatellites to Com App 2 Add Tundra and Molniya targeted and repeat contracts --- .../EarlyMolniyaSat.cfg | 14 +- .../FirstGEOSat.cfg | 6 +- .../FirstGeosync.cfg | 8 +- .../FirstTargetedGeo.cfg | 6 +- .../FirstTargetedMolniya.cfg | 139 ++++++++++++++++++ .../FirstTargetedTundra.cfg | 139 ++++++++++++++++++ .../FirstTundraSat.cfg | 111 ++++++++++++++ .../GEORepeatComSats.cfg | 24 +-- .../GeoComSatNetwork3.cfg | 6 +- .../GeoComSatNetwork4.cfg | 6 +- .../MolniyaNetwork3.cfg | 6 +- .../MolniyaRepeatComSats.cfg} | 70 +++------ .../TundraRepeatComSats.cfg} | 75 ++-------- GameData/RP-1/Programs/Programs.cfg | 48 +++++- 14 files changed, 492 insertions(+), 166 deletions(-) rename GameData/RP-1/Contracts/{Earth Satellites => Commercial Applications 2}/FirstGEOSat.cfg (80%) rename GameData/RP-1/Contracts/{Earth Satellites => Commercial Applications 2}/FirstGeosync.cfg (80%) rename GameData/RP-1/Contracts/{Earth Satellites => Commercial Applications 2}/FirstTargetedGeo.cfg (88%) create mode 100644 GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg create mode 100644 GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg create mode 100644 GameData/RP-1/Contracts/Commercial Applications 2/FirstTundraSat.cfg rename GameData/RP-1/Contracts/{Earth Satellites => Commercial Applications 2}/GEORepeatComSats.cfg (80%) rename GameData/RP-1/Contracts/{Earth Satellites => Commercial Applications 2}/GeoComSatNetwork3.cfg (90%) rename GameData/RP-1/Contracts/{Earth Satellites => Commercial Applications 2}/GeoComSatNetwork4.cfg (92%) rename GameData/RP-1/Contracts/{Earth Satellites => Commercial Applications 2}/MolniyaNetwork3.cfg (89%) rename GameData/RP-1/Contracts/{Z Disabled Contracts/MolniyaRepeatComSats.cfg.disabled => Commercial Applications 2/MolniyaRepeatComSats.cfg} (64%) rename GameData/RP-1/Contracts/{Z Disabled Contracts/TundraRepeatComSats.cfg.disabled => Commercial Applications 2/TundraRepeatComSats.cfg} (62%) diff --git a/GameData/RP-1/Contracts/Commercial Applications 1/EarlyMolniyaSat.cfg b/GameData/RP-1/Contracts/Commercial Applications 1/EarlyMolniyaSat.cfg index f185adc42e7..b53a8a30a44 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 1/EarlyMolniyaSat.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 1/EarlyMolniyaSat.cfg @@ -38,23 +38,11 @@ CONTRACT_TYPE REQUIREMENT { - name = CommApp or GEOComm active - type = Any - - REQUIREMENT - { - name = ProgramActive - type = ProgramActive - program = GEOCommNetwork - } - REQUIREMENT - { name = ProgramActive type = ProgramActive program = CommercialApplications1 - } } - + REQUIREMENT { name = CompleteContract diff --git a/GameData/RP-1/Contracts/Earth Satellites/FirstGEOSat.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstGEOSat.cfg similarity index 80% rename from GameData/RP-1/Contracts/Earth Satellites/FirstGEOSat.cfg rename to GameData/RP-1/Contracts/Commercial Applications 2/FirstGEOSat.cfg index f39754d84e2..4ed0535acc1 100644 --- a/GameData/RP-1/Contracts/Earth Satellites/FirstGEOSat.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstGEOSat.cfg @@ -2,10 +2,10 @@ CONTRACT_TYPE { name = FirstGEOSat title = First Geostationary Satellite - group = GEOCommNetwork + group = CommApp2 agent = Federation Aeronautique Internationale - description = Program: Geostationary Communication Network
Type: Required


Having a communication satellite that remains stationary relative to a ground station means that the antenna wouldn't need to track movements to stay connected. This would greatly simplify communication relay and mass transmission systems.
Historical example: Syncom 3 (39 kg, Thor-Delta) launched in August of 1964.

+ description = Program: Advanced Commercial Applications
Type: Required


Having a communication satellite that remains stationary relative to a ground station means that the antenna wouldn't need to track movements to stay connected. This would greatly simplify communication relay and mass transmission systems.
Historical example: Syncom 3 (39 kg, Thor-Delta) launched in August of 1964.

synopsis = Launch a satellite into a Geostationary Orbit completedMessage = Congratulations! The satellite is in orbit over a constant area. @@ -39,7 +39,7 @@ CONTRACT_TYPE { name = ProgramActive type = ProgramActive - program = GEOCommNetwork + program = CommercialApplications2 } REQUIREMENT { diff --git a/GameData/RP-1/Contracts/Earth Satellites/FirstGeosync.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstGeosync.cfg similarity index 80% rename from GameData/RP-1/Contracts/Earth Satellites/FirstGeosync.cfg rename to GameData/RP-1/Contracts/Commercial Applications 2/FirstGeosync.cfg index 44e0593b7ad..a25c2ed3786 100644 --- a/GameData/RP-1/Contracts/Earth Satellites/FirstGeosync.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstGeosync.cfg @@ -2,10 +2,10 @@ CONTRACT_TYPE { name = FirstGeosync title = First Geosynchronous - group = GEOCommNetwork + group = CommApp2 agent = Federation Aeronautique Internationale - description = Program: Geostationary Communications Network
Type: Optional


With an orbital period of an earth day, a satellite will remain above a constant longitude, appearing to drift north and south through the day. This will allow for constant connection to a ground station.
Historical example: Syncom 2 (39kg, Thor-Delta) launched in July of 1963.

+ description = Program: Advanced Commercial Applications
Type: Optional


With an orbital period of an earth day, a satellite will remain above a constant longitude, appearing to drift north and south through the day. This will allow for constant connection to a ground station.
Historical example: Syncom 2 (39kg, Thor-Delta) launched in July of 1963.

synopsis = Launch a geosynchronous satellite @@ -40,7 +40,7 @@ CONTRACT_TYPE { name = ProgramActive type = ProgramActive - program = GEOCommNetwork + program = CommercialApplications2 } REQUIREMENT { @@ -61,7 +61,7 @@ CONTRACT_TYPE { name = FirstGeosync type = VesselParameterGroup - title = Targeted Geostationary + title = First Geosynchronous Satellite define = FirstGeosync dissassociateVesselsOnContractCompletion = true diff --git a/GameData/RP-1/Contracts/Earth Satellites/FirstTargetedGeo.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedGeo.cfg similarity index 88% rename from GameData/RP-1/Contracts/Earth Satellites/FirstTargetedGeo.cfg rename to GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedGeo.cfg index e0b032b2b08..a946ff6031c 100644 --- a/GameData/RP-1/Contracts/Earth Satellites/FirstTargetedGeo.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedGeo.cfg @@ -2,10 +2,10 @@ CONTRACT_TYPE { name = FirstTargetedGeo title = First Targeted Geostationary - group = GEOCommNetwork + group = CommApp2 agent = Federation Aeronautique Internationale - description = Program: Geostationary Communications Network
Type: Required


Now that we have shown the benefits of Geostationary orbits, launch a satellite to cover a specific ground area.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.

+ description = Program: Advanced Commercial Applications
Type: Required


Now that we have shown the benefits of Geostationary orbits, launch a satellite to cover a specific ground area.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.

synopsis = Launch a geostationary satellite over the targeted point @@ -40,7 +40,7 @@ CONTRACT_TYPE { name = ProgramActive type = ProgramActive - program = GEOCommNetwork + program = CommercialApplications2 } REQUIREMENT { diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg new file mode 100644 index 00000000000..3bb6114c1b9 --- /dev/null +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg @@ -0,0 +1,139 @@ +CONTRACT_TYPE +{ + name = FirstTargetedMolniya + title = First Molniya Orbit Satellite + group = CommApp2 + agent = Federation Aeronautique Internationale + + description = Program: Advanced Commercial Applications
Type: Required

A Molniya orbit is a type of highly elliptical orbit with an inclination of 63.4 degrees, an argument of perigee of -90 degrees, and an orbital period of one half of a sidereal day. This keeps the satellite mostly to the northern hemisphere of the Earth. Place a satellite into a Specific Molniya orbit for the customer.

Historical example: Molniya 1-1 (1,600kg, Molniya)

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer. + + synopsis = Launch a satellite into a Molniya orbit + + completedMessage = Success! The satellite is in orbit to loiter over the desired area. + + sortKey = 501 + + cancellable = true + declinable = false + autoAccept = false + minExpiry = 0 + maxExpiry = 0 + maxCompletions = 1 + maxSimultaneous = 1 + deadline = 0 + + targetBody = HomeWorld() + + + // ************ REWARDS ************ + prestige = Trivial // 1.0x + advanceFunds = 0 + rewardScience = 0 + rewardFunds = 0 + failureFunds = 0 + rewardReputation = 60 + failureReputation = 0 // was @rewardReputation + + + + // ************ REQUIREMENTS ************ + + REQUIREMENT + { + name = ProgramActive + type = ProgramActive + program = CommercialApplications2 + } + + BEHAVIOUR + { + name = MolniyaOrbit + type = OrbitGenerator + + RANDOM_ORBIT + { + type = KOLNIYA + } + } + + PARAMETER + { + name = VesselGroup + type = VesselParameterGroup + define = FirstMolniyaSat + title = Molniya Satellite + + + PARAMETER + { + name = NewVessel + type = NewVessel + title = Launch a new vessel + hideChildren = true + } + PARAMETER + { + name = Crewmembers + type = HasCrew + minCrew = 0 + maxCrew = 0 + title = Uncrewed + hideChildren = true + } + PARAMETER + { + name = HasComSatPayload + type = HasResource + resource = ComSatPayload + minQuantity = 149.9 + title = Have a ComSatPayload of at least 150 units on the craft + hideChildren = true + } + PARAMETER + { + name = ReachSpecificOrbit + type = ReachSpecificOrbit + title = Reach the specified orbit. + displayNotes = true + index = 0 + deviationWindow = 3.0 + + PARAMETER + { + name = Duration + type = Duration + + duration = 2m + + preWaitText = Check for stable orbit + waitingText = Checking for stable orbit + completionText = Stable orbit: Confirmed + } + } + + } + BEHAVIOUR + { + name = TransferVessel + type = DestroyVessel + onState = CONTRACT_SUCCESS + vessel = FirstMolniyaSat + } + + BEHAVIOUR + { + name = VesselDestroyed + type = DialogBox + DIALOG_BOX + { + title = Vessel Ownership Transferred + condition = CONTRACT_SUCCESS + position = CENTER + width = 0.5 + TEXT + { + text = The contract has been completed successfully and the satellite has been transferred to the customer. + } + } + } +} diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg new file mode 100644 index 00000000000..6c218f8f891 --- /dev/null +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg @@ -0,0 +1,139 @@ +CONTRACT_TYPE +{ + name = FirstTargetedTundra + title = Targeted Tundra Orbit Satellite + group = CommApp2 + agent = Federation Aeronautique Internationale + + description = Program: Advanced Commercial Applications
Type: Required

A Tundra orbit is a highly elliptical geosynchronous orbit (note: not geostationary orbit) with a high inclination (usually near 63.4) and an orbital period of one sidereal day. A satellite placed in this orbit spends most of its time over a chosen area of the Earth, a phenomenon known as apogee dwell. Place the customer's satellite in a tundra orbit over the desired area.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer. + + synopsis = Launch a satellite into a Molniya orbit + + completedMessage = Success! The satellite is in orbit to loiter over the desired area. + + sortKey = 501 + + cancellable = true + declinable = false + autoAccept = false + minExpiry = 0 + maxExpiry = 0 + maxCompletions = 1 + maxSimultaneous = 1 + deadline = 0 + + targetBody = HomeWorld() + + + // ************ REWARDS ************ + prestige = Trivial // 1.0x + advanceFunds = 0 + rewardScience = 0 + rewardFunds = 0 + failureFunds = 0 + rewardReputation = 60 + failureReputation = 0 // was @rewardReputation + + + + // ************ REQUIREMENTS ************ + + REQUIREMENT + { + name = ProgramActive + type = ProgramActive + program = CommercialApplications2 + } + + BEHAVIOUR + { + name = TundraOrbit + type = OrbitGenerator + + RANDOM_ORBIT + { + type = TUNDRA + } + } + + PARAMETER + { + name = VesselGroup + type = VesselParameterGroup + define = TundraSat + title = Tundra Satellite + + + PARAMETER + { + name = NewVessel + type = NewVessel + title = Launch a new vessel + hideChildren = true + } + PARAMETER + { + name = Crewmembers + type = HasCrew + minCrew = 0 + maxCrew = 0 + title = Uncrewed + hideChildren = true + } + PARAMETER + { + name = HasComSatPayload + type = HasResource + resource = ComSatPayload + minQuantity = 149.9 + title = Have a ComSatPayload of at least 150 units on the craft + hideChildren = true + } + PARAMETER + { + name = ReachSpecificOrbit + type = ReachSpecificOrbit + title = Reach the specified orbit. + displayNotes = true + index = 0 + deviationWindow = 3.0 + + PARAMETER + { + name = Duration + type = Duration + + duration = 2m + + preWaitText = Check for stable orbit + waitingText = Checking for stable orbit + completionText = Stable orbit: Confirmed + } + } + + } + BEHAVIOUR + { + name = TransferVessel + type = DestroyVessel + onState = CONTRACT_SUCCESS + vessel = TundraSat + } + + BEHAVIOUR + { + name = VesselDestroyed + type = DialogBox + DIALOG_BOX + { + title = Vessel Ownership Transferred + condition = CONTRACT_SUCCESS + position = CENTER + width = 0.5 + TEXT + { + text = The contract has been completed successfully and the satellite has been transferred to the customer. + } + } + } +} diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTundraSat.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTundraSat.cfg new file mode 100644 index 00000000000..e6d55282024 --- /dev/null +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTundraSat.cfg @@ -0,0 +1,111 @@ +CONTRACT_TYPE +{ + name = FirstTundraSat + title = First Tundra Orbit Satellite + group = CommApp2 + agent = Federation Aeronautique Internationale + + description = Program: Advanced Commercial Applications
Type: Optional


A Tundra orbit is a highly elliptical geosynchronous orbit (note: not geostationary orbit) with a high inclination (usually near 63.4) and an orbital period of one sidereal day. A satellite placed in this orbit spends most of its time over a chosen area of the Earth, a phenomenon known as apogee dwell. The ground track of a satellite in a tundra orbit is a closed figure eight. An extreme version of this orbit puts the perigee around 1000 km and the apogee around 70,000 km. The orbit in this contract is actually using data from the Sirius satellites, the only known satellites using a Tundra orbit.

+ synopsis = Launch a satellite into a Tundra Orbit + + completedMessage = Success! The Tundra orbit is highly eccentric and lets the satellite spend most of its time over a point in the high latitudes. + + sortKey = 503 + + cancellable = true + declinable = false + autoAccept = false + minExpiry = 0 + maxExpiry = 0 + maxCompletions = 1 + maxSimultaneous = 1 + deadline = 0 + + targetBody = HomeWorld() + + + // ************ REWARDS ************ + prestige = Trivial // 1.0x + advanceFunds = 0 + rewardScience = 0 + rewardFunds = 0 + failureFunds = 0 + rewardReputation = 60 + failureReputation = 0 // was @rewardReputation + + // ************ REQUIREMENTS ************ + + REQUIREMENT + { + name = ProgramActive + type = ProgramActive + program = CommercialApplications2 + } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = FirstTargetedTundra + invertRequirement = true + } + + PARAMETER + { + name = VesselGroup + type = VesselParameterGroup + title = Tundra satellite + define = TundraSatellite + + PARAMETER + { + name = NewVessel + type = NewVessel + title = Launch a new vessel + hideChildren = true + } + PARAMETER + { + name = Crewmembers + type = HasCrew + minCrew = 0 + maxCrew = 0 + title = Uncrewed + hideChildren = true + } + PARAMETER + { + name = HasComSatPayload + type = HasResource + resource = ComSatPayload + minQuantity = 149.9 + title = Have a ComSatPayload of at least 150 units on the craft + hideChildren = true + } + PARAMETER + { + name = ReachOrbit + type = Orbit + title = Reach the correct orbit within the parameters. Note: The argument of periapsis values mean that the apogee needs to be high in the northern latitudes. This is like a Molniya orbit, but with an orbital period the same as an Earth sidereal day. + minInclination = 61.4 + maxInclination = 65.4 + minEccentricity = 0.3 + minArgumentOfPeriapsis = 220 + maxArgumentOfPeriapsis = 320 + minPeA = 1000000 + minPeriod = 23h 54m 4s + maxPeriod = 23h 58m 4s + + PARAMETER + { + name = Duration + type = Duration + + duration = 2m + + preWaitText = Check for stable orbit + waitingText = Checking for stable orbit + completionText = Stable orbit: Confirmed + } + } + } +} diff --git a/GameData/RP-1/Contracts/Earth Satellites/GEORepeatComSats.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/GEORepeatComSats.cfg similarity index 80% rename from GameData/RP-1/Contracts/Earth Satellites/GEORepeatComSats.cfg rename to GameData/RP-1/Contracts/Commercial Applications 2/GEORepeatComSats.cfg index edddb756ebb..18f51b8bd7a 100644 --- a/GameData/RP-1/Contracts/Earth Satellites/GEORepeatComSats.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/GEORepeatComSats.cfg @@ -2,12 +2,12 @@ CONTRACT_TYPE { name = GEORepeatComSats title = Geostationary Commercial Communications Satellite - group = GEOCommNetwork + group = CommApp2 agent = Federation Aeronautique Internationale tag = exclude_RepeatableComSat - description = Program: Geostationary Communications Network
Type: Optional


We have a customer requesting a new Communications Satellite over a specified area. Design a satellite within their specs and launch into an orbit with the proper orbital parameters as outlined in the contract.&br;&br;This contract can be completed as many times as you would like.&br;&br;NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.&br;&br;The reward of this contract will slowly increase over time but will be reset to 0 after each completion.&br;Current reward is at @rewardFactorPercent % of its nominal value. Elapsed/Expected Days: @elapsedDays / @RP0:expectedDays_GEORepeatComSats
Number of Contracts Completed: @index / unlimited
+ description = Program: Advanced Commercial Applications
Type: Optional


We have a customer requesting a new Communications Satellite over a specified area. Design a satellite within their specs and launch into an orbit with the proper orbital parameters as outlined in the contract.&br;&br;This contract can be completed as many times as you would like.&br;&br;NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.&br;&br;The reward of this contract will slowly increase over time but will be reset to 0 after each completion.&br;Current reward is at @rewardFactorPercent % of its nominal value. Elapsed/Expected Days: @elapsedDays / @RP0:expectedDays_GEORepeatComSats
Number of Contracts Completed: @index / unlimited
genericDescription = Put a satellite with the appropriate amount of communications satellite payload into geostationary orbit. synopsis = Launch a new Commercial Communications Satellite @@ -41,7 +41,7 @@ CONTRACT_TYPE { name = ProgramActive type = ProgramActive - program = GEOCommNetwork + program = CommercialApplications2 } REQUIREMENT @@ -51,22 +51,6 @@ CONTRACT_TYPE contractType = FirstTargetedGeo } - REQUIREMENT - { - name = AcceptContract - type = AcceptContract - tag = exclude_SoundingRocket - invertRequirement = true - } - - REQUIREMENT - { - name = AcceptContract - type = AcceptContract - tag = exclude_SoundingDownrange - invertRequirement = true - } - REQUIREMENT { name = AcceptContract @@ -205,7 +189,7 @@ CONTRACT_TYPE name = OptVesselGroup type = VesselParameterGroup title = Obtain a more precise orbit - rewardReputation = Round(20 * @rewardFactor, 1) + rewardReputation = 20 optional = true completeInSequence = true diff --git a/GameData/RP-1/Contracts/Earth Satellites/GeoComSatNetwork3.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg similarity index 90% rename from GameData/RP-1/Contracts/Earth Satellites/GeoComSatNetwork3.cfg rename to GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg index c2a7bcc3621..96c229c8ca6 100644 --- a/GameData/RP-1/Contracts/Earth Satellites/GeoComSatNetwork3.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg @@ -2,10 +2,10 @@ CONTRACT_TYPE { name = GeoComSatNetwork3 title = Geostationary Communications Network (3 Satellites) - group = GEOCommNetwork + group = CommApp2 agent = Federation Aeronautique Internationale - description = Program: Geostationary Communications Network
Type: Required


A geostationary satellite can provide continuous coverage for a large section of Earth, but to transmit everywhere requires more than one. Launch 3 satellites into geostationary orbits spaced 120 degrees apart.
Historical example: Syncom 4 (1-5) (1.3t, Shuttle Discovery) lanched starting in August of 1984.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer. + description = Program: Advanced Commercial Applications
Type: Required


A geostationary satellite can provide continuous coverage for a large section of Earth, but to transmit everywhere requires more than one. Launch 3 satellites into geostationary orbits spaced 120 degrees apart.
Historical example: Syncom 4 (1-5) (1.3t, Shuttle Discovery) lanched starting in August of 1984.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer. synopsis = Launch a 3 Satellite Geostationary Communications Network @@ -38,7 +38,7 @@ CONTRACT_TYPE { name = ProgramActive type = ProgramActive - program = GEOCommNetwork + program = CommercialApplications2 } REQUIREMENT { diff --git a/GameData/RP-1/Contracts/Earth Satellites/GeoComSatNetwork4.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg similarity index 92% rename from GameData/RP-1/Contracts/Earth Satellites/GeoComSatNetwork4.cfg rename to GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg index 1ee2c345950..0f35c62ab6e 100644 --- a/GameData/RP-1/Contracts/Earth Satellites/GeoComSatNetwork4.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg @@ -2,10 +2,10 @@ CONTRACT_TYPE { name = GeoComSatNetwork4 title = Geostationary Communications Network (4 Satellites) - group = GEOCommNetwork + group = CommApp2 agent = Federation Aeronautique Internationale - description = Program: Geostationary Communications Network
Type: Required


A geostationary satellite can provide continuous coverage for a large section of Earth, but to transmit to every longitude requires more than one. Launch 4 satellites into geostationary orbits spaced 90 degrees apart.
Historical example: Syncom 4 (1-5) (1.3t, Shuttle Discovery) lanched starting in August of 1984.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer. + description = Program: Advanced Commercial Applications
Type: Required


A geostationary satellite can provide continuous coverage for a large section of Earth, but to transmit to every longitude requires more than one. Launch 4 satellites into geostationary orbits spaced 90 degrees apart.
Historical example: Syncom 4 (1-5) (1.3t, Shuttle Discovery) lanched starting in August of 1984.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer. synopsis = Launch a 3 Satellite Geostationary Communications Network @@ -38,7 +38,7 @@ CONTRACT_TYPE { name = ProgramActive type = ProgramActive - program = GEOCommNetwork + program = CommercialApplications2 } REQUIREMENT { diff --git a/GameData/RP-1/Contracts/Earth Satellites/MolniyaNetwork3.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg similarity index 89% rename from GameData/RP-1/Contracts/Earth Satellites/MolniyaNetwork3.cfg rename to GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg index 5ba9e0269b2..85ceb9cf5d7 100644 --- a/GameData/RP-1/Contracts/Earth Satellites/MolniyaNetwork3.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg @@ -2,10 +2,10 @@ CONTRACT_TYPE { name = MolniyaNetwork3 title = Molniya Communications Network (3 Satellites) - group = GEOCommNetwork + group = CommApp2 agent = Federation Aeronautique Internationale - description = Program: Geostationary Communications Network
Type: Required


Geostationary satellites do not provide good coverage in the higher latitudes. Molniya orbits loiter over those latitudes for longer periods, to provide constant coverage with fewer satellites.
Historical example: Molniya 1-1 (1.6t, Molniya 8K78) launched starting in April of 1965.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.

NOTE: If you are completing this with a single launch, you must separate the 3 vessels before entering the specified orbit. + description = Program: Advanced Commercial Applications
Type: Required


Geostationary satellites do not provide good coverage in the higher latitudes. Molniya orbits loiter over those latitudes for longer periods, to provide constant coverage with fewer satellites.
Historical example: Molniya 1-1 (1.6t, Molniya 8K78) launched starting in April of 1965.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.

NOTE: If you are completing this with a single launch, you must separate the 3 vessels before entering the specified orbit. synopsis = Launch a 3 Satellite Molniya Communications Network @@ -38,7 +38,7 @@ CONTRACT_TYPE { name = ProgramActive type = ProgramActive - program = GEOCommNetwork + program = CommercialApplications2 } REQUIREMENT { diff --git a/GameData/RP-1/Contracts/Z Disabled Contracts/MolniyaRepeatComSats.cfg.disabled b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaRepeatComSats.cfg similarity index 64% rename from GameData/RP-1/Contracts/Z Disabled Contracts/MolniyaRepeatComSats.cfg.disabled rename to GameData/RP-1/Contracts/Commercial Applications 2/MolniyaRepeatComSats.cfg index 5cb508e513f..db93b191efc 100644 --- a/GameData/RP-1/Contracts/Z Disabled Contracts/MolniyaRepeatComSats.cfg.disabled +++ b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaRepeatComSats.cfg @@ -2,10 +2,10 @@ CONTRACT_TYPE { name = MolniyaRepeatComSats title = Molniya Commercial Communications Satellite - group = AdvSatellites - agent = Satellites + group = CommApp2 + agent = Federation Aeronautique Internationale - description = We have a customer requesting a new Communications Satellite. Design a satellite within their specs and launch into an orbit with the proper orbital parameters as outlined in the contract.&br;&br;This contract can be completed as many times as you would like.&br;&br;NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.&br;&br;The reward of this contract will slowly increase over time but will be reset to 0 after each completion.&br;Nominal reward: @rawTotalReward &br;Current reward is at @rewardFactorPercent % of its nominal value. Elapsed/Expected Days: @elapsedDays / @expectedDays
Number of Contracts Completed: @index / unlimited
+ description = Program: Advanced Commercial Applications
Type: Optional


We have a customer requesting a new Communications Satellite over a specified area in the high latitudes. Design a satellite within their specs and launch into an orbit with the proper orbital parameters as outlined in the contract.&br;&br;This contract can be completed as many times as you would like.&br;&br;NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.&br;&br;The reward of this contract will slowly increase over time but will be reset to 0 after each completion.&br;Current reward is at @rewardFactorPercent % of its nominal value. Elapsed/Expected Days: @elapsedDays / @RP0:expectedDays_GEORepeatComSats
Number of Contracts Completed: @index / unlimited
genericDescription = Put a satellite into the requested orbit. synopsis = Launch a new Commercial Communications Satellite @@ -21,82 +21,46 @@ CONTRACT_TYPE maxExpiry = 1 maxCompletions = 0 maxSimultaneous = 1 - deadline = 365 * RP1DeadlineMult() // 1 year - + deadline = 0 targetBody = HomeWorld() + // ************ REWARDS ************ prestige = Trivial // 1.0x - advanceFunds = @rawAdvance * @rewardFactor - rewardFunds = @rawReward * @rewardFactor + advanceFunds = 0 rewardScience = 0 - rewardReputation = Round(1 + (@advanceFunds / 500)) - failureReputation = @rewardReputation * 1.5 - failureFunds = @advanceFunds * 0.5 + rewardFunds = 0 + failureFunds = 0 + rewardReputation = Round(60 * Pow((@AdvComSat/HasComSatPayload/minQuantity / 350), 0.5) * @rewardFactor, 1) + failureReputation = 0 // was @rewardReputation // ************ REQUIREMENTS ************ REQUIREMENT { - name = CompleteContract - type = CompleteContract - contractType = FirstMolniyaSat + name = ProgramActive + type = ProgramActive + program = CommercialApplications2 } + REQUIREMENT { name = CompleteContract type = CompleteContract - contractType = EarlyComSat - minCount = 2 - title = Complete 'Commercial Communications Satellite (Early)' contract at least @minCount times + contractType = FirstTargetedMolniya } REQUIREMENT { name = AcceptContract type = AcceptContract - contractType = TundraRepeatComSats - invertRequirement = true - } - REQUIREMENT - { - name = AcceptContract - type = AcceptContract - contractType = GEORepeatComSats - invertRequirement = true - } - REQUIREMENT - { - name = AcceptContract - type = AcceptContract - contractType = EarlyComSat - invertRequirement = true - } - REQUIREMENT - { - name = AcceptContract - type = AcceptContract - contractType = ComTestSat - invertRequirement = true - } - REQUIREMENT - { - name = AcceptContract - type = AcceptContract - contractType = GEOWeather - invertRequirement = true - } - REQUIREMENT - { - name = AcceptContract - type = AcceptContract - contractType = SecondGenWeather + tag = exclude_RepeatableComSat invertRequirement = true } REQUIREMENT { name = AcceptContract type = AcceptContract - contractType = SunSyncWeather + contractType = MolniyaNetwork3 invertRequirement = true } diff --git a/GameData/RP-1/Contracts/Z Disabled Contracts/TundraRepeatComSats.cfg.disabled b/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg similarity index 62% rename from GameData/RP-1/Contracts/Z Disabled Contracts/TundraRepeatComSats.cfg.disabled rename to GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg index 993a70582f8..5615195b4ba 100644 --- a/GameData/RP-1/Contracts/Z Disabled Contracts/TundraRepeatComSats.cfg.disabled +++ b/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg @@ -2,10 +2,10 @@ CONTRACT_TYPE { name = TundraRepeatComSats title = Tundra Commercial Communications Satellite - group = AdvSatellites - agent = Satellites + group = CommApp2 + agent = Federation Aeronautique Internationale - description = We have a customer requesting a new Communications Satellite. Design a satellite within their specs and launch into an orbit with the proper orbital parameters as outlined in the contract.&br;&br;This contract can be completed as many times as you would like.&br;&br;NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.&br;&br;The reward of this contract will slowly increase over time but will be reset to 0 after each completion.&br;Nominal reward: @rawTotalReward &br;Current reward is at @rewardFactorPercent % of its nominal value. Elapsed/Expected Days: @elapsedDays / @expectedDays
Number of Contracts Completed: @index / unlimited
+ description = Program: Advanced Commercial Applications
Type: Optional


We have a customer requesting a new Communications Satellite over a specified area in the high latitudes. Design a satellite within their specs and launch into an orbit with the proper orbital parameters as outlined in the contract.&br;&br;This contract can be completed as many times as you would like.&br;&br;NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.&br;&br;The reward of this contract will slowly increase over time but will be reset to 0 after each completion.&br;Current reward is at @rewardFactorPercent % of its nominal value. Elapsed/Expected Days: @elapsedDays / @RP0:expectedDays_GEORepeatComSats
Number of Contracts Completed: @index / unlimited
genericDescription = Put a satellite into the requested orbit. synopsis = Launch a new Commercial Communications Satellite @@ -21,82 +21,39 @@ CONTRACT_TYPE maxExpiry = 1 maxCompletions = 0 maxSimultaneous = 1 - deadline = 365 * RP1DeadlineMult() // 1 year - + deadline = 0 targetBody = HomeWorld() + // ************ REWARDS ************ prestige = Trivial // 1.0x - advanceFunds = @rawAdvance * @rewardFactor - rewardFunds = @rawReward * @rewardFactor + advanceFunds = 0 rewardScience = 0 - rewardReputation = Round(1 + (@advanceFunds / 500)) - failureReputation = @rewardReputation * 1.5 - failureFunds = @advanceFunds * 0.5 + rewardFunds = 0 + failureFunds = 0 + rewardReputation = Round(60 * Pow((@AdvComSat/HasComSatPayload/minQuantity / 350), 0.5) * @rewardFactor, 1) + failureReputation = 0 // was @rewardReputation // ************ REQUIREMENTS ************ REQUIREMENT { - name = CompleteContract - type = CompleteContract - contractType = FirstTundraSat + name = ProgramActive + type = ProgramActive + program = CommercialApplications2 } + REQUIREMENT { name = CompleteContract type = CompleteContract - contractType = EarlyComSat - minCount = 2 - title = Complete 'Commercial Communications Satellite (Early)' contract at least @minCount times + contractType = FirstTargetedTundra } REQUIREMENT { name = AcceptContract type = AcceptContract - contractType = MolniyaRepeatComSats - invertRequirement = true - } - REQUIREMENT - { - name = AcceptContract - type = AcceptContract - contractType = GEORepeatComSats - invertRequirement = true - } - REQUIREMENT - { - name = AcceptContract - type = AcceptContract - contractType = EarlyComSat - invertRequirement = true - } - REQUIREMENT - { - name = AcceptContract - type = AcceptContract - contractType = ComTestSat - invertRequirement = true - } - REQUIREMENT - { - name = AcceptContract - type = AcceptContract - contractType = GEOWeather - invertRequirement = true - } - REQUIREMENT - { - name = AcceptContract - type = AcceptContract - contractType = SecondGenWeather - invertRequirement = true - } - REQUIREMENT - { - name = AcceptContract - type = AcceptContract - contractType = SunSyncWeather + tag = exclude_RepeatableComSat invertRequirement = true } diff --git a/GameData/RP-1/Programs/Programs.cfg b/GameData/RP-1/Programs/Programs.cfg index 8fc93489f52..d8802d915b0 100644 --- a/GameData/RP-1/Programs/Programs.cfg +++ b/GameData/RP-1/Programs/Programs.cfg @@ -431,11 +431,51 @@ RP0_PROGRAM RP0_PROGRAM { name = GEOCommNetwork + isDisabled = True title = Geostationary Communication Network - description = Geosynchronous, Geostationary, and Molniya orbits have the potential to improve satellite coverage and simplify ground antenna tracking. This program tasks you with creating a 3 or 4 satellite Geostationary or Molniya Network for communication. + description = With geostationary orbits, satellites can be placed at specific spots over the equator where they will stay. This allows communications satellites to be put exactly where they will have the greatest benefit. This program tasks you with creating a 4-satellite Geostationary Network for communication. Each satellite will require 315 units of ComSatPayload. requirementsPrettyText = Complete the Targeted Satellites Program objectivesPrettyText = Complete the Geostationary Communications Network. nominalDurationYears = 2 + baseFunding = 700000 + fundingCurve = MildBackloadedFundingCurve + repDeltaOnCompletePerYearEarly = 420 + repPenaltyPerYearLate = 420 + slots = 2 + + REQUIREMENTS + { + ANY + { + complete_program = TargetedSats + complete_program = CommercialApplications1 + } + } + + OBJECTIVES + { + complete_contract = GeoComSatNetwork + } + + OPTIONALS + { + GEORepeatComSats = true + } + + CONFIDENCECOSTS + { + Normal = 450 + Fast = 900 + } +} +RP0_PROGRAM +{ + name = CommercialApplications2 + title = Advanced Commercial Applications + description = Geosynchronous, Geostationary, Molniya, and Tundra orbits have the potential to improve satellite coverage and simplify ground antenna tracking. This program tasks you with exploring these orbits for commercial customers, and creating a 3 or 4 satellite Geostationary or Molniya Network for communication. + requirementsPrettyText = Complete the Early Commercial Applications Program + objectivesPrettyText = Complete a Geostationary or Molniya Communications Network. + nominalDurationYears = 2 baseFunding = 560000 fundingCurve = MildBackloadedFundingCurve repDeltaOnCompletePerYearEarly = 420 @@ -455,6 +495,8 @@ RP0_PROGRAM { complete_contract = FirstGEOSat complete_contract = FirstTargetedGeo + complete_contract = FirstTargetedMolniya + complete_contract = FirstTargetedTundra ANY { complete_contract = GeoComSatNetwork3 @@ -466,8 +508,10 @@ RP0_PROGRAM OPTIONALS { FirstGeosync = true + FirstTundraSat = true GEORepeatComSats = true - EarlyMolniyaSat = true + MolniyaRepeatComSats = true + TundraRepeatComSats = true } CONFIDENCECOSTS From b41e1a28bc05c0ee13b714f4525178ba67c3b9e4 Mon Sep 17 00:00:00 2001 From: Ballatik <67292986+Ballatik@users.noreply.github.com> Date: Mon, 23 Oct 2023 19:50:19 -0400 Subject: [PATCH 09/27] fix an balance Various sorting and naming fixes fixed antigrind calcs adjust payload and reward scaling for repeatables extend program duration to 4 years --- .../Commercial Applications 2/FirstGEOSat.cfg | 11 ++++---- .../FirstGeosync.cfg | 13 +++++----- .../FirstTargetedGeo.cfg | 2 +- .../FirstTargetedMolniya.cfg | 2 +- .../FirstTargetedTundra.cfg | 12 +++++++-- .../FirstTundraSat.cfg | 12 ++++----- .../GEORepeatComSats.cfg | 9 +------ .../GeoComSatNetwork3.cfg | 2 +- .../GeoComSatNetwork4.cfg | 2 +- .../MolniyaNetwork3.cfg | 2 +- .../MolniyaRepeatComSats.cfg | 25 +++---------------- .../TundraRepeatComSats.cfg | 18 +++---------- GameData/RP-1/Contracts/Groups.cfg | 14 ++++++++--- GameData/RP-1/Programs/Programs.cfg | 2 +- 14 files changed, 55 insertions(+), 71 deletions(-) diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstGEOSat.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstGEOSat.cfg index 4ed0535acc1..221d99efdac 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstGEOSat.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstGEOSat.cfg @@ -75,11 +75,12 @@ CONTRACT_TYPE } PARAMETER { - name = ResourceConsumption - type = ResourceConsumption - resource = ElectricCharge - minRate = -0.1 - title = Have positive electricity production + name = GenerateEC + title = Have positive energy balance + type = ResourceConsumption + resource = ElectricCharge + minRate = -1000000 + maxRate = 0.00001 } PARAMETER { diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstGeosync.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstGeosync.cfg index a25c2ed3786..7ecaefce9cf 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstGeosync.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstGeosync.cfg @@ -1,7 +1,7 @@ CONTRACT_TYPE { name = FirstGeosync - title = First Geosynchronous + title = First Geosynchronous Satellite group = CommApp2 agent = Federation Aeronautique Internationale @@ -83,11 +83,12 @@ CONTRACT_TYPE } PARAMETER { - name = ResourceConsumption - type = ResourceConsumption - resource = ElectricCharge - minRate = -0.1 - title = Have positive electricity production + name = GenerateEC + title = Have positive energy balance + type = ResourceConsumption + resource = ElectricCharge + minRate = -1000000 + maxRate = 0.00001 } PARAMETER { diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedGeo.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedGeo.cfg index a946ff6031c..2581c34423c 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedGeo.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedGeo.cfg @@ -1,7 +1,7 @@ CONTRACT_TYPE { name = FirstTargetedGeo - title = First Targeted Geostationary + title = Targeted Geostationary Satellite group = CommApp2 agent = Federation Aeronautique Internationale diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg index 3bb6114c1b9..73b8b5a80d5 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg @@ -1,7 +1,7 @@ CONTRACT_TYPE { name = FirstTargetedMolniya - title = First Molniya Orbit Satellite + title = First Targeted Molniya Orbit Satellite group = CommApp2 agent = Federation Aeronautique Internationale diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg index 6c218f8f891..c57c00c47ce 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg @@ -45,6 +45,14 @@ CONTRACT_TYPE program = CommercialApplications2 } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = FirstTundraSat + invertRequirement = true + } + BEHAVIOUR { name = TundraOrbit @@ -85,8 +93,8 @@ CONTRACT_TYPE name = HasComSatPayload type = HasResource resource = ComSatPayload - minQuantity = 149.9 - title = Have a ComSatPayload of at least 150 units on the craft + minQuantity = 49.9 + title = Have a ComSatPayload of at least 50 units on the craft hideChildren = true } PARAMETER diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTundraSat.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTundraSat.cfg index e6d55282024..52c5aca1995 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTundraSat.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTundraSat.cfg @@ -74,12 +74,12 @@ CONTRACT_TYPE } PARAMETER { - name = HasComSatPayload - type = HasResource - resource = ComSatPayload - minQuantity = 149.9 - title = Have a ComSatPayload of at least 150 units on the craft - hideChildren = true + name = GenerateEC + title = Have positive energy balance + type = ResourceConsumption + resource = ElectricCharge + minRate = -1000000 + maxRate = 0.00001 } PARAMETER { diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/GEORepeatComSats.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/GEORepeatComSats.cfg index 18f51b8bd7a..27dfde6682c 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/GEORepeatComSats.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/GEORepeatComSats.cfg @@ -51,13 +51,6 @@ CONTRACT_TYPE contractType = FirstTargetedGeo } - REQUIREMENT - { - name = AcceptContract - type = AcceptContract - tag = exclude_RepeatableComSat - invertRequirement = true - } REQUIREMENT { name = AcceptContract @@ -126,7 +119,7 @@ CONTRACT_TYPE DATA { type = float - payload = RP1CommsPayload() + payload = Round(RP1CommsPayload() * (0.25 + ( $GEORepeatComSats_Count / 2)), 25) // baseline of 100, plus 50 each repeat } // ************ PARAMETERS ************ diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg index 96c229c8ca6..c391cb78c28 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg @@ -11,7 +11,7 @@ CONTRACT_TYPE completedMessage = Congratulations! The satellites are in orbit and spaced to provide complete coverage. - sortKey = 903 + sortKey = 905 cancellable = true declinable = false diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg index 0f35c62ab6e..201f331cd2f 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg @@ -11,7 +11,7 @@ CONTRACT_TYPE completedMessage = Congratulations! The satellites are in orbit and spaced to provide complete coverage. - sortKey = 903 + sortKey = 905 cancellable = true declinable = false diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg index 85ceb9cf5d7..90b0e673e7e 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg @@ -11,7 +11,7 @@ CONTRACT_TYPE completedMessage = Congratulations! The satellites are in orbit and spaced to provide complete coverage. - sortKey = 903 + sortKey = 906 cancellable = true declinable = false diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaRepeatComSats.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaRepeatComSats.cfg index db93b191efc..65044a977fa 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaRepeatComSats.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaRepeatComSats.cfg @@ -49,13 +49,6 @@ CONTRACT_TYPE contractType = FirstTargetedMolniya } - REQUIREMENT - { - name = AcceptContract - type = AcceptContract - tag = exclude_RepeatableComSat - invertRequirement = true - } REQUIREMENT { name = AcceptContract @@ -88,7 +81,7 @@ CONTRACT_TYPE CONTRACT_OFFERED { - RepeatSat_Completion = ($RepeatSat_Completion + 0) == 0 ? (UniversalTime() - 60 * 86400) : ($RepeatSat_Completion + 0) + RepeatSat_Completion = ($RepeatSat_Completion + 0) == 0 ? (UniversalTime() - @RP0:expectedDays_GEORepeatComSats * 86400) : ($RepeatSat_Completion + 0) } CONTRACT_COMPLETED_SUCCESS { @@ -100,32 +93,23 @@ CONTRACT_TYPE DATA { type = int - antiGrindCompletion = $RepeatSat_Completion == 0 ? (UniversalTime() - @expectedDays * 86400) : $RepeatSat_Completion + antiGrindCompletion = $RepeatSat_Completion == 0 ? (UniversalTime() - @RP0:expectedDays_GEORepeatComSats * 86400) : $RepeatSat_Completion } DATA { type = float - expectedDays = 60 - elapsedDays = Round((UniversalTime() - @antiGrindCompletion) / 86400.0) - rewardFactor = Log(Max(@elapsedDays / @expectedDays * 20 - 9, 1), 2) / 3.46 + rewardFactor = Log(Max(@elapsedDays / @RP0:expectedDays_GEORepeatComSats * 20 - 9, 1), 2) / 3.46 rewardFactorPercent = Round(@rewardFactor * 100, 1) } DATA { type = float - payload = Round(Max(Random(RP1CommsPayload() / 2, RP1CommsPayload()), 300), 25) + payload = Round(RP1CommsPayload() * 0.75 * (1 + ( $MolniyaRepeatComSats_Count / 6)), 25) // baseline of 300, plus 50 each repeat } - DATA - { - type = float - rawAdvance = (750 + (Pow(@AdvComSat/HasComSatPayload/minQuantity, 0.37) * 75)) * 8 * @RP0:globalHardContractMultiplier - rawReward = @rawAdvance * 2 - rawTotalReward = Round(@rawAdvance + @rawReward) - } // ************ PARAMETERS ************ @@ -134,7 +118,6 @@ CONTRACT_TYPE name = AdvComSat type = VesselParameterGroup define = AdvComSatellite - dissassociateVesselsOnContractCompletion = true title = Commercial Communications Satellite PARAMETER diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg index 5615195b4ba..754128a8363 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg @@ -81,7 +81,7 @@ CONTRACT_TYPE CONTRACT_OFFERED { - RepeatSat_Completion = ($RepeatSat_Completion + 0) == 0 ? (UniversalTime() - 60 * 86400) : ($RepeatSat_Completion + 0) + RepeatSat_Completion = ($RepeatSat_Completion + 0) == 0 ? (UniversalTime() - @RP0:expectedDays_GEORepeatComSats * 86400) : ($RepeatSat_Completion + 0) } CONTRACT_COMPLETED_SUCCESS { @@ -93,32 +93,23 @@ CONTRACT_TYPE DATA { type = int - antiGrindCompletion = $RepeatSat_Completion == 0 ? (UniversalTime() - @expectedDays * 86400) : $RepeatSat_Completion + antiGrindCompletion = $RepeatSat_Completion == 0 ? (UniversalTime() - @RP0:expectedDays_GEORepeatComSats * 86400) : $RepeatSat_Completion } DATA { type = float - expectedDays = 60 - elapsedDays = Round((UniversalTime() - @antiGrindCompletion) / 86400.0) - rewardFactor = Log(Max(@elapsedDays / @expectedDays * 20 - 9, 1), 2) / 3.46 + rewardFactor = Log(Max(@elapsedDays / @RP0:expectedDays_GEORepeatComSats * 20 - 9, 1), 2) / 3.46 rewardFactorPercent = Round(@rewardFactor * 100, 1) } DATA { type = float - payload = Round(Max(Random(RP1CommsPayload() / 2, RP1CommsPayload()), 300), 25) + payload = Round(RP1CommsPayload() * 0.5 * (1 + ( $TundraRepeatComSats_Count / 8)), 25) // baseline of 200, plus 25 each repeat } - DATA - { - type = float - rawAdvance = (750 + (Pow(@AdvComSat/HasComSatPayload/minQuantity, 0.37) * 75)) * 9 * @RP0:globalHardContractMultiplier - rawReward = @rawAdvance * 2 - rawTotalReward = Round(@rawAdvance + @rawReward) - } // ************ PARAMETERS ************ @@ -127,7 +118,6 @@ CONTRACT_TYPE name = AdvComSat type = VesselParameterGroup define = AdvComSatellite - dissassociateVesselsOnContractCompletion = true title = Commercial Communications Satellite PARAMETER diff --git a/GameData/RP-1/Contracts/Groups.cfg b/GameData/RP-1/Contracts/Groups.cfg index ab9c6e90e53..973fcfcd44f 100644 --- a/GameData/RP-1/Contracts/Groups.cfg +++ b/GameData/RP-1/Contracts/Groups.cfg @@ -50,7 +50,7 @@ CONTRACT_GROUP CONTRACT_GROUP { name = EarlySatellites-Heavy - displayName = Early Satellite (Heavy) + displayName = Early Satellite (Heavy) minVersion = 1.12.2 sortKey = 15 agent = Satellites @@ -58,7 +58,7 @@ CONTRACT_GROUP CONTRACT_GROUP { name = TargetedSats - displayName = Targeted Satellite + displayName = Targeted Satellite minVersion = 1.12.2 sortKey = 16 agent = Satellites @@ -79,7 +79,7 @@ CONTRACT_GROUP sortKey = 18 agent = Satellites } - CONTRACT_GROUP + CONTRACT_GROUP { name = CommApp displayName = Commercial Application Satellites @@ -88,6 +88,14 @@ CONTRACT_GROUP agent = Satellites } CONTRACT_GROUP + { + name = CommApp2 + displayName = Advanced Commercial Application Satellites + minVersion = 1.12.2 + sortKey = 20 + agent = Satellites + } + CONTRACT_GROUP { name = GEOCommNetwork displayName = Geostationary Communications Network diff --git a/GameData/RP-1/Programs/Programs.cfg b/GameData/RP-1/Programs/Programs.cfg index d8802d915b0..90947f3a3a7 100644 --- a/GameData/RP-1/Programs/Programs.cfg +++ b/GameData/RP-1/Programs/Programs.cfg @@ -475,7 +475,7 @@ RP0_PROGRAM description = Geosynchronous, Geostationary, Molniya, and Tundra orbits have the potential to improve satellite coverage and simplify ground antenna tracking. This program tasks you with exploring these orbits for commercial customers, and creating a 3 or 4 satellite Geostationary or Molniya Network for communication. requirementsPrettyText = Complete the Early Commercial Applications Program objectivesPrettyText = Complete a Geostationary or Molniya Communications Network. - nominalDurationYears = 2 + nominalDurationYears = 4 baseFunding = 560000 fundingCurve = MildBackloadedFundingCurve repDeltaOnCompletePerYearEarly = 420 From e3745c71362c3b409c5702b9a1197bb61a9584eb Mon Sep 17 00:00:00 2001 From: Ballatik <67292986+Ballatik@users.noreply.github.com> Date: Wed, 25 Oct 2023 17:10:45 -0400 Subject: [PATCH 10/27] Compatability and Balance Adjust funding to bring it more in line based on number/size of launches Make contracts available so that anyone on the deprecated GEOComm Program can complete it. --- .../Commercial Applications 2/FirstGEOSat.cfg | 18 ++++++++++--- .../FirstTargetedGeo.cfg | 18 ++++++++++--- .../GeoComSatNetwork3.cfg | 21 ++++++++++----- .../GeoComSatNetwork4.cfg | 26 ++++++++++++------- GameData/RP-1/Programs/Programs.cfg | 6 +++-- 5 files changed, 66 insertions(+), 23 deletions(-) diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstGEOSat.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstGEOSat.cfg index 221d99efdac..021a97143b0 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstGEOSat.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstGEOSat.cfg @@ -37,9 +37,21 @@ CONTRACT_TYPE REQUIREMENT { - name = ProgramActive - type = ProgramActive - program = CommercialApplications2 + name = CommApp or GEOComm active + type = Any + + REQUIREMENT + { + name = ProgramActive + type = ProgramActive + program = GEOCommNetwork + } + REQUIREMENT + { + name = ProgramActive + type = ProgramActive + program = CommercialApplications2 + } } REQUIREMENT { diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedGeo.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedGeo.cfg index 2581c34423c..74a0c5f6456 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedGeo.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedGeo.cfg @@ -38,9 +38,21 @@ CONTRACT_TYPE REQUIREMENT { - name = ProgramActive - type = ProgramActive - program = CommercialApplications2 + name = CommApp or GEOComm active + type = Any + + REQUIREMENT + { + name = ProgramActive + type = ProgramActive + program = GEOCommNetwork + } + REQUIREMENT + { + name = ProgramActive + type = ProgramActive + program = CommercialApplications2 + } } REQUIREMENT { diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg index c391cb78c28..c6ce5a606a8 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg @@ -36,9 +36,21 @@ CONTRACT_TYPE REQUIREMENT { - name = ProgramActive - type = ProgramActive - program = CommercialApplications2 + name = CommApp or GEOComm active + type = Any + + REQUIREMENT + { + name = ProgramActive + type = ProgramActive + program = GEOCommNetwork + } + REQUIREMENT + { + name = ProgramActive + type = ProgramActive + program = CommercialApplications2 + } } REQUIREMENT { @@ -110,7 +122,6 @@ CONTRACT_TYPE //distance = 42736000 horizontalDistance = 4000 showMessages = true - completeInSequence = true disableOnStateChange = false } @@ -174,7 +185,6 @@ CONTRACT_TYPE //distance = 42736000 horizontalDistance = 4000.0 showMessages = true - completeInSequence = true disableOnStateChange = false } @@ -238,7 +248,6 @@ CONTRACT_TYPE //distance = 42736000 horizontalDistance = 4000.0 showMessages = true - completeInSequence = true disableOnStateChange = false } diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg index 201f331cd2f..1e10e2042c8 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg @@ -36,9 +36,21 @@ CONTRACT_TYPE REQUIREMENT { - name = ProgramActive - type = ProgramActive - program = CommercialApplications2 + name = CommApp or GEOComm active + type = Any + + REQUIREMENT + { + name = ProgramActive + type = ProgramActive + program = GEOCommNetwork + } + REQUIREMENT + { + name = ProgramActive + type = ProgramActive + program = CommercialApplications2 + } } REQUIREMENT { @@ -117,7 +129,6 @@ CONTRACT_TYPE //distance = 42736000 horizontalDistance = 4000 showMessages = true - completeInSequence = true disableOnStateChange = false } @@ -188,7 +199,6 @@ CONTRACT_TYPE //distance = 42736000 horizontalDistance = 4000.0 showMessages = true - completeInSequence = true disableOnStateChange = false } @@ -260,7 +270,6 @@ CONTRACT_TYPE //distance = 42736000 horizontalDistance = 4000.0 showMessages = true - completeInSequence = true disableOnStateChange = false } @@ -327,11 +336,10 @@ CONTRACT_TYPE { name = VisitWaypoint type = VisitWaypoint - index = 2 + index = 3 //distance = 42736000 horizontalDistance = 4000.0 showMessages = true - completeInSequence = true disableOnStateChange = false } @@ -377,7 +385,7 @@ CONTRACT_TYPE } WAYPOINT { - name = Geostationary Ground Target III + name = Geostationary Ground Target IV icon = thermometer altitude = 0 latitude = 0 diff --git a/GameData/RP-1/Programs/Programs.cfg b/GameData/RP-1/Programs/Programs.cfg index 90947f3a3a7..7f845717b14 100644 --- a/GameData/RP-1/Programs/Programs.cfg +++ b/GameData/RP-1/Programs/Programs.cfg @@ -453,8 +453,10 @@ RP0_PROGRAM } OBJECTIVES + ANY { - complete_contract = GeoComSatNetwork + complete_contract = GeoComSatNetwork3 + complete_contract = GeoComSatNetwork4 } OPTIONALS @@ -476,7 +478,7 @@ RP0_PROGRAM requirementsPrettyText = Complete the Early Commercial Applications Program objectivesPrettyText = Complete a Geostationary or Molniya Communications Network. nominalDurationYears = 4 - baseFunding = 560000 + baseFunding = 800000 fundingCurve = MildBackloadedFundingCurve repDeltaOnCompletePerYearEarly = 420 repPenaltyPerYearLate = 420 From c59d3a23379bdcd923a0c83ce562e3af5b407606 Mon Sep 17 00:00:00 2001 From: Ballatik <67292986+Ballatik@users.noreply.github.com> Date: Wed, 25 Oct 2023 20:01:00 -0400 Subject: [PATCH 11/27] formatting, repeatable balance Various formatting and text fixes Adjusted repeatable contracts to increment payload correctly --- .../Commercial Applications 2/FirstGEOSat.cfg | 2 +- .../Commercial Applications 2/FirstGeosync.cfg | 2 +- .../Commercial Applications 2/FirstTargetedGeo.cfg | 2 +- .../Commercial Applications 2/FirstTargetedTundra.cfg | 2 +- .../Commercial Applications 2/FirstTundraSat.cfg | 9 ++++++++- .../Commercial Applications 2/GEORepeatComSats.cfg | 6 ++---- .../Commercial Applications 2/GeoComSatNetwork3.cfg | 2 +- .../Commercial Applications 2/GeoComSatNetwork4.cfg | 2 +- .../MolniyaRepeatComSats.cfg | 2 +- .../Commercial Applications 2/TundraRepeatComSats.cfg | 11 ++--------- GameData/RP-1/Programs/Programs.cfg | 9 +++++---- 11 files changed, 24 insertions(+), 25 deletions(-) diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstGEOSat.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstGEOSat.cfg index 021a97143b0..c20df61077e 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstGEOSat.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstGEOSat.cfg @@ -5,7 +5,7 @@ CONTRACT_TYPE group = CommApp2 agent = Federation Aeronautique Internationale - description = Program: Advanced Commercial Applications
Type: Required


Having a communication satellite that remains stationary relative to a ground station means that the antenna wouldn't need to track movements to stay connected. This would greatly simplify communication relay and mass transmission systems.
Historical example: Syncom 3 (39 kg, Thor-Delta) launched in August of 1964.

+ description = Program: Advanced Commercial Applications
Type: Required


Having a communication satellite that remains stationary relative to a ground station means that the antenna wouldn't need to track movements to stay connected. This would greatly simplify communication relay and mass transmission systems.
Historical example: Syncom 3 (39 kg, Thor-Delta) launched in August of 1964. synopsis = Launch a satellite into a Geostationary Orbit completedMessage = Congratulations! The satellite is in orbit over a constant area. diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstGeosync.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstGeosync.cfg index 7ecaefce9cf..a143b10aafe 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstGeosync.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstGeosync.cfg @@ -5,7 +5,7 @@ CONTRACT_TYPE group = CommApp2 agent = Federation Aeronautique Internationale - description = Program: Advanced Commercial Applications
Type: Optional


With an orbital period of an earth day, a satellite will remain above a constant longitude, appearing to drift north and south through the day. This will allow for constant connection to a ground station.
Historical example: Syncom 2 (39kg, Thor-Delta) launched in July of 1963.

+ description = Program: Advanced Commercial Applications
Type: Optional


With an orbital period of an earth day, a satellite will remain above a constant longitude, appearing to drift north and south through the day. This will allow for constant connection to a ground station.
Historical example: Syncom 2 (39kg, Thor-Delta) launched in July of 1963. synopsis = Launch a geosynchronous satellite diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedGeo.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedGeo.cfg index 74a0c5f6456..f903c020e89 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedGeo.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedGeo.cfg @@ -5,7 +5,7 @@ CONTRACT_TYPE group = CommApp2 agent = Federation Aeronautique Internationale - description = Program: Advanced Commercial Applications
Type: Required


Now that we have shown the benefits of Geostationary orbits, launch a satellite to cover a specific ground area.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.

+ description = Program: Advanced Commercial Applications
Type: Required


Now that we have shown the benefits of Geostationary orbits, launch a satellite to cover a specific ground area.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer. synopsis = Launch a geostationary satellite over the targeted point diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg index c57c00c47ce..757f4c83747 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg @@ -7,7 +7,7 @@ CONTRACT_TYPE description = Program: Advanced Commercial Applications
Type: Required

A Tundra orbit is a highly elliptical geosynchronous orbit (note: not geostationary orbit) with a high inclination (usually near 63.4) and an orbital period of one sidereal day. A satellite placed in this orbit spends most of its time over a chosen area of the Earth, a phenomenon known as apogee dwell. Place the customer's satellite in a tundra orbit over the desired area.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer. - synopsis = Launch a satellite into a Molniya orbit + synopsis = Launch a satellite into the desired Tundra orbit completedMessage = Success! The satellite is in orbit to loiter over the desired area. diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTundraSat.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTundraSat.cfg index 52c5aca1995..c8de2830181 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTundraSat.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTundraSat.cfg @@ -5,7 +5,7 @@ CONTRACT_TYPE group = CommApp2 agent = Federation Aeronautique Internationale - description = Program: Advanced Commercial Applications
Type: Optional


A Tundra orbit is a highly elliptical geosynchronous orbit (note: not geostationary orbit) with a high inclination (usually near 63.4) and an orbital period of one sidereal day. A satellite placed in this orbit spends most of its time over a chosen area of the Earth, a phenomenon known as apogee dwell. The ground track of a satellite in a tundra orbit is a closed figure eight. An extreme version of this orbit puts the perigee around 1000 km and the apogee around 70,000 km. The orbit in this contract is actually using data from the Sirius satellites, the only known satellites using a Tundra orbit.

+ description = Program: Advanced Commercial Applications
Type: Optional


A Tundra orbit is a highly elliptical geosynchronous orbit (note: not geostationary orbit) with a high inclination (usually near 63.4) and an orbital period of one sidereal day. A satellite placed in this orbit spends most of its time over a chosen area of the Earth, a phenomenon known as apogee dwell. The ground track of a satellite in a tundra orbit is a closed figure eight. An extreme version of this orbit puts the perigee around 1000 km and the apogee around 70,000 km. The orbit in this contract is actually using data from the Sirius satellites, the only known satellites using a Tundra orbit. synopsis = Launch a satellite into a Tundra Orbit completedMessage = Success! The Tundra orbit is highly eccentric and lets the satellite spend most of its time over a point in the high latitudes. @@ -48,6 +48,13 @@ CONTRACT_TYPE contractType = FirstTargetedTundra invertRequirement = true } + REQUIREMENT + { + name = CompleteContract + type = CompleteContract + contractType = FirstTargetedTundra + invertRequirement = true + } PARAMETER { diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/GEORepeatComSats.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/GEORepeatComSats.cfg index 27dfde6682c..a73cef33f04 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/GEORepeatComSats.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/GEORepeatComSats.cfg @@ -5,8 +5,6 @@ CONTRACT_TYPE group = CommApp2 agent = Federation Aeronautique Internationale - tag = exclude_RepeatableComSat - description = Program: Advanced Commercial Applications
Type: Optional


We have a customer requesting a new Communications Satellite over a specified area. Design a satellite within their specs and launch into an orbit with the proper orbital parameters as outlined in the contract.&br;&br;This contract can be completed as many times as you would like.&br;&br;NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.&br;&br;The reward of this contract will slowly increase over time but will be reset to 0 after each completion.&br;Current reward is at @rewardFactorPercent % of its nominal value. Elapsed/Expected Days: @elapsedDays / @RP0:expectedDays_GEORepeatComSats
Number of Contracts Completed: @index / unlimited
genericDescription = Put a satellite with the appropriate amount of communications satellite payload into geostationary orbit. @@ -32,7 +30,7 @@ CONTRACT_TYPE rewardScience = 0 rewardFunds = 0 failureFunds = 0 - rewardReputation = Round(60 * Pow((@AdvComSat/HasComSatPayload/minQuantity / 350), 0.5) * @rewardFactor, 1) + rewardReputation = Round(60 * Pow((@AdvComSat/HasComSatPayload/minQuantity / 100), 0.5) * @rewardFactor, 1) failureReputation = 0 // was @rewardReputation // ************ REQUIREMENTS ************ @@ -119,7 +117,7 @@ CONTRACT_TYPE DATA { type = float - payload = Round(RP1CommsPayload() * (0.25 + ( $GEORepeatComSats_Count / 2)), 25) // baseline of 100, plus 50 each repeat + payload = Round(RP1CommsPayload() * (0.25 + ( $GEORepeatComSats_Count / 8)), 25) // baseline of 100, plus 50 each repeat } // ************ PARAMETERS ************ diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg index c6ce5a606a8..d0386e8c51f 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg @@ -5,7 +5,7 @@ CONTRACT_TYPE group = CommApp2 agent = Federation Aeronautique Internationale - description = Program: Advanced Commercial Applications
Type: Required


A geostationary satellite can provide continuous coverage for a large section of Earth, but to transmit everywhere requires more than one. Launch 3 satellites into geostationary orbits spaced 120 degrees apart.
Historical example: Syncom 4 (1-5) (1.3t, Shuttle Discovery) lanched starting in August of 1984.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer. + description = Program: Advanced Commercial Applications
Type: Required


A geostationary satellite can provide continuous coverage for a large section of Earth, but to transmit everywhere requires more than one. Launch 3 satellites into geostationary orbits spaced 120 degrees apart.
Historical example: Syncom 4 (1-5) (1.3t, Shuttle Discovery) launched starting in August of 1984.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer. synopsis = Launch a 3 Satellite Geostationary Communications Network diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg index 1e10e2042c8..3cb216c27c6 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg @@ -5,7 +5,7 @@ CONTRACT_TYPE group = CommApp2 agent = Federation Aeronautique Internationale - description = Program: Advanced Commercial Applications
Type: Required


A geostationary satellite can provide continuous coverage for a large section of Earth, but to transmit to every longitude requires more than one. Launch 4 satellites into geostationary orbits spaced 90 degrees apart.
Historical example: Syncom 4 (1-5) (1.3t, Shuttle Discovery) lanched starting in August of 1984.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer. + description = Program: Advanced Commercial Applications
Type: Required


A geostationary satellite can provide continuous coverage for a large section of Earth, but to transmit to every longitude requires more than one. Launch 4 satellites into geostationary orbits spaced 90 degrees apart.
Historical example: Syncom 4 (1-5) (1.3t, Shuttle Discovery) launched starting in August of 1984.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer. synopsis = Launch a 3 Satellite Geostationary Communications Network diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaRepeatComSats.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaRepeatComSats.cfg index 65044a977fa..706cef26565 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaRepeatComSats.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaRepeatComSats.cfg @@ -107,7 +107,7 @@ CONTRACT_TYPE DATA { type = float - payload = Round(RP1CommsPayload() * 0.75 * (1 + ( $MolniyaRepeatComSats_Count / 6)), 25) // baseline of 300, plus 50 each repeat + payload = Round(RP1CommsPayload() * (0.75 + ( $MolniyaRepeatComSats_Count / 8)), 25) // baseline of 300, plus 50 each repeat } diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg index 754128a8363..4a0c4962e4f 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg @@ -30,7 +30,7 @@ CONTRACT_TYPE rewardScience = 0 rewardFunds = 0 failureFunds = 0 - rewardReputation = Round(60 * Pow((@AdvComSat/HasComSatPayload/minQuantity / 350), 0.5) * @rewardFactor, 1) + rewardReputation = Round(60 * Pow((@AdvComSat/HasComSatPayload/minQuantity / 200), 0.5) * @rewardFactor, 1) failureReputation = 0 // was @rewardReputation // ************ REQUIREMENTS ************ @@ -49,13 +49,6 @@ CONTRACT_TYPE contractType = FirstTargetedTundra } - REQUIREMENT - { - name = AcceptContract - type = AcceptContract - tag = exclude_RepeatableComSat - invertRequirement = true - } BEHAVIOUR { @@ -107,7 +100,7 @@ CONTRACT_TYPE DATA { type = float - payload = Round(RP1CommsPayload() * 0.5 * (1 + ( $TundraRepeatComSats_Count / 8)), 25) // baseline of 200, plus 25 each repeat + payload = Round(RP1CommsPayload() * (0.5 + ( $TundraRepeatComSats_Count / 8)), 25) // baseline of 200, plus 50 each repeat } diff --git a/GameData/RP-1/Programs/Programs.cfg b/GameData/RP-1/Programs/Programs.cfg index 7f845717b14..96cb486f4de 100644 --- a/GameData/RP-1/Programs/Programs.cfg +++ b/GameData/RP-1/Programs/Programs.cfg @@ -453,12 +453,13 @@ RP0_PROGRAM } OBJECTIVES - ANY { - complete_contract = GeoComSatNetwork3 - complete_contract = GeoComSatNetwork4 + ANY + { + complete_contract = GeoComSatNetwork3 + complete_contract = GeoComSatNetwork4 + } } - OPTIONALS { GEORepeatComSats = true From 83a424c727e14c33e4740e019437d0b1d5699029 Mon Sep 17 00:00:00 2001 From: Ballatik <67292986+Ballatik@users.noreply.github.com> Date: Sun, 5 Nov 2023 07:33:50 -0500 Subject: [PATCH 12/27] Revert "Merge remote-tracking branch 'upstream/master'" This reverts commit 0e75ccf5c88a979c68360b3e6b3ad710f675e06a, reversing changes made to c59d3a23379bdcd923a0c83ce562e3af5b407606. --- .../Lunar Crewed/CrewedLunarFlyby.cfg | 4 +- .../Lunar Crewed/CrewedLunarOrbitRepeat.cfg | 184 ------ .../Lunar Crewed/CrewedMoonLandingRover.cfg | 20 - .../CrewedMoonLandingTargeted.cfg | 22 +- .../Lunar Crewed/FirstCrewedLunarOrbit.cfg | 3 +- .../Lunar Crewed/FirstMoonLandingCrewed.cfg | 13 +- .../FirstMoonLandingCrewedDirect.cfg | 13 +- .../X-Plane Research/BreakSoundBarrier.cfg | 2 +- .../CrewedLunarOrbitRepeat.cfg.DISABLED | 157 +++++ ...gleCrewedLunarOrbitRepeatable.cfg.DISABLED | 118 ++++ GameData/RP-1/CrewTrainingTimes.cfg | 12 - GameData/RP-1/Localization/en-us.cfg | 2 +- GameData/RP-1/Plugins/RP0InstallChecker.dll | Bin 10240 -> 9728 bytes GameData/RP-1/Programs/Programs.cfg | 13 +- GameData/RP-1/RP-1.version | 6 +- .../RP-1/Science/Experiments/CrewReport.cfg | 2 +- .../CrewScience/BasicCapsuleExperiments.cfg | 8 +- .../CrewScience/CockpitExperiments.cfg | 8 +- .../CrewScience/MatureCapsuleExperiments.cfg | 10 +- .../CrewScience/SecondGenExperiments.cfg | 18 +- GameData/RP-1/Science/ScienceLabs.cfg | 36 +- GameData/RP-1/Strategies/Milestones.cfg | 2 +- GameData/RP-1/Tree/ECM-Parts.cfg | 20 +- GameData/RP-1/Tree/EntryCostModifiers.cfg | 16 +- GameData/RP-1/Tree/TREE-Parts.cfg | 83 +-- GameData/RP-1/Tree/identicalParts.cfg | 16 +- GameData/RP-1/changelog.cfg | 54 -- README.md | 2 +- Source/GameData.csproj | 3 - Source/InstallChecker/InstallChecker.cs | 23 +- Source/RP0/Avionics/ModuleAvionics.cs | 2 +- .../RP0/Avionics/ModuleProceduralAvionics.cs | 25 +- Source/RP0/Harmony/CustomBarnKit.cs | 1 + Source/RP0/Harmony/KSPWheel.cs | 8 - Source/RP0/Harmony/KerbalismPatcher.cs | 564 +++++++----------- Source/RP0/Maintenance/MaintenanceHandler.cs | 89 ++- Source/RP0/Singletons/Database.cs | 3 +- .../RP0/SpaceCenter/LaunchComplex/LCData.cs | 19 +- .../SpaceCenter/LaunchComplex/LCEfficiency.cs | 4 - .../Projects/FacilityUpgradeProject.cs | 2 +- .../RP0/SpaceCenter/Projects/VesselProject.cs | 2 +- .../RP0/SpaceCenter/SpaceCenterManagement.cs | 2 +- Source/RP0/UI/KCT/GUI_Editor.cs | 4 +- Source/RP0/UI/KCT/GUI_FirstRun.cs | 2 +- Source/RP0/UI/KCT/GUI_NewLC.cs | 62 +- Source/RP0/UI/ProceduralAvionicsWindow.cs | 9 +- Source/RP0/Utilities/Formula.cs | 4 +- Source/RP0/Utilities/KCTUtilities.cs | 67 ++- Source/RP0/Utilities/KSPUtils.cs | 50 +- Source/RP0/Utilities/KerbalismUtils.cs | 40 +- Source/RP0/Utilities/MathUtils.cs | 9 +- .../data/Near_Future_Electrical.json | 110 +--- .../Parts Browser/data/RN_Soviet_Rockets.json | 4 +- .../Parts Browser/data/ROCapsules.json | 94 +-- .../data/Universal_Storage_2.json | 4 +- 55 files changed, 793 insertions(+), 1257 deletions(-) delete mode 100644 GameData/RP-1/Contracts/Lunar Crewed/CrewedLunarOrbitRepeat.cfg create mode 100644 GameData/RP-1/Contracts/Z Disabled Contracts/CrewedLunarOrbitRepeat.cfg.DISABLED create mode 100644 GameData/RP-1/Contracts/Z Disabled Contracts/SingleCrewedLunarOrbitRepeatable.cfg.DISABLED diff --git a/GameData/RP-1/Contracts/Lunar Crewed/CrewedLunarFlyby.cfg b/GameData/RP-1/Contracts/Lunar Crewed/CrewedLunarFlyby.cfg index 6e7f5e0dce0..b488a37405b 100644 --- a/GameData/RP-1/Contracts/Lunar Crewed/CrewedLunarFlyby.cfg +++ b/GameData/RP-1/Contracts/Lunar Crewed/CrewedLunarFlyby.cfg @@ -5,8 +5,6 @@ CONTRACT_TYPE group = CrewedLunar agent = Federation Aeronautique Internationale - tag = CrewedLunarOrbitRequired - description = Program: Crewed Lunar Exploration
Type: Required


Design, build, and launch a crewed spacecraft into lunar space (with a periselene under 5000 km) and return safely to Earth. synopsis = Launch a crewed ship to flyby the Moon @@ -36,6 +34,8 @@ CONTRACT_TYPE rewardReputation = 300 // was 300 failureReputation = 0 // was @rewardReputation // was 300 + + // ************ REQUIREMENTS ************ REQUIREMENT diff --git a/GameData/RP-1/Contracts/Lunar Crewed/CrewedLunarOrbitRepeat.cfg b/GameData/RP-1/Contracts/Lunar Crewed/CrewedLunarOrbitRepeat.cfg deleted file mode 100644 index ea4ed714aae..00000000000 --- a/GameData/RP-1/Contracts/Lunar Crewed/CrewedLunarOrbitRepeat.cfg +++ /dev/null @@ -1,184 +0,0 @@ -CONTRACT_TYPE -{ - name = CrewedLunarOrbitRepeat - title = Crewed Lunar Orbit - group = CrewedLunar - - tag = CrewedLunarOrbitOptional - - description = Program: Crewed Lunar Exploration
Type: Optional


Launch a crewed spacecraft into lunar orbit for a routine mission of the specified duration and return safely to Earth.&br;&br;Number of Contracts Completed: @index / 2 - - synopsis = Fly a Crewed Lunar Orbital mission - - completedMessage = Crew alive and well after the mission--congratulations! - - sortKey = 709 - - cancellable = true - declinable = true - autoAccept = false - minExpiry = 0 - maxExpiry = 0 - maxCompletions = 2 - maxSimultaneous = 1 - deadline = 0 - - targetBody = Moon - - - // ************ REWARDS ************ - prestige = Trivial // 1.0x - advanceFunds = 0 - rewardScience = 0 - rewardFunds = 0 - failureFunds = 0 - rewardReputation = 500 - failureReputation = 0 - - // ************ REQUIREMENTS ************ - - REQUIREMENT - { - name = ProgramActive - type = ProgramActive - program = CrewedLunar - } - - REQUIREMENT - { - name = CompleteContract - type = CompleteContract - contractType = FirstCrewedLunarOrbit - title = Complete 'First Crewed Lunar Orbit' contract - } - - REQUIREMENT - { - name = AcceptContract - type = AcceptContract - tag = CrewedLunarOrbitOptional - invertRequirement = true - title = Don't have another active optional Crewed Lunar Exploration contract. - } - - REQUIREMENT - { - name = AcceptContract - type = AcceptContract - tag = CrewedLunarOrbitRequired - invertRequirement = true - title = Don't have active required Crewed Lunar Exploration contract. - } - - // ************ DATA BLOCKS ************ - - DATA - { - type = List - durations = [ 36h, 72h ] - } - - DATA - { - type = Duration - Duration = @durations.ElementAt(@index) - title = Duration of Mission - } - - DATA - { - type = int - startPeA = 30000 - title = First Periselene - } - - DATA - { - type = int - startApA = 75000 + Round(Random(0, 225000), 25000) - title = First Aposelene - } - - DATA - { - type = int - index = $HSFOrbitalMoonGenRepeatable_Count + 0 - } - - BEHAVIOUR - { - name = IncrementTheCount - type = Expression - - CONTRACT_COMPLETED_SUCCESS - { - HSFOrbitalMoonGenRepeatable_Count = $HSFOrbitalMoonGenRepeatable_Count + 1 - } - } - - // ************ PARAMETERS ************ - - PARAMETER - { - name = VesselGroup - type = VesselParameterGroup - title = Crewed Orbit of @targetBody - - PARAMETER - { - name = NewVessel - type = NewVessel - title = Launch a New Vessel - hideChildren = true - } - - PARAMETER - { - name = HasCrew - type = HasCrew - minCrew = 1 - crewOnly = true - title = Have at least 1 crewmember on board - hideChildren = true - } - - PARAMETER - { - name = OrbitWrapper - title = Stay in specified orbit for the duration - type = All - disableOnStateChange = true - completeInSequence = true - - PARAMETER - { - name = MoonOrbit - type = Orbit - situation = ORBITING - minPeA = @/startPeA - maxApA = @/startApA - targetBody = Moon - title = Reach Orbit of the Moon within the provided parameters - } - - PARAMETER - { - name = Duration - type = Duration - duration = @/Duration - preWaitText = Reach specified orbit - waitingText = Orbiting... - completionText = Orbits are complete, you may return to Earth when ready - } - } - - PARAMETER - { - name = ReturnHome - type = RP1ReturnHome - title = Return Home Safely - hideChildren = true - completeInSequence = true - } - } -} diff --git a/GameData/RP-1/Contracts/Lunar Crewed/CrewedMoonLandingRover.cfg b/GameData/RP-1/Contracts/Lunar Crewed/CrewedMoonLandingRover.cfg index ecbf0003c87..b416e4bbf7f 100644 --- a/GameData/RP-1/Contracts/Lunar Crewed/CrewedMoonLandingRover.cfg +++ b/GameData/RP-1/Contracts/Lunar Crewed/CrewedMoonLandingRover.cfg @@ -4,8 +4,6 @@ CONTRACT_TYPE title = Crewed Moon Landing & Rover Exploration group = CrewedLunar - tag = CrewedLunarOrbitOptional - description = Program: Crewed Lunar Exploration
Type: Optional


Design and launch a spacecraft with at least one crew member to land on the Moon. This will be a targeted landing near a randomly generated waypoint. We will also require you to take a crewed rover to explore an additional two waypoints. Once you have explored the waypoints, return safely to Earth.&br;&br;Number of Contracts Completed: @index / @maxCompletions genericDescription = Land crew on the Moon and explore with a rover. @@ -54,24 +52,6 @@ CONTRACT_TYPE contractType = RepeatMoonLandingCrew } - REQUIREMENT - { - name = AcceptContract - type = AcceptContract - tag = CrewedLunarOrbitOptional - invertRequirement = true - title = Don't have an active optional Crewed Lunar Exploration contract. - } - - REQUIREMENT - { - name = AcceptContract - type = AcceptContract - tag = CrewedLunarOrbitRequired - invertRequirement = true - title = Don't have active required Crewed Lunar Exploration contract. - } - DATA { type = double diff --git a/GameData/RP-1/Contracts/Lunar Crewed/CrewedMoonLandingTargeted.cfg b/GameData/RP-1/Contracts/Lunar Crewed/CrewedMoonLandingTargeted.cfg index ea55911c21e..cfd6f7d1391 100644 --- a/GameData/RP-1/Contracts/Lunar Crewed/CrewedMoonLandingTargeted.cfg +++ b/GameData/RP-1/Contracts/Lunar Crewed/CrewedMoonLandingTargeted.cfg @@ -4,10 +4,8 @@ CONTRACT_TYPE title = Crewed Targeted Moon Landing group = CrewedLunar - tag = CrewedLunarOrbitRequired - description = Program: Crewed Lunar Exploration
Type: CAPSTONE


Design and launch a spacecraft with at least one crew member to land at a specific location on the Moon. Explore the area for at least @/LandDur and then return safely to Earth.&br;&br;Number of Contracts Completed: @index / @maxCompletions - + genericDescription = Launch a crewed single-person spacecraft and land it on a specific lunar biome. Explore the area for the specified amount of time and then return safely to Earth. synopsis = Land a crew on a specific biome on the Moon and return safely to Earth @@ -33,8 +31,8 @@ CONTRACT_TYPE rewardScience = 0 rewardFunds = 0 failureFunds = 0 - rewardReputation = 1000+(250 * @/index) - failureReputation = 0 + rewardReputation = 1000+(250 * @/index) // was 200.0 * (2.75+(double(@/LandDur)/172800)) + failureReputation = 0 // was @rewardReputation // was 200.0 * (2.75+(double(@/LandDur)/172800)) @@ -53,21 +51,12 @@ CONTRACT_TYPE type = CompleteContract contractType = first_MoonLandingCrewed } - - REQUIREMENT - { - name = AcceptContract - type = AcceptContract - tag = CrewedLunarOrbitOptional - invertRequirement = true - title = Don't have an active optional Crewed Lunar Exploration contract. - } DATA { type = Duration LandDur = @specifiedTime.ElementAt(@index) - title = Duration + title= Duration } DATA @@ -116,8 +105,7 @@ CONTRACT_TYPE type = int index = $RepeatMoonLandingCrew_Count + 0 } - - DATA + DATA { type = List specifiedTime = [ 48h, 72h ] diff --git a/GameData/RP-1/Contracts/Lunar Crewed/FirstCrewedLunarOrbit.cfg b/GameData/RP-1/Contracts/Lunar Crewed/FirstCrewedLunarOrbit.cfg index e4f8a4d0879..e8de2368d3e 100644 --- a/GameData/RP-1/Contracts/Lunar Crewed/FirstCrewedLunarOrbit.cfg +++ b/GameData/RP-1/Contracts/Lunar Crewed/FirstCrewedLunarOrbit.cfg @@ -4,7 +4,6 @@ CONTRACT_TYPE title = First Crewed Lunar Orbit group = CrewedLunar - tag = CrewedLunarOrbitRequired description = Program: Crewed Lunar Exploration
Type: Required


Design and launch a spacecraft with at least one crew member to orbit close to the Moon for at least 20 hours and return safely to Earth. Historically, Apollo 8 was the first to do this, flying to the Moon over Christmas, 1968. @@ -62,7 +61,7 @@ CONTRACT_TYPE PARAMETER { - name = HasCrew + name = TwoCrew type = HasCrew minCrew = 1 crewOnly = true diff --git a/GameData/RP-1/Contracts/Lunar Crewed/FirstMoonLandingCrewed.cfg b/GameData/RP-1/Contracts/Lunar Crewed/FirstMoonLandingCrewed.cfg index 3bd0f10c17a..8ebaaffcfb1 100644 --- a/GameData/RP-1/Contracts/Lunar Crewed/FirstMoonLandingCrewed.cfg +++ b/GameData/RP-1/Contracts/Lunar Crewed/FirstMoonLandingCrewed.cfg @@ -5,9 +5,7 @@ CONTRACT_TYPE group = CrewedLunar agent = Federation Aeronautique Internationale - tag = CrewedLunarOrbitRequired - - description = Program: Crewed Lunar Exploration
Type: Required


We are ready to finally put Humans on the surface of the Moon! Good luck to you in your design and execution of this complex mission!&br;&br;You must put at least one Human on the Moon and return them safely to the Earth.&br;&br;NOTE: The contract asks you to plant a flag on the Moon. Be sure that you have updated your Astronaut Complex to level five to unlock that ability. + description = Program: Crewed Lunar Exploration
Type: Required


We are ready to finally put Humans on the surface of the Moon! Good luck to you in your design and execution of this complex mission!&br;&br;You must put at least one Human on the Moon and return them safely to the Earth.&br;&br;NOTE: The contract asks you to plant a flag on the Moon. Be sure that you have updated your Astronaut Complex to level three to unlock that ability. synopsis = Land a crew on the Moon and Return them safely to Earth @@ -76,15 +74,6 @@ CONTRACT_TYPE contractType = first_MoonLandingCrewedDirect invertRequirement = true } - - REQUIREMENT - { - name = AcceptContract - type = AcceptContract - tag = CrewedLunarOrbitOptional - invertRequirement = true - title = Don't have an active optional Crewed Lunar Exploration contract. - } PARAMETER { diff --git a/GameData/RP-1/Contracts/Lunar Crewed/FirstMoonLandingCrewedDirect.cfg b/GameData/RP-1/Contracts/Lunar Crewed/FirstMoonLandingCrewedDirect.cfg index dc3b2c8f04d..49cf72e9504 100644 --- a/GameData/RP-1/Contracts/Lunar Crewed/FirstMoonLandingCrewedDirect.cfg +++ b/GameData/RP-1/Contracts/Lunar Crewed/FirstMoonLandingCrewedDirect.cfg @@ -5,9 +5,7 @@ CONTRACT_TYPE group = CrewedLunar agent = Federation Aeronautique Internationale - tag = CrewedLunarOrbitRequired - - description = Program: Crewed Lunar Exploration
Type: Required


We are ready to finally put Humans on the surface of the Moon! Good luck to you in your design and execution of this complex mission!&br;&br;You must put at least one Human on the Moon and return them safely to the Earth. You may not perform any dockings or this contract will fail. &br;&br;NOTE: The contract asks you to plant a flag on the Moon. Be sure that you have updated your Astronaut Complex to level five to unlock that ability. + description = Program: Crewed Lunar Exploration
Type: Required


We are ready to finally put Humans on the surface of the Moon! Good luck to you in your design and execution of this complex mission!&br;&br;You must put at least one Human on the Moon and return them safely to the Earth. You may not perform any dockings or this contract will fail. &br;&br;NOTE: The contract asks you to plant a flag on the Moon. Be sure that you have updated your Astronaut Complex to level three to unlock that ability. synopsis = Land a crew on the Moon and Return them safely to Earth @@ -69,15 +67,6 @@ CONTRACT_TYPE contractType = first_MoonLandingCrewed invertRequirement = true } - - REQUIREMENT - { - name = AcceptContract - type = AcceptContract - tag = CrewedLunarOrbitOptional - invertRequirement = true - title = Don't have an active optional Crewed Lunar Exploration contract. - } PARAMETER { diff --git a/GameData/RP-1/Contracts/X-Plane Research/BreakSoundBarrier.cfg b/GameData/RP-1/Contracts/X-Plane Research/BreakSoundBarrier.cfg index 2d7415bb2cf..df652f3d1b4 100644 --- a/GameData/RP-1/Contracts/X-Plane Research/BreakSoundBarrier.cfg +++ b/GameData/RP-1/Contracts/X-Plane Research/BreakSoundBarrier.cfg @@ -45,7 +45,7 @@ CONTRACT_TYPE PARAMETER { - name = BSBVesselGroup + name = VesselGroup type = VesselParameterGroup title = Break the sound barrier define = SoundBarrier diff --git a/GameData/RP-1/Contracts/Z Disabled Contracts/CrewedLunarOrbitRepeat.cfg.DISABLED b/GameData/RP-1/Contracts/Z Disabled Contracts/CrewedLunarOrbitRepeat.cfg.DISABLED new file mode 100644 index 00000000000..356b3924458 --- /dev/null +++ b/GameData/RP-1/Contracts/Z Disabled Contracts/CrewedLunarOrbitRepeat.cfg.DISABLED @@ -0,0 +1,157 @@ +CONTRACT_TYPE +{ + name = CrewedLunarOrbitRepeat + title = Crewed Lunar Orbit with @/crewNum + genericTitle = Crewed Lunar Orbital + group = MoonExploration + + + description = Launch a spacecraft with at least @/crewNum aboard into lunar orbit for a routine mission of the specified duration and return safely to Earth.&br;&br;Number of Contracts Completed: @index / unlimited + genericDescription = Launch a spacecraft with at least the required number of crew aboard into lunar orbit for a routine mission of the specified duration and return safely to Earth. + + synopsis = Fly a Crewed Lunar Orbital mission with @/crewNum crew + + completedMessage = Crew alive and well after the mission--congratulations! + + sortKey = 709 + + cancellable = true + declinable = true + autoAccept = false + minExpiry = 0 + maxExpiry = 0 + maxCompletions = 0 + maxSimultaneous = 1 + deadline = 365 * RP1DeadlineMult() // 1 year + + targetBody = Moon + + + // ************ REWARDS ************ + prestige = Significant // 1.25x + advanceFunds = 0.625 * (50000 + @/crewNum * 20000) * @RP0:globalHardContractMultiplier + rewardScience = 0 + rewardReputation = 100 + @/crewNum * 30 + rewardFunds = @advanceFunds + failureReputation = @rewardReputation * 1.5 + failureFunds = @advanceFunds * 0.5 + + // ************ REQUIREMENTS ************ + + REQUIREMENT + { + name = CompleteContract + type = CompleteContract + contractType = SingleCrewedLunarOrbitRepeatable + minCount = 2 + title = Complete 'Single Crewed Lunar Orbit' contract at least @minCount times + } + + // ************ DATA BLOCKS ************ + + DATA + { + type = int + crewNum = 1 + Round(Random(1, 2), 1) + title = Number of crew for mission + } + DATA + { + type = Duration + //Duration = Round (Random(1d, 3d), 1h) + Duration = Random(1d, 3d) + //Duration = Round ( @randDuration, 1h ) + title = Duration of Mission + } + DATA + { + type = int + startPeA = 30000 + Round(Random(0, 55000), 10000) + title = First Periselene + } + DATA + { + type = int + startApA = 100000 + Round(Random(0, 200000), 25000) + title = First Aposelene + } + DATA + { + type = double + Inclination = Round(Random(0, 180), 5) + title = Inclination to use for orbits + } + + DATA + { + type = int + index = $HSFOrbitalMoonGenRepeatable_Count + 0 + } + + BEHAVIOUR + { + name = IncrementTheCount + type = Expression + + CONTRACT_COMPLETED_SUCCESS + { + HSFOrbitalMoonGenRepeatable_Count = $HSFOrbitalMoonGenRepeatable_Count + 1 + } + } + + // ************ PARAMETERS ************ + + PARAMETER + { + name = VesselGroup + type = VesselParameterGroup + title = Crewed Orbit of @targetBody + + PARAMETER + { + name = NewVessel + type = NewVessel + title = Launch a New Vessel + hideChildren = true + } + PARAMETER + { + name = TwoCrew + type = HasCrew + minCrew = @/crewNum + maxCrew = 99 + } + PARAMETER + { + name = MoonOrbit + type = Orbit + situation = ORBITING + minPeA = @/startPeA + maxApA = @/startApA + minInclination = Min(Max(0, @/Inclination - 10), 180) + maxInclination = Min(Max(0, @/Inclination + 10), 180) + targetBody = Moon + disableOnStateChange = true + title = Reach Orbit of the Moon within the provided parameters + PARAMETER + { + name = Duration + type = Duration + + duration = @/Duration + + preWaitText = Reach Specified Orbit + waitingText = Orbiting... + completionText = Orbits are complete, you may return to Earth when ready + } + } + PARAMETER + { + name = ReturnHome + type = RP1ReturnHome + title = Return Home Safely + hideChildren = true + completeInSequence = true + } + } +} diff --git a/GameData/RP-1/Contracts/Z Disabled Contracts/SingleCrewedLunarOrbitRepeatable.cfg.DISABLED b/GameData/RP-1/Contracts/Z Disabled Contracts/SingleCrewedLunarOrbitRepeatable.cfg.DISABLED new file mode 100644 index 00000000000..088a05bb72b --- /dev/null +++ b/GameData/RP-1/Contracts/Z Disabled Contracts/SingleCrewedLunarOrbitRepeatable.cfg.DISABLED @@ -0,0 +1,118 @@ +CONTRACT_TYPE +{ + name = SingleCrewedLunarOrbitRepeatable + title = Single Crewed Lunar Orbit + group = MoonExploration + + + description = Launch a spacecraft with at least one crew aboard into lunar orbit for a routine mission of the specified duration and return safely to Earth. Completing once will unlock the Lunar Space Station contract.&br;&br;Number of Contracts Completed: @index / @maxCompletions + genericDescription = Fly a Crewed Lunar Orbital mission with at least one crew + + synopsis = Fly a Crewed Lunar Orbital mission with at least one crew + + completedMessage = Crew alive and well after the mission--congratulations! + + sortKey = 709 + + cancellable = true + declinable = true + autoAccept = false + minExpiry = 0 + maxExpiry = 0 + maxCompletions = 2 + maxSimultaneous = 1 + deadline = 365 * RP1DeadlineMult() // 1 year + + targetBody = Moon + + + // ************ REWARDS ************ + prestige = Significant // 1.25x + advanceFunds = 0.625 * 50000 * @RP0:globalHardContractMultiplier + rewardScience = 0 + rewardReputation = 100 + rewardFunds = @advanceFunds + failureReputation = 200 + failureFunds = @advanceFunds * 0.5 + + // ************ REQUIREMENTS ************ + + REQUIREMENT + { + name = CompleteContract + type = CompleteContract + contractType = FirstCrewedLunarOrbit + } + + DATA + { + type = int + index = $SingleCrewedLunarOrbitRepeatable_Count + 0 + } + + BEHAVIOUR + { + name = IncrementTheCount + type = Expression + + CONTRACT_COMPLETED_SUCCESS + { + SingleCrewedLunarOrbitRepeatable_Count = $SingleCrewedLunarOrbitRepeatable_Count + 1 + } + } + + // ************ PARAMETERS ************ + + PARAMETER + { + name = VesselGroup + type = VesselParameterGroup + title = Crew Orbit of @targetBody + + PARAMETER + { + name = NewVessel + type = NewVessel + title = Launch a New Vessel + hideChildren = true + } + PARAMETER + { + name = TwoCrew + type = HasCrew + minCrew = 1 + maxCrew = 99 + title = Have at least 1 crewmember on board + hideChildren = true + } + PARAMETER + { + name = MoonOrbit + type = Orbit + maxPeA = 200000 // relatively circular + maxApA = 500000 // relatively circular + targetBody = Moon + disableOnStateChange = true + title = Reach Orbit of the Moon with a maximum Periselene of 200 km and a maximum Aposelene of 500 km and hold it for at least 20 hours + PARAMETER + { + name = Duration + type = Duration + + duration = 20h + + preWaitText = Reach Specified Orbit + waitingText = Orbiting... + completionText = Orbits are complete, you may return to Earth when ready + } + } + PARAMETER + { + name = ReturnHome + type = RP1ReturnHome + title = Return Home Safely + hideChildren = true + completeInSequence = true + } + } +} diff --git a/GameData/RP-1/CrewTrainingTimes.cfg b/GameData/RP-1/CrewTrainingTimes.cfg index 2be534c5b0f..5644825213d 100644 --- a/GameData/RP-1/CrewTrainingTimes.cfg +++ b/GameData/RP-1/CrewTrainingTimes.cfg @@ -232,16 +232,4 @@ TRAININGTIMES MK2VApod = TKS alnair-crew-s1p5_1 = TKS TKS-Mission = 150 - - // Crew carriers - CarrierX15 = 2 - CarrierEarly = 8, CarrierX15 - CarrierAdv = 5, CarrierEarly - CarrierSTS = 5, CarrierAdv - - KerbCan = CarrierX15 - RO-Mk1CrewModule = CarrierEarly - MK1CrewCabin = CarrierEarly - mk2CrewCabin = CarrierAdv - mk3CrewCabin = CarrierSTS } diff --git a/GameData/RP-1/Localization/en-us.cfg b/GameData/RP-1/Localization/en-us.cfg index fff30f29eb3..a4fd9a38768 100644 --- a/GameData/RP-1/Localization/en-us.cfg +++ b/GameData/RP-1/Localization/en-us.cfg @@ -284,7 +284,7 @@ #rp0_loading_tip_029 = Gaining more science from each experiment on Normal or Easy difficulty... #rp0_loading_tip_030 = Being challenged with less funding on Hard difficulty... #rp0_loading_tip_031 = Experimenting with different starting Programs on different playthroughs... - #rp0_loading_tip_032 = Upgrading the Astronaut Complex three times to allow EVAs, and four times for lunar exploration... + #rp0_loading_tip_032 = Upgrading the Astronaut Complex once to allow EVAs, and twice for lunar exploration... #rp0_loading_tip_033 = Upgrading the Tracking Station to increase the power of Earth's DSN... #rp0_loading_tip_034 = Adjusting the construction speed of KSC improvements... #rp0_loading_tip_035 = Hiring scientists... diff --git a/GameData/RP-1/Plugins/RP0InstallChecker.dll b/GameData/RP-1/Plugins/RP0InstallChecker.dll index 53beb9480914417adea9abbb7f240016aeca9544..ea945891e9a3c03f732d7b15336980a60531b302 100644 GIT binary patch delta 2548 zcmZWrYjBiT8Gg?BF1vhLHrd@|FG;g(NJBRpU;?EbBM_vN(rBq=AUG)FW*Z{J!e;q4 zV7I_-N+<;sZTc~7T5YSyID=ZX?l9ER*1-$Lr0X&5i_JS+L^ZF?c7{f)UABTM&V>v%-yQjxO+&i33pnrt?p0MTK3H@6uh=e z<*DtmUg!!55i4ZX_L=y9q0@6}b)MF1+X~Rgfs?tj#+Umfoo!<`C~qzK44-k$x478A8=Fww zlS$6gyKpi2^>Tal?B1`em@vH8t$Dt*-eI>Fu+u9~ zF=b~NXks7k;OyKu?vCcS7nv0II_z@R?Ht^Qms=P^Tj#pLfm^x$iTb_XZu^E7o);_) zz9aaon8VraJ#DvDcs7pD7`y-u8y}TtOdDr4mc^vmhzqQ4;~U}y!^R@1FsSiKji1#x zsqr}-^RRe?844ON)8b$?_iW>3@mJ~K5njVOyh{vXk2z2gHU@<%8L;*+stQ)pV0V}@hl79Zv04le})dxYrI7HZALCe0|H_(B4{DDVOfPsCsq=Bu!(ph z4icB+2yu;;KZX;OH){D)8i(-`!6dfJVSFCD<)p^1Yy7FkG!Ebe zyogoU26I9^NNw<|tVV{vaQu01T*RfRj!5Nie7g6KZcR1#;3lWV$zI~_vz+&+;1&JD z+3c;O#lp^9Y0b`DvDlmK#fpvNId{DO?yQpg`?zG6%rq+P1H1~Y18ehpc8$2XyLXNZ zsTfUNI*Ur}1JvwN+_on_JhT*>M~278Tot3KH_oC`tC^S0GS{`R-tbK`TsM243v7#Q z9~sZ)bGt?`m>(T4t<7&A%~zvyuL>{PxZL|>V{i3~jYGmzC-(l^wANXjFJbMj!gvYQ z&7svo^m&0qulLLF7phC5_X%q;#KGshzLvMV?9vhf`^V@x|fA7_m-l_I#9*}l00w+9iG*k+e6jg>N9*{vJg`k-dTJZZIWq3TAheqWbaFkA*jsx~m$Tf5rMA+_}+L delta 3096 zcmZWq3v5)!6+JWWv+HMj*wrPr*v?{HoNQqiCsT8TDB~l_0B}za-v?xVAGrNGd z9eK~(&zXDg%-ngN+CKHriEl+V#D8!W`SB?h#foJc5Igz8X=_6VQ0s}hwcfahI{WHK zim9J>S~QDA-XF#1?BHTxWwjTO9ZjYL1Q1G_fbGb`l+6~uj7%t@$&N0li=@MVGa5V%kkL$LF)$hHS)r(Z<-BhNyc{&z0^+daiQeQ}$}N zNzJ)z{=#g5yV;Z{ZZKQ%WKkh$-rXH3kKWO;#lDt>zEmZUby8I|EVdxw<3nK_^%CAw5^R<7zJPPdbI^gLl&_PwqgMx)Wr(uREw7bGwQ$ z=8y9<9QR?0abB}i<_r0}t44YDQCgfuyz~b(q!-ZnKdReDPX0I}?$cCwn)aE7O7{gV zS4nk>XOtXg`#6UCbIS3B6r*v*a-x&<#5g<2X>58xMs>r;cmwrpQ=N=AQfRtlq?T}Y z-{#s>oKj1@ky^^xNHu9}ChGo@ho#zR3-zYRo%LP0_3|(;$*f5&Q{LOL@A%lcw|%YY zVxC-fO10%3BF~|$%>WAl!-UdoQQNVN2^CX!h<(du-{o3RH(%tIX!?A<^nbDReCFGx z#u8;}RmIGS%`!r1c9iXy3~qXlSqps2$uUxG-U%zd4lJsE5*X(EHzjvx+@aCIG(%tu z%U;V@RNvE$V^M(jkNV9$TQ_k2HuV?1>(-JA9w}Hn*b#30%=-mkG!<5rDd)c9qMNn!v^I_SQ_2TWEnAVs65?TOlIwYgCuA?5;c0nP<5`Wr*BED!*Kh-!7=SsYE^zLc=ELUS z-64t#3BUt%b`@}P>@AvT=tn5|z$BYbayLo-MzEYSyqBDcHSLKutnC@=OJ@2z_9v9m zaepGwo@k$I)oMp?BC%m8JvN*iUq75or`x?xoJh7kaZe$W>i;px*>q^Mci%nO)!&;* zxr(E+tSDSdHD_O0Xs4R9uPU^!Le-qwSI>3c>rEB+t=Zh4=}M0DqcffEAK5=Vu9d<5 zOkz}769YqTI#bsRG{imwZQcP8m((vJ*zS4umIQe%nj{ps}1 zuX;-YZKet{^GINyDBYyO>~J^q4rZh>?QpU5MT*Vl!8x6~c>^4T#shZYuG62*rQxdOhcHGhi46K_8%GL<;3_YrK6Yk|&v}%%9^2S= zT{9z<|B;Pl+sJmYpX-L{Pm|3Nd~^A85AWW){X4zCy>fHwfw=cXO*~ub^M^~qJ@W&4 z*fB%+{eHs^5BVy>{W9Dmt(X+Gm7$=JvLbv?)Ir(nAWcVvdu*iyq~VA_m<;8dONk*o zZW1OGBz=%FoD3(~yMe&`06*Y?fOn&&HhWy!feJX`sgt3pBm7gP$ney088Bk}ti*&C z{Jxl!fzZ?`(y8L=pn}8I7fW=7R9`$AQ b3;xSeqmKXOW=_>UCSI<4P0R#h*R1~nlb(tab)With the expert skills of <<1>>, <<2>> has traveled faster than sound. This experimental aircraft pushed through the immense turbulence of the transsonic region to surpass this impressive milestone. With the rate of progress at this new space program, new milestones are sure to follow.\n(tab)Historical Information: On October 14th, 1947, US Air Force pilot Chuck Yeager broke the sound barrier in a Bell X-1 that he nicknamed Glamorous Glennis. The rocket-powered aircraft was dropped from the bomb bay of a B-29 and acheived a speed of Mach 1.06 (361 m/s). The Soviets accomplished the feat in 1948 with a Lavochkin La-176 and the British in 1948 with a de Havilland DH.108. image = RP-1/Strategies/MilestoneImages/BreakSoundBarrier diff --git a/GameData/RP-1/Tree/ECM-Parts.cfg b/GameData/RP-1/Tree/ECM-Parts.cfg index e14ff1b399f..5041c81a31c 100644 --- a/GameData/RP-1/Tree/ECM-Parts.cfg +++ b/GameData/RP-1/Tree/ECM-Parts.cfg @@ -463,12 +463,8 @@ RO-reactor-BES5 = 100000,PowerReactors RO-reactor-TOPAZI = 200000,PowerReactors RO-reactor-kilopower = 10000,RO-reactor-snap10a - RO-reactor-prometheus = 1000000,RO-reactor-snap50-300 RO-reactor-snap10a = 15000,PowerReactors - RO-reactor-snap2 = 10000,RO-reactor-snap10a,TurbineReactors RO-reactor-snap50 = 300000,TurbineReactors - RO-reactor-snap50-300 = 200000,RO-reactor-snap50 - RO-reactor-snap8 = 105000,RO-reactor-snap10a ROAJ10-137 = AJ10-137 ROAdvCapsule = capsulesGemini ROAerobeeSustainer = WAC-Corporal @@ -476,17 +472,13 @@ ROAerojet25KS18000 = 2-5KS18000 ROBabySergeant = T17-E2 ROC-APAS8995A = APAS8995Dock - ROC-APAS8995Av2 = APAS8995Dock - ROC-APAS8995P = APAS8995Dock - ROC-APAS8995Pv2 = APAS8995Dock + ROC-APAS8995P = ROC-APAS8995A ROC-AgenaFairing = ROC-AgenaPort ROC-AgenaPort = 9000,dockingProbeDrogue - ROC-ApolloAPAS75BDB = rn_apas75 + ROC-ApolloAPAS75BDB = 5000,dockingAndro ROC-ApolloASTPAdapterBDB = 5000,dockingAndro ROC-ApolloASTPUVXBDB = ROC-ApolloASTPAdapterBDB ROC-ApolloASTPVHFBDB = ROC-ApolloASTPAdapterBDB - ROC-ApolloCADSActive = APAS8995Dock - ROC-ApolloCADSPassive = APAS8995Dock ROC-ApolloCM = capsulesApollo ROC-ApolloCMBDB = capsulesApollo ROC-ApolloCMBDBBlockIII = capsulesApolloBIII @@ -1573,9 +1565,9 @@ radiator-universal-1 = 1 radiator-universal-2 = 1 radiator-universal-3 = 1 - reactor-0625 = 500000,RO-reactor-snap50-300 + reactor-0625 = 500000, RO-reactor-snap50 reactor-125 = 75000, RO-reactor-TOPAZI - reactor-25 = 400000,RO-reactor-snap8 + reactor-25 = 400000, RO-reactor-snap50 restock-decoupler-radial-tiny-1 = 1 restock-engine-125-pug = Aestus restock-engine-125-valiant = Viking-2 @@ -1606,7 +1598,7 @@ rn-almaz-dp = s1-dp rn-almaz-ops4 = 50000,almaz3-5 rn-almaz-rcs = almaz3-5,rcsMult - rn-apas75 = 5000,dockingAndro + rn-apas75 = dockingAndro rn-astp-bo = 5000,t-bo rn-brizm-me = S5-98M rn-centaurt-rl10-l = RL10A-4 @@ -1676,7 +1668,7 @@ roverWheel2 = wheelsEarly roverWheel3 = wheelsLate rtg = 50000,RTGlevel4 - rtg-0625 = 35156,RTGlevel6 + rtg-0625 = 100000,RTGlevel6 rtgMini = 50000,RTGlevel1 s1-dp = 17000,dockingProbeDrogue,dockingCrew s1-lsolar = 7k-ok-lsolar diff --git a/GameData/RP-1/Tree/EntryCostModifiers.cfg b/GameData/RP-1/Tree/EntryCostModifiers.cfg index 013fadf821d..fc5ec7112cd 100644 --- a/GameData/RP-1/Tree/EntryCostModifiers.cfg +++ b/GameData/RP-1/Tree/EntryCostModifiers.cfg @@ -636,14 +636,6 @@ ENTRYCOSTMODS // NUCLEAR // * RTG's will progress in tiers in order to reduce the entry costs //********************************************************************************** -// sources: -// https://www.osti.gov/biblio/4110379 -// SNAP-50 reactor program cost ~21M USD/year (1965$) -// https://www.osti.gov/biblio/4101005 -// SNAP-50 power conversion program cost ~13M USD/year (1965$) -// https://apps.dtic.mil/dtic/tr/fulltext/u2/a146831.pdf -// 500M to 1B USD estimated to produce and test SNAP-50 - // RTG RTGlevel1 = 57550 // tech = firstRTG RTGlevel2 = 5660, RTGlevel1 // tech = earlyRTG @@ -653,10 +645,10 @@ ENTRYCOSTMODS RTGlevel6 = 6970, RTGlevel5 // tech = modernNuclearPower // Nuclear Reactors - SpaceReactors = 126000 // Assuming same yearly cost as SNAP-50, and first-gen reactors (SNAP-10, BES-5) were developed in around 6 years. 21M/year*6 years = ~126M USD, 126000 funds - PowerReactors = 10000, SpaceReactors, RTGlevel1 //For thermoelectrics - TurbineReactors = 130000, PowerReactors //more complex Rankine/Brayton Cycle power reactors. SNAP-2 took about 10 years to develop power conversion unit, SNAP-50 would have been around 15? 13M/year*10 year = 130M, 130000 funds - FluidCoreReactors = 1000000, SpaceReactors //cover the gas-core stuff if anyone adds that I guess + SpaceReactors = 1000000 + PowerReactors = 50000, SpaceReactors, RTGlevel1 //For thermoelectrics + TurbineReactors = 100000, PowerReactors //more complex Rankine/Brayton Cycle power reactors + LiquidCoreReactors = 1000000, SpaceReactors //********************************************************************************** diff --git a/GameData/RP-1/Tree/TREE-Parts.cfg b/GameData/RP-1/Tree/TREE-Parts.cfg index 07eee4beb7f..2601ce660e1 100644 --- a/GameData/RP-1/Tree/TREE-Parts.cfg +++ b/GameData/RP-1/Tree/TREE-Parts.cfg @@ -7237,14 +7237,6 @@ %MODULE[ModuleTagList] { tag = Nuclear } } -@PART[RO-reactor-prometheus]:FOR[xxxRP0] -{ - %TechRequired = modernNuclearPower - %cost = 24000 - %entryCost = 0 - RP0conf = true - @description ^=:$: From Near Future Electrical mod -} @PART[RO-reactor-snap10a]:FOR[xxxRP0] { %TechRequired = nuclearFissionReactors @@ -7255,32 +7247,10 @@ %MODULE[ModuleTagList] { tag = Nuclear } -} -@PART[RO-reactor-snap2]:FOR[xxxRP0] -{ - %TechRequired = improvedRTG - %cost = 5000 - %entryCost = 0 - RP0conf = true - @description ^=:$: From Near Future Electrical mod - - %MODULE[ModuleTagList] { tag = Nuclear } - } @PART[RO-reactor-snap50]:FOR[xxxRP0] { %TechRequired = improvedRTG - %cost = 10000 - %entryCost = 0 - RP0conf = true - @description ^=:$: From Near Future Electrical mod - - %MODULE[ModuleTagList] { tag = Nuclear } - -} -@PART[RO-reactor-snap50-300]:FOR[xxxRP0] -{ - %TechRequired = multihundredWattRTG %cost = 20000 %entryCost = 0 RP0conf = true @@ -7288,17 +7258,6 @@ %MODULE[ModuleTagList] { tag = Nuclear } -} -@PART[RO-reactor-snap8]:FOR[xxxRP0] -{ - %TechRequired = improvedRTG - %cost = 5000 - %entryCost = 0 - RP0conf = true - @description ^=:$: From Near Future Electrical mod - - %MODULE[ModuleTagList] { tag = Nuclear } - } @PART[RO-shockConeIntake125]:FOR[xxxRP0] { @@ -7392,14 +7351,6 @@ RP0conf = true @description ^=:$: From ROCapsules mod } -@PART[ROC-APAS8995Av2]:FOR[xxxRP0] -{ - %TechRequired = standardDockingPorts - %cost = 3500 - %entryCost = 0 - RP0conf = true - @description ^=:$: From ROCapsules mod -} @PART[ROC-APAS8995P]:FOR[xxxRP0] { %TechRequired = standardDockingPorts @@ -7408,14 +7359,6 @@ RP0conf = true @description ^=:$: From ROCapsules mod } -@PART[ROC-APAS8995Pv2]:FOR[xxxRP0] -{ - %TechRequired = standardDockingPorts - %cost = 3000 - %entryCost = 0 - RP0conf = true - @description ^=:$: From ROCapsules mod -} @PART[ROC-AgenaFairing]:FOR[xxxRP0] { %TechRequired = earlyDocking @@ -7467,22 +7410,6 @@ %MODULE[ModuleTagList] { tag = Instruments } } -@PART[ROC-ApolloCADSActive]:FOR[xxxRP0] -{ - %TechRequired = standardDockingPorts - %cost = 3500 - %entryCost = 0 - RP0conf = true - @description ^=:$: From ROCapsules mod -} -@PART[ROC-ApolloCADSPassive]:FOR[xxxRP0] -{ - %TechRequired = standardDockingPorts - %cost = 3000 - %entryCost = 0 - RP0conf = true - @description ^=:$: From ROCapsules mod -} @PART[ROC-ApolloCM]:FOR[xxxRP0] { %TechRequired = matureCapsules @@ -19477,9 +19404,6 @@ %entryCost = 0 RP0conf = true @description ^=:$: From Universal Storage 2 mod - - %MODULE[ModuleTagList] { tag = NuclearRTG } - } @PART[USRadialTanks]:FOR[xxxRP0] { @@ -29873,13 +29797,10 @@ @PART[rtg-0625]:FOR[xxxRP0] { %TechRequired = modernNuclearPower - %cost = 3550 - %entryCost = 0 + %cost = 20045 + %entryCost = 200445 RP0conf = true @description ^=:$: From Near Future Electrical mod - - %MODULE[ModuleTagList] { tag = NuclearRTG } - } @PART[rtg100]:FOR[xxxRP0] { diff --git a/GameData/RP-1/Tree/identicalParts.cfg b/GameData/RP-1/Tree/identicalParts.cfg index fe3225cf427..d346e6c101f 100644 --- a/GameData/RP-1/Tree/identicalParts.cfg +++ b/GameData/RP-1/Tree/identicalParts.cfg @@ -82,15 +82,11 @@ @PART[ROE-AltairIII]:FOR[xxxRP0] { %identicalParts = RO-AltairIII,ROE-AltairIII,ROE-AltairIII-RN } @PART[ROE-AltairIII-RN]:FOR[xxxRP0] { %identicalParts = RO-AltairIII,ROE-AltairIII,ROE-AltairIII-RN } @PART[ROEE-AMBR]:FOR[xxxRP0] { %identicalParts = ROEE-AMBR } -@PART[rn_apas75]:FOR[xxxRP0] { %identicalParts = ROC-ApolloAPAS75BDB,rn_apas75 } -@PART[ROC-ApolloAPAS75BDB]:FOR[xxxRP0] { %identicalParts = ROC-ApolloAPAS75BDB,rn_apas75 } -@PART[APAS89-95]:FOR[xxxRP0] { %identicalParts = APAS89-95,ROC-APAS8995A,ROC-APAS8995Av2,ROC-APAS8995P,ROC-APAS8995Pv2,bluedog_CXA_APAS_A_L04F,bluedog_CXA_APAS_P } -@PART[bluedog_CXA_APAS_A_L04F]:FOR[xxxRP0] { %identicalParts = APAS89-95,ROC-APAS8995A,ROC-APAS8995Av2,ROC-APAS8995P,ROC-APAS8995Pv2,bluedog_CXA_APAS_A_L04F,bluedog_CXA_APAS_P } -@PART[bluedog_CXA_APAS_P]:FOR[xxxRP0] { %identicalParts = APAS89-95,ROC-APAS8995A,ROC-APAS8995Av2,ROC-APAS8995P,ROC-APAS8995Pv2,bluedog_CXA_APAS_A_L04F,bluedog_CXA_APAS_P } -@PART[ROC-APAS8995A]:FOR[xxxRP0] { %identicalParts = APAS89-95,ROC-APAS8995A,ROC-APAS8995Av2,ROC-APAS8995P,ROC-APAS8995Pv2,bluedog_CXA_APAS_A_L04F,bluedog_CXA_APAS_P } -@PART[ROC-APAS8995Av2]:FOR[xxxRP0] { %identicalParts = APAS89-95,ROC-APAS8995A,ROC-APAS8995Av2,ROC-APAS8995P,ROC-APAS8995Pv2,bluedog_CXA_APAS_A_L04F,bluedog_CXA_APAS_P } -@PART[ROC-APAS8995P]:FOR[xxxRP0] { %identicalParts = APAS89-95,ROC-APAS8995A,ROC-APAS8995Av2,ROC-APAS8995P,ROC-APAS8995Pv2,bluedog_CXA_APAS_A_L04F,bluedog_CXA_APAS_P } -@PART[ROC-APAS8995Pv2]:FOR[xxxRP0] { %identicalParts = APAS89-95,ROC-APAS8995A,ROC-APAS8995Av2,ROC-APAS8995P,ROC-APAS8995Pv2,bluedog_CXA_APAS_A_L04F,bluedog_CXA_APAS_P } +@PART[APAS89-95]:FOR[xxxRP0] { %identicalParts = APAS89-95,ROC-APAS8995A,ROC-APAS8995P,bluedog_CXA_APAS_A_L04F,bluedog_CXA_APAS_P } +@PART[bluedog_CXA_APAS_A_L04F]:FOR[xxxRP0] { %identicalParts = APAS89-95,ROC-APAS8995A,ROC-APAS8995P,bluedog_CXA_APAS_A_L04F,bluedog_CXA_APAS_P } +@PART[bluedog_CXA_APAS_P]:FOR[xxxRP0] { %identicalParts = APAS89-95,ROC-APAS8995A,ROC-APAS8995P,bluedog_CXA_APAS_A_L04F,bluedog_CXA_APAS_P } +@PART[ROC-APAS8995A]:FOR[xxxRP0] { %identicalParts = APAS89-95,ROC-APAS8995A,ROC-APAS8995P,bluedog_CXA_APAS_A_L04F,bluedog_CXA_APAS_P } +@PART[ROC-APAS8995P]:FOR[xxxRP0] { %identicalParts = APAS89-95,ROC-APAS8995A,ROC-APAS8995P,bluedog_CXA_APAS_A_L04F,bluedog_CXA_APAS_P } @PART[bluedog_Apollo_Block3_MissionModule]:FOR[xxxRP0] { %identicalParts = ROC-ApolloMissionModule,bluedog_Apollo_Block3_MissionModule } @PART[ROC-ApolloMissionModule]:FOR[xxxRP0] { %identicalParts = ROC-ApolloMissionModule,bluedog_Apollo_Block3_MissionModule } @PART[bluedog_Apollo_Block3_Capsule]:FOR[xxxRP0] { %identicalParts = ROC-ApolloCMBDBBlockIII,ROC-ApolloCMBlockIII,bluedog_Apollo_Block3_Capsule } @@ -188,8 +184,6 @@ @PART[ntr-sc-25-1]:FOR[xxxRP0] { %identicalParts = ROE-BNTR,SXTNERVA,constellationBNTR,ntr-sc-25-1 } @PART[ROE-BNTR]:FOR[xxxRP0] { %identicalParts = ROE-BNTR,SXTNERVA,constellationBNTR,ntr-sc-25-1 } @PART[SXTNERVA]:FOR[xxxRP0] { %identicalParts = ROE-BNTR,SXTNERVA,constellationBNTR,ntr-sc-25-1 } -@PART[ROC-ApolloCADSActive]:FOR[xxxRP0] { %identicalParts = ROC-ApolloCADSActive,ROC-ApolloCADSPassive } -@PART[ROC-ApolloCADSPassive]:FOR[xxxRP0] { %identicalParts = ROC-ApolloCADSActive,ROC-ApolloCADSPassive } @PART[bluedog_castorSRB]:FOR[xxxRP0] { %identicalParts = ROE-Castor1,ROE-Castor1-RN,bluedog_castorSRB,rn_thor_castor,solidBooster1-1Small } @PART[rn_thor_castor]:FOR[xxxRP0] { %identicalParts = ROE-Castor1,ROE-Castor1-RN,bluedog_castorSRB,rn_thor_castor,solidBooster1-1Small } @PART[ROE-Castor1]:FOR[xxxRP0] { %identicalParts = ROE-Castor1,ROE-Castor1-RN,bluedog_castorSRB,rn_thor_castor,solidBooster1-1Small } diff --git a/GameData/RP-1/changelog.cfg b/GameData/RP-1/changelog.cfg index e686f2a0d54..6f0eddc40dc 100644 --- a/GameData/RP-1/changelog.cfg +++ b/GameData/RP-1/changelog.cfg @@ -5,60 +5,6 @@ KERBALCHANGELOG author = KSP-RO team website = github.com/KSP-RO/RP-1 VERSION - { - version = 3.1.1.2 - versionKSP = 1.12.3 - CHANGE - { - change = What's Changed - subchange = Fix Procedural Avionics window EC amount unit (should be kJ not J) - } - } - VERSION - { - version = 3.1.1.1 - versionKSP = 1.12.3 - CHANGE - { - change = What's Changed - subchange = Fix LC modification validation failing when upgrading 1t LCs to 3t - subchange = Improve Proc Avionics window display of EC to show the avionics wattage of the proposed controllable mass - } - } - VERSION - { - version = 3.1.1.0 - versionKSP = 1.12.3 - CHANGE - { - change = What's Changed - subchange = Update for Kerbalism 3.18 - subchange = Spaceplane crew carrier pods require training, but those training times are minimal - } - } - VERSION - { - version = 3.1.0.0 - versionKSP = 1.12.3 - CHANGE - { - change = What's Changed - subchange = Remove Orbital Recovery contract mentioning it can be completed twice - subchange = Add a patch so that Kerbalism uses the actual inclination of a vessel when checking if an experiment could run (inclination was wrong for vessels not around the current body when Principia is installed due to how Principia implements axial tilt) - subchange = Add Astronaut Complex upgrade requirements to Early X-Planes and Early Crewed Orbit to signpost that upgrades to the AC will be needed - subchange = Fix various tips etc. that mention Astronaut Complex levels - subchange = Fix an issue where UI state could sometimes not be restored properly after closing a popup - subchange = When building a new LC that does not perfectly share commonality with an existing LC, its commonality percent is capped at 95%. This fixes an issue where LCs could be upgraded bit by bit with no efficiency loss - subchange = Highlight (in yellow) when the desired max mass for an LC is above the maximum possible modify limit (or below the minimum possible modify limit) - subchange = Fix an issue where RP-1 would hang on launch if KSPWheel was not installed - subchange = Fix lingering references to Renovate and Upgrade rather than just Modify for LCs - subchange = Update Kerbalism patches to match the existing Kerbalism PRs and make sure they will not be applied to forthcoming Kerbalism releases which have the PRs merged - subchange = Improve the Install Checker's text to be clearer that the issue could be either missing or outdated dependencies when RP-1 doesn't detect its dependencies or itself fails to load - subchange = Add support for new ROC docking ports - subchange = Add optional orbit contract to Crewed Lunar program - } - } - VERSION { version = 3.0.1.0 versionKSP = 1.12.3 diff --git a/README.md b/README.md index 7b9ddb02691..99974147c1b 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@

- +

Welcome to Realistic Progression One, the heavyweight career addon for Kerbal Space Program's Realism Overhaul. diff --git a/Source/GameData.csproj b/Source/GameData.csproj index ca6acb1077f..5f795ad5740 100644 --- a/Source/GameData.csproj +++ b/Source/GameData.csproj @@ -341,9 +341,6 @@ Contracts\Lunar Crewed\CrewedLunarFlyby.cfg - - Contracts\Lunar Crewed\CrewedLunarOrbitRepeat.cfg - Contracts\Lunar Crewed\CrewedMoonLandingRover.cfg diff --git a/Source/InstallChecker/InstallChecker.cs b/Source/InstallChecker/InstallChecker.cs index 8914b59b7b8..5944cc65b00 100644 --- a/Source/InstallChecker/InstallChecker.cs +++ b/Source/InstallChecker/InstallChecker.cs @@ -7,16 +7,8 @@ namespace RP0InstallChecker [KSPAddon(KSPAddon.Startup.Instantly, true)] public class InstallChecker : MonoBehaviour { - private bool _firstFrame = true; - - protected void Update() + protected void Start() { - if (_firstFrame) - { - _firstFrame = false; - return; - } - Version minKSPCFVer = new Version(1, 30, 0); if (!AssemblyLoader.loadedAssemblies.Any(a => a.name.Equals("KSPCommunityFixes") && (new Version(a.versionMajor, a.versionMinor, a.versionRevision)) >= minKSPCFVer)) { @@ -30,7 +22,7 @@ protected void Update() if (assembliesToCheck.Any(an => !AssemblyLoader.loadedAssemblies.Any(a => a.name.Equals(an, StringComparison.OrdinalIgnoreCase)))) { string titleText = "Incorrect RP-1 Installation"; - string contentText = "This could be caused by downloading the RP-1 repo or some specific branch directly from GitHub, or by not installing or not updating dependencies. " + + string contentText = "This could be caused by downloading the RP-1 repo or some specific branch directly from GitHub. " + "Make sure to follow the install guide located in the RP-1 wiki.\n\n" + "If the goal was to obtain the latest developmental version of RP-1, then please use the link at the top of the RP-1 readme."; ShowErrorDialog(titleText, contentText); @@ -40,7 +32,7 @@ protected void Update() if (AssemblyLoader.loadedAssemblies.Any(a => a.name.Equals("KerbalConstructionTime", StringComparison.OrdinalIgnoreCase))) { string titleText = "Incorrect RP-1 Installation"; - string contentText = "You still have a KerbalConstructionTime dll (RP0KCT.dll). Please uninstall RP-1 and properly reinstall it to remove this dll. " + + string contentText = "You still have a KerbalConstructionTime dll (RP0KCT.dll). Please uninstall RP-1 and properly reinstall it to remove this dll." + "Make sure to follow the install guide located in the RP-1 wiki.\n\n" + "If the goal was to obtain the latest developmental version of RP-1, then please use the link at the top of the RP-1 readme after uninstalling this RP-1 install."; ShowErrorDialog(titleText, contentText); @@ -48,14 +40,11 @@ protected void Update() } assembliesToCheck = new[] { "ToolbarController", "ClickThroughBlocker", "RealFuels", "ContractConfigurator", "ModularFlightIntegrator" }; // These are values of KSPAssembly attribute - var kerbAssembly = AssemblyLoader.loadedAssemblies.FirstOrDefault(a => a.name.StartsWith("Kerbalism", StringComparison.OrdinalIgnoreCase)); - if (assembliesToCheck.Any(an => !AssemblyLoader.loadedAssemblies.Any(a => a.name.Equals(an, StringComparison.OrdinalIgnoreCase))) - || kerbAssembly == null - || kerbAssembly.assembly.GetName().Version < new Version("3.18")) + if (assembliesToCheck.Any(an => !AssemblyLoader.loadedAssemblies.Any(a => a.name.Equals(an, StringComparison.OrdinalIgnoreCase)))) { string titleText = "Incorrect RP-1 Installation"; - string contentText = "You are missing dependencies for RP-1. This could be caused by manually installing RP-1, or by not updating dependencies. " + - "Make sure to follow the install guide located in the RP-1 wiki and make sure to update your mods in CKAN.\n\n" + + string contentText = "You are missing dependencies for RP-1. This could be caused by manually installing RP-1, or by not updating dependencies." + + "Make sure to follow the install guide located in the RP-1 wiki.\n\n" + "If the goal was to obtain the latest developmental version of RP-1, then install normally through the guide and then use the link at the top of the RP-1 readme."; ShowErrorDialog(titleText, contentText); return; diff --git a/Source/RP0/Avionics/ModuleAvionics.cs b/Source/RP0/Avionics/ModuleAvionics.cs index 3bf87eb6fe7..451004aca4f 100644 --- a/Source/RP0/Avionics/ModuleAvionics.cs +++ b/Source/RP0/Avionics/ModuleAvionics.cs @@ -175,7 +175,7 @@ public override void OnAwake() base.OnAwake(); GameEvents.onStageActivate.Add(StageActivated); if (HighLogic.LoadedScene != GameScenes.LOADING) - KerbalismAPI ??= KerbalismUtils.Assembly; + KerbalismAPI ??= AssemblyLoader.loadedAssemblies.FirstOrDefault(x => x.name.StartsWith("Kerbalism"))?.assembly; } // OnStartFinished() instead of OnStart(), to let ModuleCommand configure itself first. diff --git a/Source/RP0/Avionics/ModuleProceduralAvionics.cs b/Source/RP0/Avionics/ModuleProceduralAvionics.cs index 107ce132bac..2c883583801 100644 --- a/Source/RP0/Avionics/ModuleProceduralAvionics.cs +++ b/Source/RP0/Avionics/ModuleProceduralAvionics.cs @@ -1,4 +1,5 @@ -using RealFuels.Tanks; +using KSPAPIExtensions; +using RealFuels.Tanks; using System; using System.Collections.Generic; using UniLinq; @@ -132,7 +133,7 @@ internal float GetShieldedAvionicsMass(float controllableMass) private float GetShieldingMass(float avionicsMass) => Mathf.Pow(avionicsMass, 2f / 3) * CurrentProceduralAvionicsTechNode.shieldingMassFactor; protected override float GetEnabledkW() => GetEnabledkW(CurrentProceduralAvionicsTechNode, GetInternalMassLimit()); - internal static float GetEnabledkW(ProceduralAvionicsTechNode techNode, float controllableMass) => GetPolynomial(controllableMass, techNode.powerExponent, techNode.powerConstant, techNode.powerFactor) / 1000f; + private static float GetEnabledkW(ProceduralAvionicsTechNode techNode, float controllableMass) => GetPolynomial(controllableMass, techNode.powerExponent, techNode.powerConstant, techNode.powerFactor) / 1000f; protected override float GetDisabledkW() => GetEnabledkW() * CurrentProceduralAvionicsTechNode.disabledPowerFactor; private static float GetPolynomial(float value, float exponent, float constant, float factor) => (Mathf.Pow(value, exponent) + constant) * factor; @@ -586,21 +587,25 @@ internal void RefreshDisplays() _window?.RefreshDisplays(); } - public static string BuildPowerString(float enabledkW, float disabledkW) + private void RefreshPowerDisplay() { var powerConsumptionBuilder = StringBuilderCache.Acquire(); - powerConsumptionBuilder.Append(KERBALISM.Lib.HumanOrSIRate(enabledkW, KERBALISM.Lib.ECResID)); - if (disabledkW > 0) + AppendPowerString(powerConsumptionBuilder, GetEnabledkW()); + float dkW = GetDisabledkW(); + if (dkW > 0) { - powerConsumptionBuilder.Append(" / "); - powerConsumptionBuilder.Append(KERBALISM.Lib.HumanOrSIRate(disabledkW, KERBALISM.Lib.ECResID)); + powerConsumptionBuilder.Append(" /"); + AppendPowerString(powerConsumptionBuilder, dkW); } - return powerConsumptionBuilder.ToStringAndRelease(); + powerRequirementsDisplay = powerConsumptionBuilder.ToStringAndRelease(); } - private void RefreshPowerDisplay() + private void AppendPowerString(System.Text.StringBuilder builder, float val) { - powerRequirementsDisplay = BuildPowerString(GetEnabledkW(), GetDisabledkW()); + if (val >= 1) + builder.AppendFormat(KwFormat, val).Append("\u2009kW"); + else + builder.AppendFormat(WFormat, val * 1000).Append("\u2009W"); } private void SetScienceContainer() diff --git a/Source/RP0/Harmony/CustomBarnKit.cs b/Source/RP0/Harmony/CustomBarnKit.cs index 74c69fb4d84..f95f60c7799 100644 --- a/Source/RP0/Harmony/CustomBarnKit.cs +++ b/Source/RP0/Harmony/CustomBarnKit.cs @@ -19,6 +19,7 @@ internal static void Postfix_LoadUpgradesPrices(ref bool ___varLoaded, bool __st { if (___varLoaded && !__state) { + MaintenanceHandler.ClearFacilityCosts(); MaintenanceHandler.Instance?.ScheduleMaintenanceUpdate(); } } diff --git a/Source/RP0/Harmony/KSPWheel.cs b/Source/RP0/Harmony/KSPWheel.cs index 4ddde1f6db3..7f55501c198 100644 --- a/Source/RP0/Harmony/KSPWheel.cs +++ b/Source/RP0/Harmony/KSPWheel.cs @@ -1,20 +1,12 @@ using HarmonyLib; using System.Reflection; using UnityEngine; -using System.Linq; namespace RP0.Harmony { [HarmonyPatch] internal class PatchKSPWheel_KSPWheelDamage_wearUpdateSimple { - static bool Prepare() - { - bool foundKSPWheel = AssemblyLoader.loadedAssemblies.FirstOrDefault(a => a.name.Equals("KSPWheel", System.StringComparison.OrdinalIgnoreCase)) != null; - RP0Debug.Log("Attempting to patch KSPWheel. Found? " + foundKSPWheel.ToString(), true); - return foundKSPWheel; - } - static MethodBase TargetMethod() => AccessTools.TypeByName("KSPWheel.KSPWheelDamage")?.GetMethod("wearUpdateSimple", AccessTools.all); [HarmonyPrefix] diff --git a/Source/RP0/Harmony/KerbalismPatcher.cs b/Source/RP0/Harmony/KerbalismPatcher.cs index 4ed5e84f563..23c25ad80a3 100644 --- a/Source/RP0/Harmony/KerbalismPatcher.cs +++ b/Source/RP0/Harmony/KerbalismPatcher.cs @@ -4,7 +4,6 @@ using UnityEngine; using System.Collections.Generic; using System.Reflection; -using System.Linq; namespace RP0.Harmony { @@ -57,8 +56,6 @@ internal static void Postfix_SetDifficultyPreset(ref float ___shieldingEfficienc [HarmonyPatch(typeof(CrewSpecs))] internal class PatchKerbalism_CrewSpecs { - static bool Prepare() => KerbalismUtils.IsValidToPatch(new Version(3, 17, int.MaxValue, int.MaxValue), true); - [HarmonyPrefix] [HarmonyPatch("Check", new Type[] { typeof(ProtoCrewMember) })] internal static bool Prefix_Check(ProtoCrewMember c, ref bool __result) @@ -118,53 +115,38 @@ internal static void Postfix_Update(Experiment __instance) [HarmonyPatch(typeof(Sim))] internal class PatchKerbalism_Sim { - static bool Prepare() => KerbalismUtils.IsValidToPatch(new Version(3, 17, int.MaxValue, int.MaxValue), true); - [HarmonyPrefix] [HarmonyPatch("ShadowPeriod", new Type[] { typeof(Vessel) })] internal static bool Prefix_ShadowPeriod(Vessel v, ref double __result) { - // We have only 1 sun so don't try to figure out what's the current sunData. - Vector3d sunVec = (Planetarium.fetch.Sun.position - Lib.VesselPosition(v)).normalized; - __result = EclipseFraction(v, Planetarium.fetch.Sun, sunVec) * Sim.OrbitalPeriod(v); - return false; - } - - [HarmonyPrefix] - [HarmonyPatch("SampleSunFactor")] - internal static bool Prefix_SampleSunFactor(Vessel v, double elapsedSeconds, ref double __result) - { - // We have only 1 sun so don't try to figure out what's the current sunData. - __result = SampleSunFactor(v, elapsedSeconds, Planetarium.fetch.Sun); - return false; - } - - public static double EclipseFraction(Vessel v, CelestialBody sun, Vector3d sunVec) - { - var obt = v.orbitDriver?.orbit; + Orbit obt = v.orbitDriver?.orbit; if (obt == null) - return 0; + { + __result = 0d; + return false; + } bool incNaN = double.IsNaN(obt.inclination); if (Lib.Landed(v) || incNaN) { + var sun = Planetarium.fetch.Sun; var mb = v.mainBody; if (sun == mb) { - return 0; + __result = 0d; } - - if (mb.referenceBody == sun && mb.tidallyLocked) + else if (mb.referenceBody == sun && mb.tidallyLocked) { - Vector3d vPos = incNaN ? (Vector3d)v.transform.position : v.orbitDriver.pos + mb.position; + Vector3d vPos = incNaN ? v.transform.position : v.orbitDriver.pos + mb.position; + Vector3d sunV = sun.position - vPos; // We have to refind orbit pos in case inc is NaN - return Vector3d.Dot(sunVec, mb.position - vPos) < 0 ? 0 : 1.0; + __result = Vector3d.Dot(sunV, mb.position - vPos) > 0d ? mb.rotationPeriod : 0d; } - - // Just assume half the body's rotation period (note that - // for landed vessels, the orbital period is considered the - // body's rotation period). - return 0.5 * mb.rotationPeriod; + else + { + __result = mb.rotationPeriod * 0.5d; + } + return false; } double e = obt.eccentricity; @@ -172,9 +154,11 @@ public static double EclipseFraction(Vessel v, CelestialBody sun, Vector3d sunVe { // This is wrong, of course, but given the speed of an escape trajectory // you'll be in shadow for a very miniscule fraction of the period. - return 0; + __result = 0d; + return false; } Vector3d planeNormal = Vector3d.Cross(v.orbitDriver.vel, -v.orbitDriver.pos).normalized; + Vector3d sunVec = Planetarium.fetch.Sun.position - (v.mainBody.position + v.orbitDriver.pos).normalized; double sunDot = Math.Abs(Vector3d.Dot(sunVec, planeNormal)); double betaAngle = Math.PI * 0.5d - Math.Acos(sunDot); @@ -183,86 +167,60 @@ public static double EclipseFraction(Vessel v, CelestialBody sun, Vector3d sunVe // Now, branch depending on if we're in a low-ecc orbit // We check locally for betaStar because we might bail early in the Kerbalism case - double frac; if (e < 0.1d) - frac = FracEclipseCircular(betaAngle, a, R); + __result = FracEclipseCirc(betaAngle, a, R); else - frac = FracEclipseElliptical(v, betaAngle, a, R, e, sunVec); + __result = FracEclipseKerbalism(v, betaAngle, a, R, e, sunVec); + + __result *= obt.period; - return frac; + return false; } - /// - /// This computes eclipse fraction for circular orbits - /// (well, realy circular _low_ orbits, but at higher altitudes - /// you're not spending much time in shadow anyway). - /// - /// The beta angle (angle between the solar normal and its projection on the orbital plane) - /// The semi-major axis - /// The body's radius - /// - private static double FracEclipseCircular(double betaAngle, double sma, double R) + internal static double FracEclipseCirc(double betaAngle, double sma, double R) { // from https://commons.erau.edu/cgi/viewcontent.cgi?article=1412&context=ijaaa - // beta* is the angle above which there is no occlusion of the orbit double betaStar = Math.Asin(R / sma); if (Math.Abs(betaAngle) >= betaStar) - return 0; + return 0d; double avgHeight = sma - R; - return (1.0 / Math.PI) * Math.Acos(Math.Sqrt(avgHeight * avgHeight + 2.0 * R * avgHeight) / (sma * Math.Cos(betaAngle))); + return (1d / Math.PI) * Math.Acos(Math.Sqrt(avgHeight * avgHeight + 2 * R * avgHeight) / (sma * Math.Cos(betaAngle))); } - /// - /// An analytic solution to the fraction of an orbit eclipsed by its primary - /// - /// The vessel - /// The beta angle (angle between the solar normal and its projection on the orbital plane) - /// semi-major axis - /// body radius - /// eccentricity - /// The normalized vector to the sun - /// - private static double FracEclipseElliptical(Vessel v, double betaAngle, double a, double R, double e, Vector3d sunVec) + internal static double FracEclipseKerbalism(Vessel v, double betaAngle, double a, double R, double e, Vector3d sunVec) { var obt = v.orbit; double b = obt.semiMinorAxis; // Just bail if we were going to report NaN, or we're in a weird state // We've likely avoided this already due to the eccentricity check in the main call, though if (a < b || b < R) - return 0; + return 0d; // Compute where the Pe is with respect to the sun Vector3d PeToBody = -Planetarium.Zup.WorldToLocal(obt.semiLatusRectum / (1d + e) * obt.OrbitFrame.X).xzy; Vector3d orthog = Vector3d.Cross(obt.referenceBody.GetFrameVel().xzy.normalized, sunVec); Vector3d PeToBodyProj = (PeToBody - orthog * Vector3d.Dot(PeToBody, orthog)).normalized; - // Use these to calculate true anomaly for this projected orbit double tA = Math.Acos(Vector3d.Dot(sunVec, PeToBodyProj)); // Get distance to ellipse edge - double r = a * (1.0 - e * e) / (1.0 + e * Math.Cos(tA)); + double r = a * (1d - e * e) / (1 + e * Math.Cos(tA)); double betaStar = Math.Asin(R / r); double absBeta = Math.Abs(betaAngle); if (absBeta >= betaStar) return 0d; - // Get the vector to the center of the eclipse - double vecToHalfEclipsePortion = Math.Asin(R / r); - // Get the true anomalies at the front and rear of the eclipse portion - double vAhead = tA + vecToHalfEclipsePortion; - double vBehind = tA - vecToHalfEclipsePortion; - vAhead *= 0.5; - vBehind *= 0.5; - double ePlusOneSqrt = Math.Sqrt(1 + e); - double eMinusOneSqrt = Math.Sqrt(1 - e); - // Calculate eccentric and mean anomalies - double EAAhead = 2.0 * Math.Atan2(eMinusOneSqrt * Math.Sin(vAhead), ePlusOneSqrt * Math.Cos(vAhead)); - double MAhead = EAAhead - e * Math.Sin(EAAhead); - double EABehind = 2.0 * Math.Atan2(eMinusOneSqrt * Math.Sin(vBehind), ePlusOneSqrt * Math.Cos(vBehind)); - double Mbehind = EABehind - e * Math.Sin(EABehind); - // Finally, calculate the eclipse fraction from mean anomalies - double eclipseFrac = (MAhead - Mbehind) / (2.0 * Math.PI); + double halfEclipsedv = Math.Asin(R / r); + double vAhead = tA + halfEclipsedv; + double vBehind = tA - halfEclipsedv; + double sqrtep = Math.Sqrt(1d + e); + double sqrten = Math.Sqrt(1d - e); + double Eahead = 2d * Math.Atan2(sqrten * Math.Sin(vAhead * 0.5d), sqrtep * Math.Cos(vAhead * 0.5d)); + double Mahead = Eahead - e * Math.Sin(Eahead); + double Ebehind = 2d * Math.Atan2(sqrten * Math.Sin(vBehind * 0.5d), sqrtep * Math.Cos(vBehind * 0.5d)); + double Mbehind = Ebehind - e * Math.Sin(Ebehind); + double eclipseFrac = (Mahead - Mbehind) / (2d * Math.PI); // This is not quite correct I think, but it'll be close enough. // We just lerp between 0 occlusion at beta = betaStar, and full occlusion // at beta = 0. This takes advantage of the difference 1 degree makes being larger @@ -271,55 +229,122 @@ private static double FracEclipseElliptical(Vessel v, double betaAngle, double a return eclipseFrac * absBeta / betaStar; } - /// - /// This expects to be called repeatedly - /// - public static double SampleSunFactor(Vessel v, double elapsedSeconds, CelestialBody sun) + [HarmonyPrefix] + [HarmonyPatch("SampleSunFactor")] + internal static bool Prefix_SampleSunFactor(Vessel v, double elapsedSeconds, ref double __result) { - UnityEngine.Profiling.Profiler.BeginSample("Kerbalism.Sim.SunFactor2"); + __result = SampleSunFactor(v, elapsedSeconds); + return false; + } - bool isSurf = Lib.Landed(v); - if (v.orbitDriver == null || v.orbitDriver.orbit == null || (!isSurf && double.IsNaN(v.orbit.inclination))) + private static readonly List _cbPositions = new List(); + private static readonly List _cbParents = new List(); + private static readonly List _occluderToPos = new List(); + private static readonly List _cbSLRs = new List(); + + private static void InitBodies() + { + int c = FlightGlobals.Bodies.Count; + if (_cbPositions.Count == c) + return; + + _cbPositions.Clear(); + _cbParents.Clear(); + _cbSLRs.Clear(); + if (_cbPositions.Capacity < c) + _cbPositions.Capacity = c; + if (_cbParents.Capacity < c) + _cbParents.Capacity = c; + if (_cbSLRs.Capacity < c) + _cbSLRs.Capacity = c; + for (int i = 0; i < c; ++i) { - UnityEngine.Profiling.Profiler.EndSample(); - return 1d; // fail safe + var cb = FlightGlobals.Bodies[i]; + var parent = cb.orbitDriver?.orbit?.referenceBody; + if (parent != null && parent != cb) + { + _cbParents.Add(FlightGlobals.GetBodyIndex(parent)); + _cbSLRs.Add(cb.orbit.semiLatusRectum); + } + else + { + _cbParents.Add(-1); + _cbSLRs.Add(1d); + } + _cbPositions.Add(new Vector3d()); + } + } + + internal static void FillCBPositionsAtUT(double ut, List occluders) + { + // Start from unknown positions + for (int i = _cbPositions.Count; i-- > 0;) + _cbPositions[i] = new Vector3d(double.MaxValue, double.MaxValue); + + // Fill positions at UT, recursively (skipping calculated parents) + for (int i = occluders.Count; i-- > 0;) + _FillCBPositionAtUT(_occluderToPos[i], ut); + + + } + internal static void _FillCBPositionAtUT(int i, double ut) + { + if (_cbPositions[i].x != double.MaxValue) + return; + + var cb = FlightGlobals.Bodies[i]; + int pIdx = _cbParents[i]; + if (pIdx == -1) + { + _cbPositions[i] = cb.position; + return; } + _FillCBPositionAtUT(pIdx, ut); + _cbPositions[i] = _cbPositions[pIdx] + fastGetRelativePositionAtUT(cb.orbit, ut, _cbSLRs[i]); + } + + internal static double SampleSunFactor(Vessel v, double elapsedSeconds) + { + bool isSurf = Lib.Landed(v); + if (v.orbitDriver == null || (!isSurf && (v.orbit == null || double.IsNaN(v.orbit.inclination)))) + return 1d; // fail safe + + UnityEngine.Profiling.Profiler.BeginSample("Kerbalism.Sim.SunFactor2"); int sunSamples = 0; var now = Planetarium.GetUniversalTime(); var vd = v.KerbalismData(); + CelestialBody sun = vd.EnvMainSun.SunData.body; + int sunIdx = FlightGlobals.GetBodyIndex(sun); List occluders = vd.EnvVisibleBodies; // set up CB position caches - bodyCache.SetForOccluders(occluders); + InitBodies(); + foreach (var cb in occluders) + { + _occluderToPos.Add(FlightGlobals.GetBodyIndex(cb)); + } // Set max time to calc double maxCalculation = elapsedSeconds * 1.01d; // cache values for speed double semiLatusRectum = 0d; - CelestialBody mb = v.mainBody; - Vector3d surfPos; - Vector3d polarAxis; + int bodyIdx = FlightGlobals.GetBodyIndex(v.orbit.referenceBody); + CelestialBody mb; + Vector3d surfPos = new Vector3d(); if (isSurf) { - surfPos = mb.GetRelSurfacePosition(v.latitude, v.longitude, v.altitude); - // Doing this manually instead of swizzling surfPos avoids one of the two swizzles - surfPos = (surfPos.x * mb.BodyFrame.X + surfPos.z * mb.BodyFrame.Y + surfPos.y * mb.BodyFrame.Z).xzy; - - // This will not be quite correct for Principia but at least it's - // using the BodyFrame, which Principia clobbers, rather than the - // transform. - polarAxis = mb.BodyFrame.Rotation.swizzle * Vector3d.up; + mb = v.mainBody; + surfPos = v.mainBody.GetRelSurfacePosition(v.latitude, v.longitude, v.altitude); } else { + mb = null; semiLatusRectum = v.orbit.semiLatusRectum; maxCalculation = Math.Min(maxCalculation, v.orbit.period); - surfPos = new Vector3d(); - polarAxis = new Vector3d(); } // Set up timimg @@ -339,79 +364,65 @@ public static double SampleSunFactor(Vessel v, double elapsedSeconds, CelestialB for (int i = sampleCount; i-- > 0;) { double ut = now - i * stepLength; - bodyCache.SetForUT(ut, occluders); - Vector3d bodyPos = bodyCache.GetBodyPosition(mb.flightGlobalsIndex); + FillCBPositionsAtUT(ut, occluders); Vector3d pos; - if (isSurf) + if (!isSurf) { - // Rotate the surface position based on where the body would have rotated in the past - // Note: rotation is around *down* so we flip the sign of the rotation - pos = QuaternionD.AngleAxis(mb.rotPeriodRecip * i * stepLength * 360d, polarAxis) * surfPos; + pos = _cbPositions[bodyIdx] + fastGetRelativePositionAtUT(v.orbit, ut, semiLatusRectum); } else { - pos = FastGetRelativePositionAtUT(v.orbit, ut, semiLatusRectum); + // Doing this manually instead of calling LocalToWorld avoids a double swizzle (was LocalToWorld(surfPos.xzy).xzy ) + pos = surfPos.x * mb.BodyFrame.X + surfPos.y * mb.BodyFrame.Z + surfPos.z * mb.BodyFrame.Y; + // Now rotate the pos based on where the body would have rotated in the past + pos = QuaternionD.AngleAxis(mb.rotPeriodRecip * -i * stepLength * 360d, mb.transform.up) * pos; + pos += _cbPositions[bodyIdx]; // and apply the position } - // Apply the body's position - pos += bodyPos; - - bool vis = IsSunVisibleAtTime(v, pos, sun, occluders, isSurf); + bool vis = IsSunVisibleAtTime(v, pos, sun, sunIdx, occluders, ut); if (vis) ++sunSamples; } + _occluderToPos.Clear(); UnityEngine.Profiling.Profiler.EndSample(); double sunFactor = (double)sunSamples / (double)sampleCount; - //Lib.Log("Vessel " + v + " sun factor: " + sunFactor + " " + sunSamples + "/" + sampleCount + " #s=" + sampleCount + " e=" + elapsedSeconds + " step=" + stepLength); return sunFactor; } - /// - /// A version of IsBodyVisibleAt that is optimized for suns - /// and supports using arbitrary time (assuming bodyCache is set) - /// - /// - /// Vessel position at time - /// - /// The body index of the sun - /// - /// - /// is the vessel landed - /// - internal static bool IsSunVisibleAtTime(Vessel vessel, Vector3d vesselPos, CelestialBody sun, List occluders, bool isSurf) + // We have to reimplement this code because we need to check at a specific time + internal static bool IsSunVisibleAtTime(Vessel vessel, Vector3d vesselPos, CelestialBody sun, int sunIdx, List occluders, double UT) { // generate ray parameters - Vector3d sunPos = bodyCache.GetBodyPosition(sun.flightGlobalsIndex) - vesselPos; + Vector3d sunPos = _cbPositions[sunIdx] - vesselPos; var sunDir = sunPos; var sunDist = sunDir.magnitude; sunDir /= sunDist; sunDist -= sun.Radius; // for very small bodies the analytic method is very unreliable at high latitudes - // So we use a modified version of the analytic method (unlike IsBodyVisible) + // So we use a modified version of the analytic method bool ignoreMainbody = false; - if (isSurf && vessel.mainBody.Radius < 100000.0) + if (Lib.Landed(vessel) && vessel.mainBody.Radius < 100000.0) { ignoreMainbody = true; - Vector3d mainBodyPos = bodyCache.GetBodyPosition(vessel.mainBody.flightGlobalsIndex); + Vector3d mainBodyPos = _cbPositions[FlightGlobals.GetBodyIndex(vessel.mainBody)]; Vector3d mainBodyDir = (mainBodyPos - vesselPos).normalized; double dotSunBody = Vector3d.Dot(mainBodyDir, sunDir); Vector3d mainBodyDirProjected = mainBodyDir * dotSunBody; // Assume the sun is far enough away that we can treat the line from the vessel - // to the sun as parallel to the line from the body center to the sun, which means + // to the sine as parallel to the line from the body center to the sun, which means // we can ignore testing further if we're very close to the plane orthogonal to the - // sun vector but on the opposite side of the body from the sun. - // We don't strictly test dot to give ourselves approx half a degree of slop - if (mainBodyDirProjected.sqrMagnitude > 0.0001d && dotSunBody > 0d) + // sun vector, and we only care if the dot is positive + if (mainBodyDirProjected.sqrMagnitude > 0.0001d && dotSunBody > 0d) // approx half a degree from the pole { return false; } } // check if the ray intersect one of the provided bodies - for (int i = occluders.Count; i-- > 0;) + for (int i = 0; i < occluders.Count; ++i) { CelestialBody occludingBody = occluders[i]; if (occludingBody == sun) @@ -419,7 +430,7 @@ internal static bool IsSunVisibleAtTime(Vessel vessel, Vector3d vesselPos, Celes if (ignoreMainbody && occludingBody == vessel.mainBody) continue; - Vector3d toBody = bodyCache.GetBodyPosition(occludingBody.flightGlobalsIndex) - vesselPos; + Vector3d toBody = _cbPositions[_occluderToPos[i]] - vesselPos; // projection of origin->body center ray over the raytracing direction double k = Vector3d.Dot(toBody, sunDir); // the ray doesn't hit body if its minimal analytical distance along the ray is less than its radius @@ -432,136 +443,7 @@ internal static bool IsSunVisibleAtTime(Vessel vessel, Vector3d vesselPos, Celes return true; } - /// - /// A cache to speed calculation of body positions at a given UT, based on - /// as set of occluders. Used when calculating solar exposure at analytic rates. - /// This creates storage for each body in FlightGlobals, but only caches - /// a lookup from occluder to body index, and then for each relevant occluder - /// and its parents a lookup to each parent (and on up the chain) and the - /// semilatus rectum. Then when set for a UT, it calculates positions - /// for each occluder on up the chain to the root CB. - /// - public class BodyCache - { - private Vector3d[] positions = null; - private int[] parents; - private double[] semiLatusRectums; - - public Vector3d GetBodyPosition(int idx) { return positions[idx]; } - - /// - /// Check and, if uninitialized, setup the body caches - /// - private void CheckInitBodies() - { - int c = FlightGlobals.Bodies.Count; - if (positions != null && positions.Length == c) - return; - - positions = new Vector3d[c]; - parents = new int[c]; - semiLatusRectums = new double[c]; - - for (int i = 0; i < c; ++i) - { - var cb = FlightGlobals.Bodies[i]; - // Set parent index lookup - var parent = cb.orbitDriver?.orbit?.referenceBody; - if (parent != null && parent != cb) - { - parents[i] = parent.flightGlobalsIndex; - } - else - { - parents[i] = -1; - } - } - } - - /// - /// Initialize the cache for a set of occluders. This - /// will set up the lookups for the occluder bodies and - /// cache the semi-latus recturm for each body and its - /// parents - /// - /// - public void SetForOccluders(List occluders) - { - CheckInitBodies(); - - // Now clear all SLRs and then set only the relevant ones - // (i.e. the occluders, their parents, their grandparents, etc) - for (int i = semiLatusRectums.Length; i-- > 0;) - semiLatusRectums[i] = double.MaxValue; - for (int i = occluders.Count; i-- > 0;) - SetSLRs(occluders[i].flightGlobalsIndex); - } - - private void SetSLRs(int i) - { - // Check if set - if (semiLatusRectums[i] != double.MaxValue) - return; - - // Check if parent - int pIdx = parents[i]; - if (pIdx == -1) - { - semiLatusRectums[i] = 1d; - return; - } - - semiLatusRectums[i] = FlightGlobals.Bodies[i].orbit.semiLatusRectum; - SetSLRs(pIdx); - } - - /// - /// Set the occluder body positions at the given UT - /// - /// - public void SetForUT(double ut, List occluders) - { - // Start from unknown positions - for (int i = positions.Length; i-- > 0;) - positions[i] = new Vector3d(double.MaxValue, double.MaxValue); - - // Fill positions at UT, recursively (skipping calculated parents) - for (int i = occluders.Count; i-- > 0;) - SetForUTInternal(occluders[i].flightGlobalsIndex, ut); - } - - private void SetForUTInternal(int i, double ut) - { - // If we've already been here, bail - if (positions[i].x != double.MaxValue) - return; - - // Check if we have a parent. If not - // position is just the body's position - var cb = FlightGlobals.Bodies[i]; - int pIdx = parents[i]; - if (pIdx == -1) - { - positions[i] = cb.position; - return; - } - - // If we do have a parent, recurse and then - // set position based on newly-set parent's pos - SetForUTInternal(pIdx, ut); - positions[i] = positions[pIdx] + FastGetRelativePositionAtUT(cb.orbit, ut, semiLatusRectums[i]); - } - } - - /// - /// A fast version of KSP's GetRelativePositionAtUT. - /// It skips a bunch of steps and uses cached values - /// - /// - /// - /// - /// - private static Vector3d FastGetRelativePositionAtUT(Orbit orbit, double UT, double semiLatusRectum) + internal static Vector3d fastGetRelativePositionAtUT(Orbit orbit, double UT, double semiLatusRectum) { double T = orbit.getObtAtUT(UT); @@ -574,8 +456,6 @@ private static Vector3d FastGetRelativePositionAtUT(Orbit orbit, double UT, doub Vector3d pos = semiLatusRectum / (1.0 + orbit.eccentricity * cos) * (orbit.OrbitFrame.X * cos + orbit.OrbitFrame.Y * sin); return Planetarium.Zup.WorldToLocal(pos).xzy; } - - static readonly BodyCache bodyCache = new BodyCache(); } #endregion @@ -588,8 +468,6 @@ private static Vector3d FastGetRelativePositionAtUT(Orbit orbit, double UT, doub [HarmonyPatch(typeof(SolarPanelFixer))] internal class PatchKerbalism_SolarPanelFixer { - static bool Prepare() => KerbalismUtils.IsValidToPatch(new Version(3, 17, int.MaxValue, int.MaxValue), true); - [HarmonyPostfix] [HarmonyPatch("Update")] internal static void Postfix_Update(SolarPanelFixer __instance) @@ -614,8 +492,6 @@ internal static void Postfix_Update(SolarPanelFixer __instance) [HarmonyPatch(typeof(Specifics))] internal class PatchKerbalism_Specifics { - static bool Prepare() => KerbalismUtils.IsValidToPatch(new Version(3, 17, int.MaxValue, int.MaxValue), true); - private static string _ecName; private static bool _needName = true; @@ -645,6 +521,86 @@ internal static void Prefix_Add(ref string label, ref string value) } } + // The following patches don't work, and are done instead + // by the hacky workarounds below them +#if disabled + // This throws: + // FormatException: Method static System.Void KERBALISM.Planner.Planner::AddSubPanelEC(KERBALISM.Panel p) cannot be patched. Reason: The type initializer for 'KERBALISM.Planner.Planner' threw an exception. + // HarmonyLib.PatchFunctions.UpdateWrapper + [HarmonyPatch(typeof(KERBALISM.Planner.Planner))] + internal class PatchKerbalism_Planner + { + [HarmonyPrefix] + [HarmonyPatch("AddSubPanelEC")] + internal static bool Prefix_AddSubPanelEC(Panel p, KERBALISM.Planner.ResourceSimulator ___resource_sim) + { + KERBALISM.Planner.SimulatedResource simulatedResource = ___resource_sim.Resource("ElectricCharge"); + string tooltip = simulatedResource.Tooltip(); + p.AddSection(Local.Planner_ELECTRICCHARGE); + p.AddContent(Local.Planner_storage, Lib.HumanReadableAmount(simulatedResource.storage), tooltip); + p.AddContent(Local.Planner_consumed, KSPUtil.PrintSI(simulatedResource.consumed * 1000d, "W", 3), tooltip); + p.AddContent(Local.Planner_produced, KSPUtil.PrintSI(simulatedResource.produced * 1000d, "W", 3), tooltip); + p.AddContent(Local.Planner_duration, Lib.HumanReadableDuration(simulatedResource.Lifetime())); + + return false; + } + } + + // This fails the same way. + + [HarmonyPatch(typeof(KERBALISM.Planner.Planner))] + internal class PatchKerbalism_Planner + { + private static readonly FieldInfo _resSimField = typeof(KERBALISM.Planner.Planner).GetField("resource_sim", AccessTools.all); + private static bool _needField = true; + private static KERBALISM.Planner.ResourceSimulator _resource_sim; + + private static readonly MethodInfo _addSubECMethod = typeof(KERBALISM.Planner.Planner).GetMethod("AddSubPanelEC", AccessTools.all); + private static readonly MethodInfo _replaceMethod = typeof(PatchKerbalism_Planner).GetMethod("ReplacementAddSubPanelEC", AccessTools.all); + + [HarmonyTranspiler] + [HarmonyPatch("Update")] + internal static IEnumerable Transpiler(IEnumerable instructions) + { + List code = new List(instructions); + for (int i = 0; i < code.Count; ++i) + { + if (code[i].Calls(_addSubECMethod)) + { + code[i] = new CodeInstruction(System.Reflection.Emit.OpCodes.Call, _replaceMethod); + break; + } + } + return code; + } + + internal static void ReplacementAddSubPanelEC(Panel p) + { + if (_needField) + { + _resource_sim = (KERBALISM.Planner.ResourceSimulator)_resSimField.GetValue(null); + _needField = false; + } + + KERBALISM.Planner.SimulatedResource simulatedResource = _resource_sim.Resource("ElectricCharge"); + string tooltip = simulatedResource.Tooltip(); + string[] splitTip = tooltip.Split('\n'); + for (int i = 0; i < splitTip.Length; ++i) + { + if (splitTip[i].Length > 0) + KerbalismUtils.HumanRateToSI(ref splitTip[i], "W", 1000d); + } + tooltip = string.Join("\n", splitTip); + + p.AddSection(Local.Planner_ELECTRICCHARGE); + p.AddContent(Local.Planner_storage, Lib.HumanReadableAmount(simulatedResource.storage), tooltip); + p.AddContent(Local.Planner_consumed, KSPUtil.PrintSI(simulatedResource.consumed * 1000d, "W", 4), tooltip); + p.AddContent(Local.Planner_produced, KSPUtil.PrintSI(simulatedResource.produced * 1000d, "W", 4), tooltip); + p.AddContent(Local.Planner_duration, Lib.HumanReadableDuration(simulatedResource.Lifetime())); + } + } +#endif + /// /// This exists to signal that we just ran the Analyze method. It's /// only run in one place, right before we create the EC subpanel @@ -653,8 +609,6 @@ internal static void Prefix_Add(ref string label, ref string value) [HarmonyPatch(typeof(KERBALISM.Planner.ResourceSimulator))] internal class PatchKerbalism_Planner_ResourceSimulator { - static bool Prepare() => KerbalismUtils.IsValidToPatch(new Version(3, 17, int.MaxValue, int.MaxValue), true); - public static bool JustRanAnalyze = false; [HarmonyPostfix] [HarmonyPatch("Analyze")] @@ -674,8 +628,6 @@ internal static void Postfix_Analyze() [HarmonyPatch(typeof(KERBALISM.Panel))] internal class PatchKerbalism_Panel { - static bool Prepare() => KerbalismUtils.IsValidToPatch(new Version(3, 17, int.MaxValue, int.MaxValue), true); - [HarmonyPrefix] [HarmonyPatch("AddContent")] internal static void Prefix_AddContent(string label, ref string value) @@ -705,8 +657,6 @@ internal static void Prefix_AddContent(string label, ref string value) [HarmonyPatch(typeof(KERBALISM.Planner.SimulatedResource))] internal class PatchKerbalism_Planner_SimulatedResource { - static bool Prepare() => KerbalismUtils.IsValidToPatch(new Version(3, 17, int.MaxValue, int.MaxValue), true); - public static bool IsEC = false; [HarmonyPrefix] @@ -733,8 +683,6 @@ internal static void Postfix_Tooltip() [HarmonyPatch(typeof(Telemetry))] internal class PatchKerbalism_Telemetry { - static bool Prepare() => KerbalismUtils.IsValidToPatch(new Version(3, 17, int.MaxValue, int.MaxValue), true); - public static bool IsRenderSupplies = false; public static bool IsEC = false; @@ -769,8 +717,6 @@ internal static void Postfix_Render_supplies() [HarmonyPatch(typeof(Lib))] internal class PatchKerbalism_Lib { - static bool Prepare() => KerbalismUtils.IsValidToPatch(new Version(3, 17, int.MaxValue, int.MaxValue), true); - private static string _ecName; private static bool _needName = true; @@ -811,50 +757,4 @@ internal static void Prefix_SpacesOnCaps(string s) } } #endregion - - [HarmonyPatch(typeof(ExperimentRequirements))] - internal class PatchKerbalism_ExperimentRequirements - { - // Don't even bother to patch if Principia isn't installed. - // Also, of course, don't patch if Kerbalism 3.18 is out with this fix inside it. - static bool Prepare() => KCTUtilities.IsPrincipiaInstalled && KerbalismUtils.IsValidToPatch(new Version(3, 17, int.MaxValue, int.MaxValue), true); - - private static double PrincipiaCorrectInclination(Orbit o) - { - if (KCTUtilities.IsPrincipiaInstalled && o.referenceBody != (FlightGlobals.currentMainBody ?? Planetarium.fetch.Home)) - { - Vector3d polarAxis = o.referenceBody.BodyFrame.Z; - - double hSqrMag = o.h.sqrMagnitude; - if (hSqrMag == 0d) - { - return Math.Acos(Vector3d.Dot(polarAxis, o.pos) / o.pos.magnitude) * (180.0 / Math.PI); - } - else - { - Vector3d orbitZ = o.h / Math.Sqrt(hSqrMag); - return Math.Atan2((orbitZ - polarAxis).magnitude, (orbitZ + polarAxis).magnitude) * (2d * (180.0 / Math.PI)); - } - } - else - { - return o.inclination; - } - } - - [HarmonyPrefix] - [HarmonyPatch("TestRequirements")] - internal static void Prefix_TestRequirements(Vessel v, out double __state) - { - __state = v.orbit.inclination; - v.orbit.inclination = PrincipiaCorrectInclination(v.orbit); - } - - [HarmonyPostfix] - [HarmonyPatch("TestRequirements")] - internal static void Postfix_TestRequirements(Vessel v, double __state) - { - v.orbit.inclination = __state; - } - } } \ No newline at end of file diff --git a/Source/RP0/Maintenance/MaintenanceHandler.cs b/Source/RP0/Maintenance/MaintenanceHandler.cs index 87e3d9e3995..a2e31553e01 100644 --- a/Source/RP0/Maintenance/MaintenanceHandler.cs +++ b/Source/RP0/Maintenance/MaintenanceHandler.cs @@ -24,7 +24,9 @@ public class MaintenanceHandler : ScenarioModule public static MaintenanceHandler Instance { get; private set; } = null; private bool _isFirstLoad = true; - + private static readonly Dictionary _facilityLevelCosts = new Dictionary(); + public static void ClearFacilityCosts() { _facilityLevelCosts.Clear(); } + public static EventVoid OnRP0MaintenanceChanged = new EventVoid("OnRP0MaintenanceChanged"); [KSPField(isPersistant = true)] @@ -46,6 +48,7 @@ public class MaintenanceHandler : ScenarioModule private bool _wasWarpingHigh = false; private int _frameCount = 0; + private bool _waitingForLevelLoad = false; #region Component costs @@ -170,6 +173,32 @@ public void Start() OnRP0MaintenanceChanged.Add(ScheduleMaintenanceUpdate); } + protected double SumCosts(float[] costs, int idx) + { + double s = 0d; + for (int i = idx + 1; i-- > 0;) + s += costs[i]; + + return s; + } + + protected double SumCosts(float[] costs, float fractionalIdx) + { + double s = 0d; + int i = (int)fractionalIdx; + if (i != fractionalIdx && i + 1 < costs.Length) + { + float fractionOverFullLvl = fractionalIdx - i; + float fractionCost = costs[i + 1] * fractionOverFullLvl; + s = fractionCost; + } + + for (; i >= 0; i--) + s += costs[i]; + + return s; + } + public void ScheduleMaintenanceUpdate() { nextUpdate = 0d; @@ -325,6 +354,8 @@ public void UpdateUpkeep() UpdateKCTSalaries(); + EnsureFacilityLvlCostsLoaded(); + LCsCostPerDay = 0d; foreach (var ksc in SpaceCenterManagement.Instance.KSCs) { @@ -337,14 +368,14 @@ public void UpdateUpkeep() if (Database.LockedFacilities.Contains(facility)) continue; - if (!Database.FacilityLevelCosts.TryGetValue(facility, out var facCosts)) + if (!_facilityLevelCosts.TryGetValue(facility, out float[] facCosts)) continue; - double cost = ComputeDailyMaintenanceCost(KCTUtilities.SumThrough(facCosts, KCTUtilities.GetFacilityLevel(facility))); + double cost = ComputeDailyMaintenanceCost(SumCosts(facCosts, KCTUtilities.GetFacilityLevel(facility))); double ratio = GetFacilityUpgradeRatio(facility); if (ratio > 0d) { - double newCost = ComputeDailyMaintenanceCost(KCTUtilities.SumThrough(facCosts, 1 + KCTUtilities.GetFacilityLevel(facility))); + double newCost = ComputeDailyMaintenanceCost(SumCosts(facCosts, 1 + KCTUtilities.GetFacilityLevel(facility))); cost = UtilMath.LerpUnclamped(cost, newCost, ratio); } FacilityMaintenanceCosts[facility] = cost; @@ -353,21 +384,24 @@ public void UpdateUpkeep() TrainingUpkeepPerDay = 0d; - if (CrewHandler.Instance?.TrainingCourses != null) + if (_facilityLevelCosts.TryGetValue(SpaceCenterFacility.AstronautComplex, out float[] costs)) { - foreach (var course in CrewHandler.Instance.TrainingCourses) + if (CrewHandler.Instance?.TrainingCourses != null) { - if (!course.Started) - continue; - - TrainingDatabase.FillBools(course.Target, Database.SettingsSC.nautUpkeepTrainings, Database.SettingsSC.nautUpkeepTrainingBools); - double trainingTypeCost = GetTrainingCostFromBools(); - Database.SettingsSC.ResetBools(); - TrainingUpkeepPerDay += course.Students.Count * - (Database.SettingsSC.nautTrainingCostPerFacLevel[KCTUtilities.GetFacilityLevel(SpaceCenterFacility.AstronautComplex)] - + trainingTypeCost * Database.SettingsSC.nautTrainingTypeCostMult); + foreach (var course in CrewHandler.Instance.TrainingCourses) + { + if (!course.Started) + continue; + + TrainingDatabase.FillBools(course.Target, Database.SettingsSC.nautUpkeepTrainings, Database.SettingsSC.nautUpkeepTrainingBools); + double trainingTypeCost = GetTrainingCostFromBools(); + Database.SettingsSC.ResetBools(); + TrainingUpkeepPerDay += course.Students.Count * + (Database.SettingsSC.nautTrainingCostPerFacLevel[KCTUtilities.GetFacilityLevel(SpaceCenterFacility.AstronautComplex)] + + trainingTypeCost * Database.SettingsSC.nautTrainingTypeCostMult); + } + TrainingUpkeepPerDay /= 365.25d; } - TrainingUpkeepPerDay /= 365.25d; } @@ -544,6 +578,29 @@ private void SettingsChanged() UpdateUpkeep(); } + private bool EnsureFacilityLvlCostsLoaded() + { + if(_waitingForLevelLoad) + return false; + + if (_facilityLevelCosts.Count == 0) + { + // Facility level upgrade costs should be loaded only once. These do not change and are actually unavailable + // when outside HomePlanet's SOI and also in the tracking station in some cases. + foreach (UpgradeableFacility facility in FindObjectsOfType()) + { + var costArr = new float[facility.UpgradeLevels.Length]; + for (int i = 0; i < facility.UpgradeLevels.Length; i++) + { + costArr[i] = facility.UpgradeLevels[i].levelCost; + } + _facilityLevelCosts[(SpaceCenterFacility)Enum.Parse(typeof(SpaceCenterFacility), facility.name)] = costArr; + } + RP0Debug.Log($"Updated facilityLevelsCosts, count: {_facilityLevelCosts.Count}"); + } + return true; + } + public double GetSubsidyAmount(double startUT, double endUT) { double delta = endUT - startUT; diff --git a/Source/RP0/Singletons/Database.cs b/Source/RP0/Singletons/Database.cs index 585562c2a3c..ac1ebd91310 100644 --- a/Source/RP0/Singletons/Database.cs +++ b/Source/RP0/Singletons/Database.cs @@ -42,8 +42,7 @@ public class Database : MonoBehaviour public static readonly PersistentDictionaryValueTypes NodeTypes = new PersistentDictionaryValueTypes(); public static readonly List LockedFacilities = new List(); public static readonly Dictionary> FacilityLevelCosts = new Dictionary>(); - public static int GetFacilityLevelCount(SpaceCenterFacility fac) { return FacilityLevelCosts.ValueOrDefault(fac)?.Count ?? 1; } - public static int GetFacilityLevelCount(string facilityID) { return Database.GetFacilityLevelCount(Database.FacilityIDToFacility.ValueOrDefault(facilityID)); } + public static int GetFacilityLevelCount(SpaceCenterFacility fac) { return FacilityLevelCosts.ValueOrDefault(fac)?.Count ?? 0; } public static readonly Dictionary FacilityIDToFacility = new Dictionary(); public static readonly Dictionary TechNameToTitle = new Dictionary(); public static readonly Dictionary> TechNameToParents = new Dictionary>(); diff --git a/Source/RP0/SpaceCenter/LaunchComplex/LCData.cs b/Source/RP0/SpaceCenter/LaunchComplex/LCData.cs index 7839d12e7ad..b4b60e671d3 100644 --- a/Source/RP0/SpaceCenter/LaunchComplex/LCData.cs +++ b/Source/RP0/SpaceCenter/LaunchComplex/LCData.cs @@ -14,30 +14,15 @@ public enum LaunchComplexType public class LCData { [Persistent] public string Name; - /// - /// Max vessel mass that the LC can support. - /// [Persistent] public float massMax; - /// - /// The mass that LC was originally built with. - /// [Persistent] public float massOrig; [Persistent] public Vector3 sizeMax; [Persistent] public LaunchComplexType lcType = LaunchComplexType.Pad; [Persistent] public bool isHumanRated; [Persistent] public PersistentDictionaryValueTypes resourcesHandled = new PersistentDictionaryValueTypes(); - /// - /// Max allowable mass that the LC can be upgraded to. - /// - public float MaxPossibleMass => Math.Max(3f, Mathf.Floor(massOrig * 2f)); - /// - /// Min allowable mass that the LC can be downgraded to. - /// - public float MinPossibleMass => Math.Max(1, Mathf.Ceil(massOrig * 0.5f)); - public bool IsMassWithinUpgradeMargin => massMax <= MaxPossibleMass; - public bool IsMassWithinDowngradeMargin => massMax >= MinPossibleMass; - public bool IsMassWithinUpAndDowngradeMargins => IsMassWithinUpgradeMargin && IsMassWithinDowngradeMargin; + public float MaxPossibleMass => Mathf.Floor(massOrig * 2f); + public float MinPossibleMass => Mathf.Ceil(massOrig * 0.5f); public static float CalcMassMin(float massMax) => massMax == float.MaxValue ? 0f : Mathf.Floor(massMax * 0.75f); public float MassMin => CalcMassMin(massMax); public static float CalcMassMaxFromMin(float massMin) => Mathf.Ceil(massMin / 0.75f); diff --git a/Source/RP0/SpaceCenter/LaunchComplex/LCEfficiency.cs b/Source/RP0/SpaceCenter/LaunchComplex/LCEfficiency.cs index 8c99a8e003c..2a0cb53b06d 100644 --- a/Source/RP0/SpaceCenter/LaunchComplex/LCEfficiency.cs +++ b/Source/RP0/SpaceCenter/LaunchComplex/LCEfficiency.cs @@ -262,10 +262,6 @@ public static LCEfficiency FindClosest(LCData data, out double bestCloseness) bestItem = e; } } - - if (bestCloseness < 1d && bestCloseness > 0.95d) - bestCloseness = 0.95d; - return bestItem; } diff --git a/Source/RP0/SpaceCenter/Projects/FacilityUpgradeProject.cs b/Source/RP0/SpaceCenter/Projects/FacilityUpgradeProject.cs index b4335314039..fe11b7792cb 100644 --- a/Source/RP0/SpaceCenter/Projects/FacilityUpgradeProject.cs +++ b/Source/RP0/SpaceCenter/Projects/FacilityUpgradeProject.cs @@ -66,7 +66,7 @@ public void Apply() facility.SetLevel(upgradeLevel); } - int newLvl = KCTUtilities.GetFacilityLevel(id); + int newLvl = KCTUtilities.GetBuildingUpgradeLevel(id); upgradeProcessed = newLvl == upgradeLevel; if (upgradeProcessed) { diff --git a/Source/RP0/SpaceCenter/Projects/VesselProject.cs b/Source/RP0/SpaceCenter/Projects/VesselProject.cs index 89e0ff28f51..72b98583356 100644 --- a/Source/RP0/SpaceCenter/Projects/VesselProject.cs +++ b/Source/RP0/SpaceCenter/Projects/VesselProject.cs @@ -597,7 +597,7 @@ public bool ResourcesOK(LCData stats, List failedReasons = null) return false; pass = false; - failedReasons.Add($"Insufficient {kvp.Key} at LC: {kvp.Value:N0} required, {lcAmount:N0} available. Modify {(stats.lcType == LaunchComplexType.Pad ? "LC" : "the Hangar")}."); + failedReasons.Add($"Insufficient {kvp.Key} at LC: {kvp.Value:N0} required, {lcAmount:N0} available. Renovate or Upgrade {(stats.lcType == LaunchComplexType.Pad ? "LC" : "the Hangar")}."); } return pass; diff --git a/Source/RP0/SpaceCenter/SpaceCenterManagement.cs b/Source/RP0/SpaceCenter/SpaceCenterManagement.cs index fba17c1a37a..5be36ca7cf6 100644 --- a/Source/RP0/SpaceCenter/SpaceCenterManagement.cs +++ b/Source/RP0/SpaceCenter/SpaceCenterManagement.cs @@ -1546,7 +1546,7 @@ private IEnumerator UpdateFacilityLevels() { if (ActiveSC.ActiveLC.ActiveLPInstance is LCLaunchPad pad) { - if (KCTUtilities.GetFacilityLevel(SpaceCenterFacility.LaunchPad) != pad.level) + if (KCTUtilities.GetBuildingUpgradeLevel(SpaceCenterFacility.LaunchPad) != pad.level) { ActiveSC.ActiveLC.SwitchLaunchPad(ActiveSC.ActiveLC.ActiveLaunchPadIndex, false); pad.UpdateLaunchpadDestructionState(false); diff --git a/Source/RP0/UI/KCT/GUI_Editor.cs b/Source/RP0/UI/KCT/GUI_Editor.cs index a1e0279e189..cad55bc3e1c 100644 --- a/Source/RP0/UI/KCT/GUI_Editor.cs +++ b/Source/RP0/UI/KCT/GUI_Editor.cs @@ -282,8 +282,8 @@ private static void RenderEditorLaunchComplexControls() // _centralWindowPosition.width = 300; // } //} - if (GUILayout.Button(new GUIContent("Modify", - $"Modify the {(activeLC.LCType == LaunchComplexType.Pad ? "launch complex" : "hangar")} to support the current vessel, keeping existing support where possible.{(canModify ? string.Empty : modifyFailTooltip)}"), + if (GUILayout.Button(new GUIContent("Upgrade", + $"Upgrade the {(activeLC.LCType == LaunchComplexType.Pad ? "launch complex" : "hangar")} to support the current vessel, keeping existing support where possible.{(canModify ? string.Empty : modifyFailTooltip)}"), canModify ? GUI.skin.button : _yellowButton)) { if (EditorLogic.fetch.ship.parts.Count == 0) diff --git a/Source/RP0/UI/KCT/GUI_FirstRun.cs b/Source/RP0/UI/KCT/GUI_FirstRun.cs index b7ca9b2a291..e6cff1992f2 100644 --- a/Source/RP0/UI/KCT/GUI_FirstRun.cs +++ b/Source/RP0/UI/KCT/GUI_FirstRun.cs @@ -62,7 +62,7 @@ public static void DrawFirstRun(int windowID) if (!SpaceCenterManagement.Instance.StarterLCBuilding) { GUILayout.Label($"{step++}) Build a starting Launch Complex."); - GUILayout.Label("With a contract accepted, now it's time to create and integrate a vessel to complete it. If it's a rocket, you'll need a launch complex to launch it. Go to the VAB and make your rocket, then click New the Integration Info (was KCT) window. The LC properties will be set to support that vessel. Once you have LCs built you can also modify them the same way."); + GUILayout.Label("With a contract accepted, now it's time to create and integrate a vessel to complete it. If it's a rocket, you'll need a launch complex to launch it. Go to the VAB and make your rocket, then click New the Integration Info (was KCT) window. The LC properties will be set to support that vessel. Once you have LCs built you can also modify them the same way, either a simple Upgrade or a bigger Reconstruction. Reconstructions remove support for any vessel but the current, but lead to lower maintenance over time."); if (GUILayout.Button($"Go to VAB", HighLogic.Skin.button)) { EnterVAB(); diff --git a/Source/RP0/UI/KCT/GUI_NewLC.cs b/Source/RP0/UI/KCT/GUI_NewLC.cs index a0d4e3ceb98..8b2e84433d4 100644 --- a/Source/RP0/UI/KCT/GUI_NewLC.cs +++ b/Source/RP0/UI/KCT/GUI_NewLC.cs @@ -303,43 +303,32 @@ public static void DrawNewLCWindow(int windowID) if (isModify) { - _newLCData.massOrig = isModify ? activeLC.MassOrig : 0; - int maxMax = (int)_newLCData.MaxPossibleMass; - int maxMin = (int)_newLCData.MinPossibleMass; GUILayout.BeginHorizontal(); - if (maxMax < _newLCData.massMax) - GUILayout.Label("Upgrade Limit for max tng:", GetLabelStyleYellow()); - else - GUILayout.Label("Upgrade Limit for max tng:"); - GUILayout.Label($"{maxMax:N0}", - maxMax < _newLCData.massMax ? GetLabelRightAlignStyleYellow() : GetLabelRightAlignStyle(), - GUILayout.ExpandWidth(false)); + GUILayout.Label("Upgrade Limit for max tng:"); + GUILayout.Label($"{(int)(_newLCData.massOrig * 2f):N0}", GetLabelRightAlignStyle(), GUILayout.ExpandWidth(false)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); - if (maxMin > _newLCData.massMax) - GUILayout.Label("Downgrade Limit for max tng:", GetLabelStyleYellow()); - else - GUILayout.Label("Downgrade Limit for max tng:"); - GUILayout.Label($"{maxMin:N0}", - maxMin > _newLCData.massMax ? GetLabelRightAlignStyleYellow() : GetLabelRightAlignStyle(), - GUILayout.ExpandWidth(false)); + GUILayout.Label("Downgrade Limit for max tng:"); + GUILayout.Label($"{Math.Max(1, (int)(_newLCData.massOrig * 0.5f)):N0}", GetLabelRightAlignStyle(), GUILayout.ExpandWidth(false)); GUILayout.EndHorizontal(); + + } else { _newLCData.massOrig = _newLCData.massMax; - int maxMax = (int)_newLCData.MaxPossibleMass; - int maxMin = (int)_newLCData.MinPossibleMass; + if (_newLCData.massOrig < 1.5f) + _newLCData.massOrig = 1.5f; GUILayout.BeginHorizontal(); GUILayout.Label("Upgrade Limit for max tng:"); - GUILayout.Label($"{_newLCData.MaxPossibleMass:N0}", GetLabelRightAlignStyle(), GUILayout.ExpandWidth(false)); + GUILayout.Label($"{Math.Max(3, _newLCData.massOrig * 2):N0}", GetLabelRightAlignStyle(), GUILayout.ExpandWidth(false)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Downgrade Limit for max tng:"); - GUILayout.Label($"{_newLCData.MinPossibleMass:N0}", GetLabelRightAlignStyle(), GUILayout.ExpandWidth(false)); + GUILayout.Label($"{Math.Max(1, _newLCData.massOrig / 2):N0}", GetLabelRightAlignStyle(), GUILayout.ExpandWidth(false)); GUILayout.EndHorizontal(); } } @@ -440,7 +429,7 @@ public static void DrawNewLCWindow(int windowID) double buildTime = ConstructionProject.CalculateBuildTime(totalCost, oldTotalCost, SpaceCenterFacility.LaunchPad, null); double buildCost = -CurrencyUtils.Funds(TransactionReasonsRP0.StructureConstructionLC, -totalCost); string sBuildTime = KSPUtil.PrintDateDelta(buildTime, includeTime: false); - string costString = isModify ? "Modify Cost:" : "Build Cost:"; + string costString = isModify ? "Renovate Cost:" : "Build Cost:"; GUILayout.BeginHorizontal(); GUILayout.Label(costString, GUILayout.ExpandWidth(false)); GUILayout.Label(new GUIContent($"√{buildCost:N0}", $"Daily: √{(buildCost * 86400d / buildTime):N1}"), GetLabelRightAlignStyle()); @@ -506,7 +495,7 @@ public static void DrawNewLCWindow(int windowID) GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); - if (GUILayout.Button(isModify ? "Modify" : "Build") && ValidateLCCreationParameters(_newLCData, isModify ? activeLC : null)) + if (GUILayout.Button(isModify ? "Renovate" : "Build") && ValidateLCCreationParameters(_newLCData.Name, _newLCData.GetPadFracLevel(), _newLCData.massMax, _newLCData.sizeMax, isModify ? activeLC : null)) { if (HighLogic.LoadedSceneIsEditor && !SpaceCenterManagement.Instance.EditorVessel.MeetsFacilityRequirements(_newLCData, null)) { @@ -792,34 +781,25 @@ private static bool ModifyFailure(out string failedVessels) return failedVessels != string.Empty; } - private static bool ValidateLCCreationParameters(LCData newLCData, LaunchComplex existingLC) + private static bool ValidateLCCreationParameters(string newName, float fractionalPadLvl, float tonnageLimit, Vector3 curPadSize, LaunchComplex lc) { - if (newLCData.sizeMax == Vector3.zero) + if (curPadSize == Vector3.zero) { ScreenMessages.PostScreenMessage("Please enter a valid size"); return false; } - if (existingLC != null && existingLC.LCType == LaunchComplexType.Hangar) + if (lc != null && lc.LCType == LaunchComplexType.Hangar) return true; - if (newLCData.GetPadFracLevel() == -1 || newLCData.massMax == 0) + if (fractionalPadLvl == -1 || tonnageLimit == 0 || (lc != null && (tonnageLimit < Math.Max(1, (int)lc.MassOrig / 2) || tonnageLimit > lc.MassOrig * 2))) { ScreenMessages.PostScreenMessage("Please enter a valid tonnage limit"); - RP0Debug.Log($"Invalid LC tonnage set, fractional: {newLCData.GetPadFracLevel()}, tonnageLimit {newLCData.massMax}"); + RP0Debug.Log($"Invalid LC tonnage set, fractional: {fractionalPadLvl}, tonnageLimit {tonnageLimit}, orig {(lc != null ? lc.MassOrig : -1f)}"); return false; } - if (existingLC != null && !newLCData.IsMassWithinUpAndDowngradeMargins) - { - string msg = !newLCData.IsMassWithinUpgradeMargin ? $"Cannot upgrade tonnage above the limit of {newLCData.MaxPossibleMass}t" - : $"Cannot downgrade tonnage below the limit of {newLCData.MinPossibleMass}t"; - ScreenMessages.PostScreenMessage(msg); - RP0Debug.Log($"LC tonnage exceeding upgrade margins, fractional: {newLCData.GetPadFracLevel()}, tonnageLimit {newLCData.massMax}, orig {(existingLC != null ? existingLC.MassOrig : -1f)}"); - return false; - } - - if (existingLC != null && !existingLC.CanModifyReal) + if (lc != null && !lc.CanModifyReal) { ScreenMessages.PostScreenMessage("Please wait for any reconditioning, rollout, rollback, or recovery to complete"); RP0Debug.Log($"Can't modify LC, recon_rollout in progress"); @@ -827,10 +807,10 @@ private static bool ValidateLCCreationParameters(LCData newLCData, LaunchComplex } // Don't bother with name if it's a modify. - if (existingLC != null) + if (lc != null) return true; - if (string.IsNullOrEmpty(newLCData.Name)) + if (string.IsNullOrEmpty(newName)) { ScreenMessages.PostScreenMessage("Enter a name for the new launch complex"); return false; @@ -839,7 +819,7 @@ private static bool ValidateLCCreationParameters(LCData newLCData, LaunchComplex for (int i = 0; i < SpaceCenterManagement.Instance.ActiveSC.LaunchComplexes.Count; i++) { var lp = SpaceCenterManagement.Instance.ActiveSC.LaunchComplexes[i]; - if (string.Equals(lp.Name, newLCData.Name, StringComparison.OrdinalIgnoreCase)) + if (string.Equals(lp.Name, newName, StringComparison.OrdinalIgnoreCase)) { ScreenMessages.PostScreenMessage("Another launch complex with the same name already exists"); return false; diff --git a/Source/RP0/UI/ProceduralAvionicsWindow.cs b/Source/RP0/UI/ProceduralAvionicsWindow.cs index 0affd56fa1d..2582326680b 100644 --- a/Source/RP0/UI/ProceduralAvionicsWindow.cs +++ b/Source/RP0/UI/ProceduralAvionicsWindow.cs @@ -171,7 +171,7 @@ private void WindowFunction(int windowID) if (float.TryParse(ControllableMass, out _newControlMass)) { float avionicsMass = _module.GetShieldedAvionicsMass(_newControlMass); - GUILayout.Label($" ({MathUtils.PrintMass(avionicsMass)})", HighLogic.Skin.label, GUILayout.Width(150)); + GUILayout.Label($" ({avionicsMass * 1000:0.#} kg)", HighLogic.Skin.label, GUILayout.Width(150)); } if (oldControlMass != _newControlMass) @@ -187,15 +187,12 @@ private void WindowFunction(int windowID) GUILayout.BeginHorizontal(GUILayout.Width(250)); GUILayout.Label("EC amount: ", HighLogic.Skin.label, GUILayout.Width(150)); _sECAmount = GUILayout.TextField(_sECAmount, HighLogic.Skin.textField); - GUILayout.Label("kJ", HighLogic.Skin.label); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(GUILayout.MaxWidth(50)); if (float.TryParse(_sECAmount, out float ecAmount)) { - float ekW = ModuleProceduralAvionics.GetEnabledkW(_module.CurrentProceduralAvionicsTechNode, _newControlMass); - float dkW = _module.CurrentProceduralAvionicsTechNode.disabledPowerFactor * ekW; - GUILayout.Label($" ({MathUtils.PrintMass(_ecTank.mass * ecAmount / _ecTank.utilization)}, {ModuleProceduralAvionics.BuildPowerString(ekW, dkW)})", HighLogic.Skin.label, GUILayout.Width(150)); + GUILayout.Label($" ({_ecTank.mass * ecAmount:0.#} kg)", HighLogic.Skin.label, GUILayout.Width(150)); } GUILayout.EndHorizontal(); GUILayout.EndHorizontal(); @@ -208,7 +205,7 @@ private void WindowFunction(int windowID) GUI.enabled = false; _sExtraVolume = GUILayout.TextField(_sExtraVolume, HighLogic.Skin.textField); GUI.enabled = true; - GUILayout.Label("L", HighLogic.Skin.label); + GUILayout.Label("l", HighLogic.Skin.label); GUILayout.EndHorizontal(); if (_showROTankSizeWarning) diff --git a/Source/RP0/Utilities/Formula.cs b/Source/RP0/Utilities/Formula.cs index 85b485a9c5c..13776f18f18 100644 --- a/Source/RP0/Utilities/Formula.cs +++ b/Source/RP0/Utilities/Formula.cs @@ -245,13 +245,13 @@ public static double ResourceTankCost(string res, double amount, bool isModify, /// public static double GetLCCloseness(LCData ourStats, LCData otherStats) { - if (ourStats.lcType == LaunchComplexType.Hangar) + if (ourStats.Compare(otherStats)) return 1d; if (otherStats.lcType != ourStats.lcType) return 0d; - if (ourStats.Compare(otherStats)) + if (ourStats.lcType == LaunchComplexType.Hangar) return 1d; LCData bigger, smaller; diff --git a/Source/RP0/Utilities/KCTUtilities.cs b/Source/RP0/Utilities/KCTUtilities.cs index b6a1974d71e..4cc3ff41da3 100644 --- a/Source/RP0/Utilities/KCTUtilities.cs +++ b/Source/RP0/Utilities/KCTUtilities.cs @@ -883,6 +883,46 @@ public static bool PartIsProcedural(Part part) return false; } + public static int GetBuildingUpgradeLevel(SpaceCenterFacility facility) + { + int lvl = GetBuildingUpgradeMaxLevel(facility); + if (HighLogic.CurrentGame.Mode == Game.Modes.CAREER) + { + lvl = (int)Math.Round(lvl * ScenarioUpgradeableFacilities.GetFacilityLevel(facility)); + } + return lvl; + } + + public static int GetBuildingUpgradeLevel(string facilityID) + { + int lvl = GetBuildingUpgradeMaxLevel(facilityID); + if (HighLogic.CurrentGame.Mode == Game.Modes.CAREER) + { + lvl = (int)Math.Round(lvl * ScenarioUpgradeableFacilities.GetFacilityLevel(facilityID)); + } + return lvl; + } + + public static int GetBuildingUpgradeMaxLevel(string facilityID) + { + int lvl = ScenarioUpgradeableFacilities.GetFacilityLevelCount(facilityID); + if (lvl < 0) + { + return Database.GetFacilityLevelCount(Database.FacilityIDToFacility.ValueOrDefault(facilityID)); + } + return lvl; + } + + public static int GetBuildingUpgradeMaxLevel(SpaceCenterFacility facility) + { + int lvl = ScenarioUpgradeableFacilities.GetFacilityLevelCount(facility); + if (lvl < 0) + { + return Database.GetFacilityLevelCount(facility); + } + return lvl; + } + public static bool RecoverActiveVesselToStorage(ProjectType listType) { try @@ -1566,25 +1606,22 @@ public static bool IsVesselKCTRecovering(ProtoVessel v) public static int GetFacilityLevel(SpaceCenterFacility facility) { - return GetIndexFromNorm(ScenarioUpgradeableFacilities.GetFacilityLevel(facility), Database.GetFacilityLevelCount(facility)); - } + if (ScenarioUpgradeableFacilities.facilityStrings.TryGetValue(facility, out string str)) + return GetFacilityLevel(str); - public static int GetFacilityLevel(string facility) - { - return GetIndexFromNorm(ScenarioUpgradeableFacilities.GetFacilityLevel(facility), Database.GetFacilityLevelCount(facility)); + return GetFacilityLevel(facility.ToString()); } - /// - /// Takes a normalized value and converts it to an array index - /// - /// - /// - /// - public static int GetIndexFromNorm(float norm, int levels) + public static int GetFacilityLevel(string facilityId) { - norm *= levels; - norm += 0.01f; - return (int)norm / levels; + facilityId = ScenarioUpgradeableFacilities.SlashSanitize(facilityId); + if (!ScenarioUpgradeableFacilities.protoUpgradeables.TryGetValue(facilityId, out var value)) + return 0; + + if (value.facilityRefs.Count < 1) + return 0; + + return value.facilityRefs[0].facilityLevel; } public static string ToCommaString(this List list) diff --git a/Source/RP0/Utilities/KSPUtils.cs b/Source/RP0/Utilities/KSPUtils.cs index b029b9f700e..36566cf6633 100644 --- a/Source/RP0/Utilities/KSPUtils.cs +++ b/Source/RP0/Utilities/KSPUtils.cs @@ -54,7 +54,7 @@ public static List GetAllLoadedTypes(bool instantiableOnly = true) /// optional (will use default if not specified and locking controls) /// optional: runs on dialog spawn /// optional: runs when dialog is destroyed - public static void PrePostActions(this PopupDialog dialog, ControlTypes lockType = ControlTypes.None, string lockName = null, Callback onCreateAction = null, Callback onDestroyAction = null) + public static void PrePostActions(this PopupDialog dialog, ControlTypes lockType = ControlTypes.None, string lockName = null, Action onCreateAction = null, Action onDestroyAction = null) { if (dialog == null) return; @@ -74,47 +74,12 @@ public static void PrePostActions(this PopupDialog dialog, ControlTypes lockType public class LockRemover : MonoBehaviour { private string _lockName; - private Callback _dismissAction; - private bool _dismissActionRun = false; + private Action _action; - public void Setup(string lockName, Callback dismissAction) + public void Setup(string lockName, Action action) { _lockName = lockName; - _dismissAction = dismissAction; - - // If the dialog is dismissed by a button, we need to run the - // postaction _before_ the button's own callback. This is because - // usually we are restoring UI elements, and the button's callback - // *also* probably tocuhes UI elements. So we need to restore state - // prior to the callback running. To do this, we combine the callbacks - // on all child buttons that dismiss on select. - if (_dismissAction != null && gameObject.GetComponent() is PopupDialog dlg && dlg.dialogToDisplay != null) - { - Callback cb = () => - { - if (!_dismissActionRun) - { - _dismissActionRun = true; - _dismissAction(); - } - }; - - foreach (var d in dlg.dialogToDisplay.Options) - CombineCallbackAndRecurse(d, cb); - } - } - - private void CombineCallbackAndRecurse(DialogGUIBase dlg, Callback cb) - { - if (dlg is DialogGUIButton b && b.DismissOnSelect) - { - if (b.onOptionSelected == null) - b.onOptionSelected = cb; - else - b.onOptionSelected = (Callback)Callback.Combine(cb, b.onOptionSelected); - } - foreach (var d in dlg.children) - CombineCallbackAndRecurse(d, cb); + _action = action; } public void OnDestroy() @@ -122,11 +87,8 @@ public void OnDestroy() if (_lockName != null) InputLockManager.RemoveControlLock(_lockName); - if (_dismissAction != null && !_dismissActionRun) - { - _dismissActionRun = true; - _dismissAction(); - } + if (_action != null) + _action(); } } diff --git a/Source/RP0/Utilities/KerbalismUtils.cs b/Source/RP0/Utilities/KerbalismUtils.cs index 4b0273c8627..63dab3643f4 100644 --- a/Source/RP0/Utilities/KerbalismUtils.cs +++ b/Source/RP0/Utilities/KerbalismUtils.cs @@ -1,47 +1,11 @@ -using System; -using System.Reflection; -using System.Linq; +using System.Collections.Generic; +using UnityEngine; using KERBALISM; namespace RP0 { public static class KerbalismUtils { - private static bool _needCheck = true; - private static Version _version = null; - private static Assembly _assembly = null; - - public static Assembly Assembly - { - get - { - Check(); - return _assembly; - } - } - - private static void Check() - { - if (_needCheck) - { - _needCheck = false; - _assembly = AssemblyLoader.loadedAssemblies.FirstOrDefault(a => a.name.StartsWith("Kerbalism", StringComparison.OrdinalIgnoreCase))?.assembly; - if (_assembly != null) - _version = new Version(_assembly.GetName().Version.ToString()); - RP0Debug.Log("Kerbalism version: " + (_version?.ToString() ?? "assembly not found"), true); - } - } - - public static bool IsValidToPatch(Version v, bool isMax) - { - Check(); - - if (_version == null) - return false; - - return isMax ? _version <= v : _version >= v; - } - public static ExperimentSituations ToExperimentSituations(this KERBALISM.ScienceSituation sit) { int sitInt = 1 << (int)ScienceSituationUtils.ToValidStockSituation(sit); diff --git a/Source/RP0/Utilities/MathUtils.cs b/Source/RP0/Utilities/MathUtils.cs index 50aa448529e..5f3d49c3338 100644 --- a/Source/RP0/Utilities/MathUtils.cs +++ b/Source/RP0/Utilities/MathUtils.cs @@ -3,7 +3,7 @@ using UnityEngine; // ReSharper disable once CheckNamespace -namespace RP0 +namespace KSPAPIExtensions { public static class MathUtils { @@ -350,15 +350,10 @@ public static string FormatMass(float mass, int sigFigs = 4, int exponent = 0) /// public static string FormatMass(double mass, int sigFigs = 4, int exponent = 0) { - return mass < 1.0d ? + return mass < 1.0f ? mass.ToStringSI(sigFigs, exponent + 6, "g") : mass.ToStringSI(sigFigs, exponent, "t"); } - - public static string PrintMass(double mass, int sigFigs = 3, bool longPrefix = false) - { - return mass < 1d ? KSPUtil.PrintSI(mass * 1000d * 1000d, longPrefix ? "grams" : "g", sigFigs, longPrefix) : KSPUtil.PrintSI(mass, longPrefix ? "tons" : "t", sigFigs, longPrefix); - } } /// diff --git a/Source/Tech Tree/Parts Browser/data/Near_Future_Electrical.json b/Source/Tech Tree/Parts Browser/data/Near_Future_Electrical.json index b457a491a61..8e9cb1dea4f 100644 --- a/Source/Tech Tree/Parts Browser/data/Near_Future_Electrical.json +++ b/Source/Tech Tree/Parts Browser/data/Near_Future_Electrical.json @@ -71,27 +71,6 @@ "Nuclear" ] }, - { - "name": "RO-reactor-prometheus", - "title": "Prometheus 200 KWe Nuclear Reactor", - "description": "", - "mod": "Near Future Electrical", - "cost": 24000, - "entry_cost": "0", - "category": "NUCLEAR", - "info": "Nuclear Reactor", - "year": "2016", - "technology": "modernNuclearPower", - "ro": true, - "orphan": false, - "rp0_conf": true, - "spacecraft": "JIMO", - "engine_config": "", - "upgrade": false, - "entry_cost_mods": "1000000,RO-reactor-snap50-300", - "identical_part_name": "", - "module_tags": [] - }, { "name": "RO-reactor-snap10a", "title": "NASA SNAP-10A Nuclear Reactor", @@ -116,36 +95,13 @@ "Nuclear" ] }, - { - "name": "RO-reactor-snap2", - "title": "NASA SNAP-2 Nuclear Reactor", - "description": "", - "mod": "Near Future Electrical", - "cost": 5000, - "entry_cost": "0", - "category": "NUCLEAR", - "info": "Nuclear Reactor", - "year": "1967", - "technology": "improvedRTG", - "ro": true, - "orphan": false, - "rp0_conf": true, - "spacecraft": "", - "engine_config": "", - "upgrade": false, - "entry_cost_mods": "10000,RO-reactor-snap10a,TurbineReactors", - "identical_part_name": "", - "module_tags": [ - "Nuclear" - ] - }, { "name": "RO-reactor-snap50", - "title": "NASA SNAP-50 35 kWe Nuclear Reactor", + "title": "NASA SNAP-50 Nuclear Reactor", "description": "", "mod": "Near Future Electrical", - "cost": 10000, - "entry_cost": "0", + "cost": 20000, + "entry_cost": 0, "category": "NUCLEAR", "info": "Nuclear Reactor", "year": "1975", @@ -163,52 +119,6 @@ "Nuclear" ] }, - { - "name": "RO-reactor-snap50-300", - "title": "NASA SNAP-50 300 kWe Nuclear Reactor", - "description": "", - "mod": "Near Future Electrical", - "cost": 20000, - "entry_cost": "0", - "category": "NUCLEAR", - "info": "Nuclear Reactor", - "year": "1976", - "technology": "multihundredWattRTG", - "ro": true, - "orphan": false, - "rp0_conf": true, - "spacecraft": "", - "engine_config": "", - "upgrade": false, - "entry_cost_mods": "200000,RO-reactor-snap50", - "identical_part_name": "", - "module_tags": [ - "Nuclear" - ] - }, - { - "name": "RO-reactor-snap8", - "title": "NASA SNAP-8 Nuclear Reactor", - "description": "", - "mod": "Near Future Electrical", - "cost": 5000, - "entry_cost": "0", - "category": "NUCLEAR", - "info": "Nuclear Reactor", - "year": "1971", - "technology": "improvedRTG", - "ro": true, - "orphan": false, - "rp0_conf": true, - "spacecraft": "", - "engine_config": "", - "upgrade": false, - "entry_cost_mods": "105000,RO-reactor-snap10a", - "identical_part_name": "", - "module_tags": [ - "Nuclear" - ] - }, { "name": "nuclear-recycler-25", "title": "Whirlijig Nuclear Reprocessor", @@ -315,7 +225,7 @@ "spacecraft": "", "engine_config": "", "upgrade": false, - "entry_cost_mods": "500000,RO-reactor-snap50-300", + "entry_cost_mods": "500000, RO-reactor-snap50", "identical_part_name": "", "module_tags": [ "Nuclear" @@ -363,7 +273,7 @@ "spacecraft": "", "engine_config": "", "upgrade": false, - "entry_cost_mods": "400000,RO-reactor-snap8", + "entry_cost_mods": "400000, RO-reactor-snap50", "identical_part_name": "", "module_tags": [ "Nuclear" @@ -398,8 +308,8 @@ "title": "NASA & DOE Advanced Sterling RG", "description": "A much lighter and more efficient radioisotope generator by using the sterling cycle.", "mod": "Near Future Electrical", - "cost": 3550, - "entry_cost": 0, + "cost": 20045, + "entry_cost": 200445, "category": "NUCLEAR", "info": "RTG", "year": "2015", @@ -412,10 +322,8 @@ "spacecraft": "", "engine_config": "", "upgrade": false, - "entry_cost_mods": "35156,RTGlevel6", + "entry_cost_mods": "100000,RTGlevel6", "identical_part_name": "", - "module_tags": [ - "NuclearRTG" - ] + "module_tags": [] } ] \ No newline at end of file diff --git a/Source/Tech Tree/Parts Browser/data/RN_Soviet_Rockets.json b/Source/Tech Tree/Parts Browser/data/RN_Soviet_Rockets.json index b369807cd2b..c32b2043133 100644 --- a/Source/Tech Tree/Parts Browser/data/RN_Soviet_Rockets.json +++ b/Source/Tech Tree/Parts Browser/data/RN_Soviet_Rockets.json @@ -86,8 +86,8 @@ "spacecraft": "APAS-75 (ASTP)", "engine_config": "", "upgrade": false, - "entry_cost_mods": "5000,dockingAndro", - "identical_part_name": "APAS-75", + "entry_cost_mods": "dockingAndro", + "identical_part_name": "", "module_tags": [] }, { diff --git a/Source/Tech Tree/Parts Browser/data/ROCapsules.json b/Source/Tech Tree/Parts Browser/data/ROCapsules.json index 212e2a58b95..7df24777d44 100644 --- a/Source/Tech Tree/Parts Browser/data/ROCapsules.json +++ b/Source/Tech Tree/Parts Browser/data/ROCapsules.json @@ -1,7 +1,7 @@ [ { "name": "ROC-APAS8995A", - "title": "APAS 89/95 Active Docking Port (Deprecated)", + "title": "APAS 89/95 Active Docking Port", "description": "", "mod": "ROCapsules", "cost": 3500, @@ -21,30 +21,9 @@ "identical_part_name": "APAS-89/95", "module_tags": [] }, - { - "name": "ROC-APAS8995Av2", - "title": "APAS 89/95 Active Docking Port", - "description": "", - "mod": "ROCapsules", - "cost": "3500", - "entry_cost": "0", - "category": "RCS", - "info": "Docking", - "year": "1989", - "technology": "standardDockingPorts", - "ro": true, - "orphan": false, - "rp0_conf": true, - "spacecraft": "", - "engine_config": "", - "upgrade": false, - "entry_cost_mods": "APAS8995Dock", - "identical_part_name": "APAS-89/95", - "module_tags": [] - }, { "name": "ROC-APAS8995P", - "title": "APAS 89/95 Passive Docking Port (Deprecated)", + "title": "APAS 89/95 Passive Docking Port", "description": "", "mod": "ROCapsules", "cost": 3000, @@ -60,28 +39,7 @@ "spacecraft": "Shuttle", "engine_config": "", "upgrade": false, - "entry_cost_mods": "APAS8995Dock", - "identical_part_name": "APAS-89/95", - "module_tags": [] - }, - { - "name": "ROC-APAS8995Pv2", - "title": "APAS 89/95 Passive Docking Port", - "description": "", - "mod": "ROCapsules", - "cost": "3000", - "entry_cost": "0", - "category": "RCS", - "info": "Docking", - "year": "1989", - "technology": "standardDockingPorts", - "ro": true, - "orphan": false, - "rp0_conf": true, - "spacecraft": "", - "engine_config": "", - "upgrade": false, - "entry_cost_mods": "APAS8995Dock", + "entry_cost_mods": "ROC-APAS8995A", "identical_part_name": "APAS-89/95", "module_tags": [] }, @@ -147,8 +105,8 @@ "spacecraft": "", "engine_config": "", "upgrade": false, - "entry_cost_mods": "rn_apas75", - "identical_part_name": "APAS-75", + "entry_cost_mods": "5000,dockingAndro", + "identical_part_name": "", "module_tags": [] }, { @@ -219,48 +177,6 @@ "Instruments" ] }, - { - "name": "ROC-ApolloCADSActive", - "title": "Apollo Block IV CADS Active Docking Port", - "description": "", - "mod": "ROCapsules", - "cost": "3500", - "entry_cost": "0", - "category": "RCS", - "info": "Docking", - "year": "1988", - "technology": "standardDockingPorts", - "ro": true, - "orphan": false, - "rp0_conf": true, - "spacecraft": "", - "engine_config": "", - "upgrade": false, - "entry_cost_mods": "APAS8995Dock", - "identical_part_name": "CADS", - "module_tags": [] - }, - { - "name": "ROC-ApolloCADSPassive", - "title": "Apollo Block IV CADS Passive Docking Port", - "description": "", - "mod": "ROCapsules", - "cost": "3000", - "entry_cost": "0", - "category": "RCS", - "info": "Docking", - "year": "1988", - "technology": "standardDockingPorts", - "ro": true, - "orphan": false, - "rp0_conf": true, - "spacecraft": "", - "engine_config": "", - "upgrade": false, - "entry_cost_mods": "APAS8995Dock", - "identical_part_name": "CADS", - "module_tags": [] - }, { "name": "ROC-ApolloCM", "title": "Apollo Command Module (CM)", diff --git a/Source/Tech Tree/Parts Browser/data/Universal_Storage_2.json b/Source/Tech Tree/Parts Browser/data/Universal_Storage_2.json index 9b0d5232ab7..9cfade777c7 100644 --- a/Source/Tech Tree/Parts Browser/data/Universal_Storage_2.json +++ b/Source/Tech Tree/Parts Browser/data/Universal_Storage_2.json @@ -793,9 +793,7 @@ "upgrade": false, "entry_cost_mods": "RO-MMRTG", "identical_part_name": "", - "module_tags": [ - "NuclearRTG" - ] + "module_tags": [] }, { "name": "USRadialTanks", From 7fcc9b75aaffb64c26142af0c2afc80376ab1bc0 Mon Sep 17 00:00:00 2001 From: Ballatik <67292986+Ballatik@users.noreply.github.com> Date: Sun, 5 Nov 2023 07:36:01 -0500 Subject: [PATCH 13/27] Revert "Revert "Merge remote-tracking branch 'upstream/master'"" This reverts commit 83a424c727e14c33e4740e019437d0b1d5699029. --- .../Lunar Crewed/CrewedLunarFlyby.cfg | 4 +- .../Lunar Crewed/CrewedLunarOrbitRepeat.cfg | 184 ++++++ .../Lunar Crewed/CrewedMoonLandingRover.cfg | 20 + .../CrewedMoonLandingTargeted.cfg | 22 +- .../Lunar Crewed/FirstCrewedLunarOrbit.cfg | 3 +- .../Lunar Crewed/FirstMoonLandingCrewed.cfg | 13 +- .../FirstMoonLandingCrewedDirect.cfg | 13 +- .../X-Plane Research/BreakSoundBarrier.cfg | 2 +- .../CrewedLunarOrbitRepeat.cfg.DISABLED | 157 ----- ...gleCrewedLunarOrbitRepeatable.cfg.DISABLED | 118 ---- GameData/RP-1/CrewTrainingTimes.cfg | 12 + GameData/RP-1/Localization/en-us.cfg | 2 +- GameData/RP-1/Plugins/RP0InstallChecker.dll | Bin 9728 -> 10240 bytes GameData/RP-1/Programs/Programs.cfg | 13 +- GameData/RP-1/RP-1.version | 6 +- .../RP-1/Science/Experiments/CrewReport.cfg | 2 +- .../CrewScience/BasicCapsuleExperiments.cfg | 8 +- .../CrewScience/CockpitExperiments.cfg | 8 +- .../CrewScience/MatureCapsuleExperiments.cfg | 10 +- .../CrewScience/SecondGenExperiments.cfg | 18 +- GameData/RP-1/Science/ScienceLabs.cfg | 36 +- GameData/RP-1/Strategies/Milestones.cfg | 2 +- GameData/RP-1/Tree/ECM-Parts.cfg | 20 +- GameData/RP-1/Tree/EntryCostModifiers.cfg | 16 +- GameData/RP-1/Tree/TREE-Parts.cfg | 83 ++- GameData/RP-1/Tree/identicalParts.cfg | 16 +- GameData/RP-1/changelog.cfg | 54 ++ README.md | 2 +- Source/GameData.csproj | 3 + Source/InstallChecker/InstallChecker.cs | 23 +- Source/RP0/Avionics/ModuleAvionics.cs | 2 +- .../RP0/Avionics/ModuleProceduralAvionics.cs | 25 +- Source/RP0/Harmony/CustomBarnKit.cs | 1 - Source/RP0/Harmony/KSPWheel.cs | 8 + Source/RP0/Harmony/KerbalismPatcher.cs | 564 +++++++++++------- Source/RP0/Maintenance/MaintenanceHandler.cs | 89 +-- Source/RP0/Singletons/Database.cs | 3 +- .../RP0/SpaceCenter/LaunchComplex/LCData.cs | 19 +- .../SpaceCenter/LaunchComplex/LCEfficiency.cs | 4 + .../Projects/FacilityUpgradeProject.cs | 2 +- .../RP0/SpaceCenter/Projects/VesselProject.cs | 2 +- .../RP0/SpaceCenter/SpaceCenterManagement.cs | 2 +- Source/RP0/UI/KCT/GUI_Editor.cs | 4 +- Source/RP0/UI/KCT/GUI_FirstRun.cs | 2 +- Source/RP0/UI/KCT/GUI_NewLC.cs | 62 +- Source/RP0/UI/ProceduralAvionicsWindow.cs | 9 +- Source/RP0/Utilities/Formula.cs | 4 +- Source/RP0/Utilities/KCTUtilities.cs | 67 +-- Source/RP0/Utilities/KSPUtils.cs | 50 +- Source/RP0/Utilities/KerbalismUtils.cs | 40 +- Source/RP0/Utilities/MathUtils.cs | 9 +- .../data/Near_Future_Electrical.json | 110 +++- .../Parts Browser/data/RN_Soviet_Rockets.json | 4 +- .../Parts Browser/data/ROCapsules.json | 94 ++- .../data/Universal_Storage_2.json | 4 +- 55 files changed, 1257 insertions(+), 793 deletions(-) create mode 100644 GameData/RP-1/Contracts/Lunar Crewed/CrewedLunarOrbitRepeat.cfg delete mode 100644 GameData/RP-1/Contracts/Z Disabled Contracts/CrewedLunarOrbitRepeat.cfg.DISABLED delete mode 100644 GameData/RP-1/Contracts/Z Disabled Contracts/SingleCrewedLunarOrbitRepeatable.cfg.DISABLED diff --git a/GameData/RP-1/Contracts/Lunar Crewed/CrewedLunarFlyby.cfg b/GameData/RP-1/Contracts/Lunar Crewed/CrewedLunarFlyby.cfg index b488a37405b..6e7f5e0dce0 100644 --- a/GameData/RP-1/Contracts/Lunar Crewed/CrewedLunarFlyby.cfg +++ b/GameData/RP-1/Contracts/Lunar Crewed/CrewedLunarFlyby.cfg @@ -5,6 +5,8 @@ CONTRACT_TYPE group = CrewedLunar agent = Federation Aeronautique Internationale + tag = CrewedLunarOrbitRequired + description = Program: Crewed Lunar Exploration
Type: Required


Design, build, and launch a crewed spacecraft into lunar space (with a periselene under 5000 km) and return safely to Earth. synopsis = Launch a crewed ship to flyby the Moon @@ -34,8 +36,6 @@ CONTRACT_TYPE rewardReputation = 300 // was 300 failureReputation = 0 // was @rewardReputation // was 300 - - // ************ REQUIREMENTS ************ REQUIREMENT diff --git a/GameData/RP-1/Contracts/Lunar Crewed/CrewedLunarOrbitRepeat.cfg b/GameData/RP-1/Contracts/Lunar Crewed/CrewedLunarOrbitRepeat.cfg new file mode 100644 index 00000000000..ea4ed714aae --- /dev/null +++ b/GameData/RP-1/Contracts/Lunar Crewed/CrewedLunarOrbitRepeat.cfg @@ -0,0 +1,184 @@ +CONTRACT_TYPE +{ + name = CrewedLunarOrbitRepeat + title = Crewed Lunar Orbit + group = CrewedLunar + + tag = CrewedLunarOrbitOptional + + description = Program: Crewed Lunar Exploration
Type: Optional


Launch a crewed spacecraft into lunar orbit for a routine mission of the specified duration and return safely to Earth.&br;&br;Number of Contracts Completed: @index / 2 + + synopsis = Fly a Crewed Lunar Orbital mission + + completedMessage = Crew alive and well after the mission--congratulations! + + sortKey = 709 + + cancellable = true + declinable = true + autoAccept = false + minExpiry = 0 + maxExpiry = 0 + maxCompletions = 2 + maxSimultaneous = 1 + deadline = 0 + + targetBody = Moon + + + // ************ REWARDS ************ + prestige = Trivial // 1.0x + advanceFunds = 0 + rewardScience = 0 + rewardFunds = 0 + failureFunds = 0 + rewardReputation = 500 + failureReputation = 0 + + // ************ REQUIREMENTS ************ + + REQUIREMENT + { + name = ProgramActive + type = ProgramActive + program = CrewedLunar + } + + REQUIREMENT + { + name = CompleteContract + type = CompleteContract + contractType = FirstCrewedLunarOrbit + title = Complete 'First Crewed Lunar Orbit' contract + } + + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + tag = CrewedLunarOrbitOptional + invertRequirement = true + title = Don't have another active optional Crewed Lunar Exploration contract. + } + + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + tag = CrewedLunarOrbitRequired + invertRequirement = true + title = Don't have active required Crewed Lunar Exploration contract. + } + + // ************ DATA BLOCKS ************ + + DATA + { + type = List + durations = [ 36h, 72h ] + } + + DATA + { + type = Duration + Duration = @durations.ElementAt(@index) + title = Duration of Mission + } + + DATA + { + type = int + startPeA = 30000 + title = First Periselene + } + + DATA + { + type = int + startApA = 75000 + Round(Random(0, 225000), 25000) + title = First Aposelene + } + + DATA + { + type = int + index = $HSFOrbitalMoonGenRepeatable_Count + 0 + } + + BEHAVIOUR + { + name = IncrementTheCount + type = Expression + + CONTRACT_COMPLETED_SUCCESS + { + HSFOrbitalMoonGenRepeatable_Count = $HSFOrbitalMoonGenRepeatable_Count + 1 + } + } + + // ************ PARAMETERS ************ + + PARAMETER + { + name = VesselGroup + type = VesselParameterGroup + title = Crewed Orbit of @targetBody + + PARAMETER + { + name = NewVessel + type = NewVessel + title = Launch a New Vessel + hideChildren = true + } + + PARAMETER + { + name = HasCrew + type = HasCrew + minCrew = 1 + crewOnly = true + title = Have at least 1 crewmember on board + hideChildren = true + } + + PARAMETER + { + name = OrbitWrapper + title = Stay in specified orbit for the duration + type = All + disableOnStateChange = true + completeInSequence = true + + PARAMETER + { + name = MoonOrbit + type = Orbit + situation = ORBITING + minPeA = @/startPeA + maxApA = @/startApA + targetBody = Moon + title = Reach Orbit of the Moon within the provided parameters + } + + PARAMETER + { + name = Duration + type = Duration + duration = @/Duration + preWaitText = Reach specified orbit + waitingText = Orbiting... + completionText = Orbits are complete, you may return to Earth when ready + } + } + + PARAMETER + { + name = ReturnHome + type = RP1ReturnHome + title = Return Home Safely + hideChildren = true + completeInSequence = true + } + } +} diff --git a/GameData/RP-1/Contracts/Lunar Crewed/CrewedMoonLandingRover.cfg b/GameData/RP-1/Contracts/Lunar Crewed/CrewedMoonLandingRover.cfg index b416e4bbf7f..ecbf0003c87 100644 --- a/GameData/RP-1/Contracts/Lunar Crewed/CrewedMoonLandingRover.cfg +++ b/GameData/RP-1/Contracts/Lunar Crewed/CrewedMoonLandingRover.cfg @@ -4,6 +4,8 @@ CONTRACT_TYPE title = Crewed Moon Landing & Rover Exploration group = CrewedLunar + tag = CrewedLunarOrbitOptional + description = Program: Crewed Lunar Exploration
Type: Optional


Design and launch a spacecraft with at least one crew member to land on the Moon. This will be a targeted landing near a randomly generated waypoint. We will also require you to take a crewed rover to explore an additional two waypoints. Once you have explored the waypoints, return safely to Earth.&br;&br;Number of Contracts Completed: @index / @maxCompletions genericDescription = Land crew on the Moon and explore with a rover. @@ -52,6 +54,24 @@ CONTRACT_TYPE contractType = RepeatMoonLandingCrew } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + tag = CrewedLunarOrbitOptional + invertRequirement = true + title = Don't have an active optional Crewed Lunar Exploration contract. + } + + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + tag = CrewedLunarOrbitRequired + invertRequirement = true + title = Don't have active required Crewed Lunar Exploration contract. + } + DATA { type = double diff --git a/GameData/RP-1/Contracts/Lunar Crewed/CrewedMoonLandingTargeted.cfg b/GameData/RP-1/Contracts/Lunar Crewed/CrewedMoonLandingTargeted.cfg index cfd6f7d1391..ea55911c21e 100644 --- a/GameData/RP-1/Contracts/Lunar Crewed/CrewedMoonLandingTargeted.cfg +++ b/GameData/RP-1/Contracts/Lunar Crewed/CrewedMoonLandingTargeted.cfg @@ -4,8 +4,10 @@ CONTRACT_TYPE title = Crewed Targeted Moon Landing group = CrewedLunar + tag = CrewedLunarOrbitRequired + description = Program: Crewed Lunar Exploration
Type: CAPSTONE


Design and launch a spacecraft with at least one crew member to land at a specific location on the Moon. Explore the area for at least @/LandDur and then return safely to Earth.&br;&br;Number of Contracts Completed: @index / @maxCompletions - + genericDescription = Launch a crewed single-person spacecraft and land it on a specific lunar biome. Explore the area for the specified amount of time and then return safely to Earth. synopsis = Land a crew on a specific biome on the Moon and return safely to Earth @@ -31,8 +33,8 @@ CONTRACT_TYPE rewardScience = 0 rewardFunds = 0 failureFunds = 0 - rewardReputation = 1000+(250 * @/index) // was 200.0 * (2.75+(double(@/LandDur)/172800)) - failureReputation = 0 // was @rewardReputation // was 200.0 * (2.75+(double(@/LandDur)/172800)) + rewardReputation = 1000+(250 * @/index) + failureReputation = 0 @@ -51,12 +53,21 @@ CONTRACT_TYPE type = CompleteContract contractType = first_MoonLandingCrewed } + + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + tag = CrewedLunarOrbitOptional + invertRequirement = true + title = Don't have an active optional Crewed Lunar Exploration contract. + } DATA { type = Duration LandDur = @specifiedTime.ElementAt(@index) - title= Duration + title = Duration } DATA @@ -105,7 +116,8 @@ CONTRACT_TYPE type = int index = $RepeatMoonLandingCrew_Count + 0 } - DATA + + DATA { type = List specifiedTime = [ 48h, 72h ] diff --git a/GameData/RP-1/Contracts/Lunar Crewed/FirstCrewedLunarOrbit.cfg b/GameData/RP-1/Contracts/Lunar Crewed/FirstCrewedLunarOrbit.cfg index e8de2368d3e..e4f8a4d0879 100644 --- a/GameData/RP-1/Contracts/Lunar Crewed/FirstCrewedLunarOrbit.cfg +++ b/GameData/RP-1/Contracts/Lunar Crewed/FirstCrewedLunarOrbit.cfg @@ -4,6 +4,7 @@ CONTRACT_TYPE title = First Crewed Lunar Orbit group = CrewedLunar + tag = CrewedLunarOrbitRequired description = Program: Crewed Lunar Exploration
Type: Required


Design and launch a spacecraft with at least one crew member to orbit close to the Moon for at least 20 hours and return safely to Earth. Historically, Apollo 8 was the first to do this, flying to the Moon over Christmas, 1968. @@ -61,7 +62,7 @@ CONTRACT_TYPE PARAMETER { - name = TwoCrew + name = HasCrew type = HasCrew minCrew = 1 crewOnly = true diff --git a/GameData/RP-1/Contracts/Lunar Crewed/FirstMoonLandingCrewed.cfg b/GameData/RP-1/Contracts/Lunar Crewed/FirstMoonLandingCrewed.cfg index 8ebaaffcfb1..3bd0f10c17a 100644 --- a/GameData/RP-1/Contracts/Lunar Crewed/FirstMoonLandingCrewed.cfg +++ b/GameData/RP-1/Contracts/Lunar Crewed/FirstMoonLandingCrewed.cfg @@ -5,7 +5,9 @@ CONTRACT_TYPE group = CrewedLunar agent = Federation Aeronautique Internationale - description = Program: Crewed Lunar Exploration
Type: Required


We are ready to finally put Humans on the surface of the Moon! Good luck to you in your design and execution of this complex mission!&br;&br;You must put at least one Human on the Moon and return them safely to the Earth.&br;&br;NOTE: The contract asks you to plant a flag on the Moon. Be sure that you have updated your Astronaut Complex to level three to unlock that ability. + tag = CrewedLunarOrbitRequired + + description = Program: Crewed Lunar Exploration
Type: Required


We are ready to finally put Humans on the surface of the Moon! Good luck to you in your design and execution of this complex mission!&br;&br;You must put at least one Human on the Moon and return them safely to the Earth.&br;&br;NOTE: The contract asks you to plant a flag on the Moon. Be sure that you have updated your Astronaut Complex to level five to unlock that ability. synopsis = Land a crew on the Moon and Return them safely to Earth @@ -74,6 +76,15 @@ CONTRACT_TYPE contractType = first_MoonLandingCrewedDirect invertRequirement = true } + + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + tag = CrewedLunarOrbitOptional + invertRequirement = true + title = Don't have an active optional Crewed Lunar Exploration contract. + } PARAMETER { diff --git a/GameData/RP-1/Contracts/Lunar Crewed/FirstMoonLandingCrewedDirect.cfg b/GameData/RP-1/Contracts/Lunar Crewed/FirstMoonLandingCrewedDirect.cfg index 49cf72e9504..dc3b2c8f04d 100644 --- a/GameData/RP-1/Contracts/Lunar Crewed/FirstMoonLandingCrewedDirect.cfg +++ b/GameData/RP-1/Contracts/Lunar Crewed/FirstMoonLandingCrewedDirect.cfg @@ -5,7 +5,9 @@ CONTRACT_TYPE group = CrewedLunar agent = Federation Aeronautique Internationale - description = Program: Crewed Lunar Exploration
Type: Required


We are ready to finally put Humans on the surface of the Moon! Good luck to you in your design and execution of this complex mission!&br;&br;You must put at least one Human on the Moon and return them safely to the Earth. You may not perform any dockings or this contract will fail. &br;&br;NOTE: The contract asks you to plant a flag on the Moon. Be sure that you have updated your Astronaut Complex to level three to unlock that ability. + tag = CrewedLunarOrbitRequired + + description = Program: Crewed Lunar Exploration
Type: Required


We are ready to finally put Humans on the surface of the Moon! Good luck to you in your design and execution of this complex mission!&br;&br;You must put at least one Human on the Moon and return them safely to the Earth. You may not perform any dockings or this contract will fail. &br;&br;NOTE: The contract asks you to plant a flag on the Moon. Be sure that you have updated your Astronaut Complex to level five to unlock that ability. synopsis = Land a crew on the Moon and Return them safely to Earth @@ -67,6 +69,15 @@ CONTRACT_TYPE contractType = first_MoonLandingCrewed invertRequirement = true } + + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + tag = CrewedLunarOrbitOptional + invertRequirement = true + title = Don't have an active optional Crewed Lunar Exploration contract. + } PARAMETER { diff --git a/GameData/RP-1/Contracts/X-Plane Research/BreakSoundBarrier.cfg b/GameData/RP-1/Contracts/X-Plane Research/BreakSoundBarrier.cfg index df652f3d1b4..2d7415bb2cf 100644 --- a/GameData/RP-1/Contracts/X-Plane Research/BreakSoundBarrier.cfg +++ b/GameData/RP-1/Contracts/X-Plane Research/BreakSoundBarrier.cfg @@ -45,7 +45,7 @@ CONTRACT_TYPE PARAMETER { - name = VesselGroup + name = BSBVesselGroup type = VesselParameterGroup title = Break the sound barrier define = SoundBarrier diff --git a/GameData/RP-1/Contracts/Z Disabled Contracts/CrewedLunarOrbitRepeat.cfg.DISABLED b/GameData/RP-1/Contracts/Z Disabled Contracts/CrewedLunarOrbitRepeat.cfg.DISABLED deleted file mode 100644 index 356b3924458..00000000000 --- a/GameData/RP-1/Contracts/Z Disabled Contracts/CrewedLunarOrbitRepeat.cfg.DISABLED +++ /dev/null @@ -1,157 +0,0 @@ -CONTRACT_TYPE -{ - name = CrewedLunarOrbitRepeat - title = Crewed Lunar Orbit with @/crewNum - genericTitle = Crewed Lunar Orbital - group = MoonExploration - - - description = Launch a spacecraft with at least @/crewNum aboard into lunar orbit for a routine mission of the specified duration and return safely to Earth.&br;&br;Number of Contracts Completed: @index / unlimited - genericDescription = Launch a spacecraft with at least the required number of crew aboard into lunar orbit for a routine mission of the specified duration and return safely to Earth. - - synopsis = Fly a Crewed Lunar Orbital mission with @/crewNum crew - - completedMessage = Crew alive and well after the mission--congratulations! - - sortKey = 709 - - cancellable = true - declinable = true - autoAccept = false - minExpiry = 0 - maxExpiry = 0 - maxCompletions = 0 - maxSimultaneous = 1 - deadline = 365 * RP1DeadlineMult() // 1 year - - targetBody = Moon - - - // ************ REWARDS ************ - prestige = Significant // 1.25x - advanceFunds = 0.625 * (50000 + @/crewNum * 20000) * @RP0:globalHardContractMultiplier - rewardScience = 0 - rewardReputation = 100 + @/crewNum * 30 - rewardFunds = @advanceFunds - failureReputation = @rewardReputation * 1.5 - failureFunds = @advanceFunds * 0.5 - - // ************ REQUIREMENTS ************ - - REQUIREMENT - { - name = CompleteContract - type = CompleteContract - contractType = SingleCrewedLunarOrbitRepeatable - minCount = 2 - title = Complete 'Single Crewed Lunar Orbit' contract at least @minCount times - } - - // ************ DATA BLOCKS ************ - - DATA - { - type = int - crewNum = 1 + Round(Random(1, 2), 1) - title = Number of crew for mission - } - DATA - { - type = Duration - //Duration = Round (Random(1d, 3d), 1h) - Duration = Random(1d, 3d) - //Duration = Round ( @randDuration, 1h ) - title = Duration of Mission - } - DATA - { - type = int - startPeA = 30000 + Round(Random(0, 55000), 10000) - title = First Periselene - } - DATA - { - type = int - startApA = 100000 + Round(Random(0, 200000), 25000) - title = First Aposelene - } - DATA - { - type = double - Inclination = Round(Random(0, 180), 5) - title = Inclination to use for orbits - } - - DATA - { - type = int - index = $HSFOrbitalMoonGenRepeatable_Count + 0 - } - - BEHAVIOUR - { - name = IncrementTheCount - type = Expression - - CONTRACT_COMPLETED_SUCCESS - { - HSFOrbitalMoonGenRepeatable_Count = $HSFOrbitalMoonGenRepeatable_Count + 1 - } - } - - // ************ PARAMETERS ************ - - PARAMETER - { - name = VesselGroup - type = VesselParameterGroup - title = Crewed Orbit of @targetBody - - PARAMETER - { - name = NewVessel - type = NewVessel - title = Launch a New Vessel - hideChildren = true - } - PARAMETER - { - name = TwoCrew - type = HasCrew - minCrew = @/crewNum - maxCrew = 99 - } - PARAMETER - { - name = MoonOrbit - type = Orbit - situation = ORBITING - minPeA = @/startPeA - maxApA = @/startApA - minInclination = Min(Max(0, @/Inclination - 10), 180) - maxInclination = Min(Max(0, @/Inclination + 10), 180) - targetBody = Moon - disableOnStateChange = true - title = Reach Orbit of the Moon within the provided parameters - PARAMETER - { - name = Duration - type = Duration - - duration = @/Duration - - preWaitText = Reach Specified Orbit - waitingText = Orbiting... - completionText = Orbits are complete, you may return to Earth when ready - } - } - PARAMETER - { - name = ReturnHome - type = RP1ReturnHome - title = Return Home Safely - hideChildren = true - completeInSequence = true - } - } -} diff --git a/GameData/RP-1/Contracts/Z Disabled Contracts/SingleCrewedLunarOrbitRepeatable.cfg.DISABLED b/GameData/RP-1/Contracts/Z Disabled Contracts/SingleCrewedLunarOrbitRepeatable.cfg.DISABLED deleted file mode 100644 index 088a05bb72b..00000000000 --- a/GameData/RP-1/Contracts/Z Disabled Contracts/SingleCrewedLunarOrbitRepeatable.cfg.DISABLED +++ /dev/null @@ -1,118 +0,0 @@ -CONTRACT_TYPE -{ - name = SingleCrewedLunarOrbitRepeatable - title = Single Crewed Lunar Orbit - group = MoonExploration - - - description = Launch a spacecraft with at least one crew aboard into lunar orbit for a routine mission of the specified duration and return safely to Earth. Completing once will unlock the Lunar Space Station contract.&br;&br;Number of Contracts Completed: @index / @maxCompletions - genericDescription = Fly a Crewed Lunar Orbital mission with at least one crew - - synopsis = Fly a Crewed Lunar Orbital mission with at least one crew - - completedMessage = Crew alive and well after the mission--congratulations! - - sortKey = 709 - - cancellable = true - declinable = true - autoAccept = false - minExpiry = 0 - maxExpiry = 0 - maxCompletions = 2 - maxSimultaneous = 1 - deadline = 365 * RP1DeadlineMult() // 1 year - - targetBody = Moon - - - // ************ REWARDS ************ - prestige = Significant // 1.25x - advanceFunds = 0.625 * 50000 * @RP0:globalHardContractMultiplier - rewardScience = 0 - rewardReputation = 100 - rewardFunds = @advanceFunds - failureReputation = 200 - failureFunds = @advanceFunds * 0.5 - - // ************ REQUIREMENTS ************ - - REQUIREMENT - { - name = CompleteContract - type = CompleteContract - contractType = FirstCrewedLunarOrbit - } - - DATA - { - type = int - index = $SingleCrewedLunarOrbitRepeatable_Count + 0 - } - - BEHAVIOUR - { - name = IncrementTheCount - type = Expression - - CONTRACT_COMPLETED_SUCCESS - { - SingleCrewedLunarOrbitRepeatable_Count = $SingleCrewedLunarOrbitRepeatable_Count + 1 - } - } - - // ************ PARAMETERS ************ - - PARAMETER - { - name = VesselGroup - type = VesselParameterGroup - title = Crew Orbit of @targetBody - - PARAMETER - { - name = NewVessel - type = NewVessel - title = Launch a New Vessel - hideChildren = true - } - PARAMETER - { - name = TwoCrew - type = HasCrew - minCrew = 1 - maxCrew = 99 - title = Have at least 1 crewmember on board - hideChildren = true - } - PARAMETER - { - name = MoonOrbit - type = Orbit - maxPeA = 200000 // relatively circular - maxApA = 500000 // relatively circular - targetBody = Moon - disableOnStateChange = true - title = Reach Orbit of the Moon with a maximum Periselene of 200 km and a maximum Aposelene of 500 km and hold it for at least 20 hours - PARAMETER - { - name = Duration - type = Duration - - duration = 20h - - preWaitText = Reach Specified Orbit - waitingText = Orbiting... - completionText = Orbits are complete, you may return to Earth when ready - } - } - PARAMETER - { - name = ReturnHome - type = RP1ReturnHome - title = Return Home Safely - hideChildren = true - completeInSequence = true - } - } -} diff --git a/GameData/RP-1/CrewTrainingTimes.cfg b/GameData/RP-1/CrewTrainingTimes.cfg index 5644825213d..2be534c5b0f 100644 --- a/GameData/RP-1/CrewTrainingTimes.cfg +++ b/GameData/RP-1/CrewTrainingTimes.cfg @@ -232,4 +232,16 @@ TRAININGTIMES MK2VApod = TKS alnair-crew-s1p5_1 = TKS TKS-Mission = 150 + + // Crew carriers + CarrierX15 = 2 + CarrierEarly = 8, CarrierX15 + CarrierAdv = 5, CarrierEarly + CarrierSTS = 5, CarrierAdv + + KerbCan = CarrierX15 + RO-Mk1CrewModule = CarrierEarly + MK1CrewCabin = CarrierEarly + mk2CrewCabin = CarrierAdv + mk3CrewCabin = CarrierSTS } diff --git a/GameData/RP-1/Localization/en-us.cfg b/GameData/RP-1/Localization/en-us.cfg index a4fd9a38768..fff30f29eb3 100644 --- a/GameData/RP-1/Localization/en-us.cfg +++ b/GameData/RP-1/Localization/en-us.cfg @@ -284,7 +284,7 @@ #rp0_loading_tip_029 = Gaining more science from each experiment on Normal or Easy difficulty... #rp0_loading_tip_030 = Being challenged with less funding on Hard difficulty... #rp0_loading_tip_031 = Experimenting with different starting Programs on different playthroughs... - #rp0_loading_tip_032 = Upgrading the Astronaut Complex once to allow EVAs, and twice for lunar exploration... + #rp0_loading_tip_032 = Upgrading the Astronaut Complex three times to allow EVAs, and four times for lunar exploration... #rp0_loading_tip_033 = Upgrading the Tracking Station to increase the power of Earth's DSN... #rp0_loading_tip_034 = Adjusting the construction speed of KSC improvements... #rp0_loading_tip_035 = Hiring scientists... diff --git a/GameData/RP-1/Plugins/RP0InstallChecker.dll b/GameData/RP-1/Plugins/RP0InstallChecker.dll index ea945891e9a3c03f732d7b15336980a60531b302..53beb9480914417adea9abbb7f240016aeca9544 100644 GIT binary patch delta 3096 zcmZWq3v5)!6+JWWv+HMj*wrPr*v?{HoNQqiCsT8TDB~l_0B}za-v?xVAGrNGd z9eK~(&zXDg%-ngN+CKHriEl+V#D8!W`SB?h#foJc5Igz8X=_6VQ0s}hwcfahI{WHK zim9J>S~QDA-XF#1?BHTxWwjTO9ZjYL1Q1G_fbGb`l+6~uj7%t@$&N0li=@MVGa5V%kkL$LF)$hHS)r(Z<-BhNyc{&z0^+daiQeQ}$}N zNzJ)z{=#g5yV;Z{ZZKQ%WKkh$-rXH3kKWO;#lDt>zEmZUby8I|EVdxw<3nK_^%CAw5^R<7zJPPdbI^gLl&_PwqgMx)Wr(uREw7bGwQ$ z=8y9<9QR?0abB}i<_r0}t44YDQCgfuyz~b(q!-ZnKdReDPX0I}?$cCwn)aE7O7{gV zS4nk>XOtXg`#6UCbIS3B6r*v*a-x&<#5g<2X>58xMs>r;cmwrpQ=N=AQfRtlq?T}Y z-{#s>oKj1@ky^^xNHu9}ChGo@ho#zR3-zYRo%LP0_3|(;$*f5&Q{LOL@A%lcw|%YY zVxC-fO10%3BF~|$%>WAl!-UdoQQNVN2^CX!h<(du-{o3RH(%tIX!?A<^nbDReCFGx z#u8;}RmIGS%`!r1c9iXy3~qXlSqps2$uUxG-U%zd4lJsE5*X(EHzjvx+@aCIG(%tu z%U;V@RNvE$V^M(jkNV9$TQ_k2HuV?1>(-JA9w}Hn*b#30%=-mkG!<5rDd)c9qMNn!v^I_SQ_2TWEnAVs65?TOlIwYgCuA?5;c0nP<5`Wr*BED!*Kh-!7=SsYE^zLc=ELUS z-64t#3BUt%b`@}P>@AvT=tn5|z$BYbayLo-MzEYSyqBDcHSLKutnC@=OJ@2z_9v9m zaepGwo@k$I)oMp?BC%m8JvN*iUq75or`x?xoJh7kaZe$W>i;px*>q^Mci%nO)!&;* zxr(E+tSDSdHD_O0Xs4R9uPU^!Le-qwSI>3c>rEB+t=Zh4=}M0DqcffEAK5=Vu9d<5 zOkz}769YqTI#bsRG{imwZQcP8m((vJ*zS4umIQe%nj{ps}1 zuX;-YZKet{^GINyDBYyO>~J^q4rZh>?QpU5MT*Vl!8x6~c>^4T#shZYuG62*rQxdOhcHGhi46K_8%GL<;3_YrK6Yk|&v}%%9^2S= zT{9z<|B;Pl+sJmYpX-L{Pm|3Nd~^A85AWW){X4zCy>fHwfw=cXO*~ub^M^~qJ@W&4 z*fB%+{eHs^5BVy>{W9Dmt(X+Gm7$=JvLbv?)Ir(nAWcVvdu*iyq~VA_m<;8dONk*o zZW1OGBz=%FoD3(~yMe&`06*Y?fOn&&HhWy!feJX`sgt3pBm7gP$ney088Bk}ti*&C z{Jxl!fzZ?`(y8L=pn}8I7fW=7R9`$AQ b3;xSeqmKXOW=_>UCSI<4P0R#h*R1~nlbLr0X&5i_JS+L^ZF?c7{f)UABTM&V>v%-yQjxO+&i33pnrt?p0MTK3H@6uh=e z<*DtmUg!!55i4ZX_L=y9q0@6}b)MF1+X~Rgfs?tj#+Umfoo!<`C~qzK44-k$x478A8=Fww zlS$6gyKpi2^>Tal?B1`em@vH8t$Dt*-eI>Fu+u9~ zF=b~NXks7k;OyKu?vCcS7nv0II_z@R?Ht^Qms=P^Tj#pLfm^x$iTb_XZu^E7o);_) zz9aaon8VraJ#DvDcs7pD7`y-u8y}TtOdDr4mc^vmhzqQ4;~U}y!^R@1FsSiKji1#x zsqr}-^RRe?844ON)8b$?_iW>3@mJ~K5njVOyh{vXk2z2gHU@<%8L;*+stQ)pV0V}@hl79Zv04le})dxYrI7HZALCe0|H_(B4{DDVOfPsCsq=Bu!(ph z4icB+2yu;;KZX;OH){D)8i(-`!6dfJVSFCD<)p^1Yy7FkG!Ebe zyogoU26I9^NNw<|tVV{vaQu01T*RfRj!5Nie7g6KZcR1#;3lWV$zI~_vz+&+;1&JD z+3c;O#lp^9Y0b`DvDlmK#fpvNId{DO?yQpg`?zG6%rq+P1H1~Y18ehpc8$2XyLXNZ zsTfUNI*Ur}1JvwN+_on_JhT*>M~278Tot3KH_oC`tC^S0GS{`R-tbK`TsM243v7#Q z9~sZ)bGt?`m>(T4t<7&A%~zvyuL>{PxZL|>V{i3~jYGmzC-(l^wANXjFJbMj!gvYQ z&7svo^m&0qulLLF7phC5_X%q;#KGshzLvMV?9vhf`^V@x|fA7_m-l_I#9*}l00w+9iG*k+e6jg>N9*{vJg`k-dTJZZIWq3TAheqWbaFkA*jsx~m$Tf5rMA+_}+L diff --git a/GameData/RP-1/Programs/Programs.cfg b/GameData/RP-1/Programs/Programs.cfg index 96cb486f4de..91212a68514 100644 --- a/GameData/RP-1/Programs/Programs.cfg +++ b/GameData/RP-1/Programs/Programs.cfg @@ -14,6 +14,11 @@ RP0_PROGRAM OBJECTIVES { + FACILITY_LEVEL + { + facility = AstronautComplex + level = 2 + } COMPLETE_CONTRACT { name = BreakSoundBarrier @@ -704,6 +709,11 @@ RP0_PROGRAM OBJECTIVES { + FACILITY_LEVEL + { + facility = AstronautComplex + level = 3 + } complete_contract = first_OrbitRecover complete_contract = OrbitalTestFlight complete_contract = first_OrbitCrewed @@ -871,7 +881,7 @@ RP0_PROGRAM name = CrewedLunar isHSF = true title = Crewed Lunar Exploration - description = You are tasked with sending to the Moon, 240,000 miles away from the control station in Houston, a giant rocket more than 300 feet tall, made of new metal alloys, some of which have not yet been invented, capable of standing heat and stresses several times more than have ever been experienced, fitted together with a precision better than the finest watch, carrying all the equipment needed for propulsion, guidance, control, communications, food, and survival, on an untried mission, to an unknown celestial body, and then return it safely to earth, reentering the atmosphere at speeds of over 25,000 miles per hour, causing heat about half that of the temperature of the sun. Alternatively, this could be an opportunity for some command chair antics. But a proper rocket is probably your best bet. You will need to upgrade your astronaut complex to level three to plant a flag on the Moon and complete the first crewed landing contract. + description = You are tasked with sending to the Moon, 240,000 miles away from the control station in Houston, a giant rocket more than 300 feet tall, made of new metal alloys, some of which have not yet been invented, capable of standing heat and stresses several times more than have ever been experienced, fitted together with a precision better than the finest watch, carrying all the equipment needed for propulsion, guidance, control, communications, food, and survival, on an untried mission, to an unknown celestial body, and then return it safely to earth, reentering the atmosphere at speeds of over 25,000 miles per hour, causing heat about half that of the temperature of the sun. Alternatively, this could be an opportunity for some command chair antics. But a proper rocket is probably your best bet. You will need to upgrade your astronaut complex to level five to plant a flag on the Moon and complete the first crewed landing contract. requirementsPrettyText = Complete contracts X and Y objectivesPrettyText = Send crew to flyby, orbit, and land on the Moon. nominalDurationYears = 12 @@ -934,6 +944,7 @@ RP0_PROGRAM OPTIONALS { + CrewedLunarOrbitRepeat = true MoonExtendedStayCrew = true } } diff --git a/GameData/RP-1/RP-1.version b/GameData/RP-1/RP-1.version index 59c55370690..0176e1ec303 100644 --- a/GameData/RP-1/RP-1.version +++ b/GameData/RP-1/RP-1.version @@ -1,13 +1,13 @@ { "NAME": "Realistic Progression One", "URL": "https://raw.githubusercontent.com/KSP-RO/RP-1/master/GameData/RP-1/RP-1.version", - "DOWNLOAD": "https://github.com/KSP-RO/RP-1/releases/download/v3.0.1.0/RP-1-v3.0.1.0.zip", + "DOWNLOAD": "https://github.com/KSP-RO/RP-1/releases/download/v3.1.1.2/RP-1-v3.1.1.2.zip", "HOMEPAGE": "https://github.com/KSP-RO/RP-1/", "VERSION": { "MAJOR": 3, - "MINOR": 0, + "MINOR": 1, "PATCH": 1, - "BUILD": 0 + "BUILD": 2 }, "KSP_VERSION": { "MAJOR": "1", diff --git a/GameData/RP-1/Science/Experiments/CrewReport.cfg b/GameData/RP-1/Science/Experiments/CrewReport.cfg index ef991276851..93741cd1e05 100644 --- a/GameData/RP-1/Science/Experiments/CrewReport.cfg +++ b/GameData/RP-1/Science/Experiments/CrewReport.cfg @@ -55,7 +55,7 @@ @data_rate /= 300 //5 minutes %requires = %resources = - %crew_operate = True + %crew_operate = CrewOnly %experiment_desc = A simple report on the current situation. Includes basic vital signs and crew observations. } } diff --git a/GameData/RP-1/Science/Experiments/CrewScience/BasicCapsuleExperiments.cfg b/GameData/RP-1/Science/Experiments/CrewScience/BasicCapsuleExperiments.cfg index 41d797ff66a..ded55d2bc23 100644 --- a/GameData/RP-1/Science/Experiments/CrewScience/BasicCapsuleExperiments.cfg +++ b/GameData/RP-1/Science/Experiments/CrewScience/BasicCapsuleExperiments.cfg @@ -52,7 +52,7 @@ EXPERIMENT_DEFINITION @data_rate /= 10800 //3 hours requires = CrewMin:1 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } } @@ -103,7 +103,7 @@ EXPERIMENT_DEFINITION @data_rate /= 14400 //4 hours requires = CrewMin:1 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } } @@ -154,7 +154,7 @@ EXPERIMENT_DEFINITION @data_rate /= 10800 //3 hours requires = CrewMin:1 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } } @@ -206,7 +206,7 @@ EXPERIMENT_DEFINITION @data_rate /= 21600 //6 hours requires = CrewMin:1 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } } diff --git a/GameData/RP-1/Science/Experiments/CrewScience/CockpitExperiments.cfg b/GameData/RP-1/Science/Experiments/CrewScience/CockpitExperiments.cfg index c60cdcd5adb..c148af8a865 100644 --- a/GameData/RP-1/Science/Experiments/CrewScience/CockpitExperiments.cfg +++ b/GameData/RP-1/Science/Experiments/CrewScience/CockpitExperiments.cfg @@ -51,7 +51,7 @@ EXPERIMENT_DEFINITION @data_rate /= 1080 //18 minutes requires = CrewMin:1,SurfaceSpeedMin:450,SurfaceSpeedMax:525,AltitudeMin:10000 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } } @@ -100,7 +100,7 @@ EXPERIMENT_DEFINITION @data_rate /= 1440 //24 minutes, requires 3 flights requires = CrewMin:1,SurfaceSpeedMin:620,SurfaceSpeedMax:820,AltitudeMin:10000 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } } @@ -151,7 +151,7 @@ EXPERIMENT_DEFINITION @data_rate /= 1440 //24 minutes, requires 3 flights requires = CrewMin:1,SurfaceSpeedMin:650 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } } @@ -200,7 +200,7 @@ EXPERIMENT_DEFINITION @data_rate /= 1440 //24 minutes, requires 3 flights requires = CrewMin:1,SurfaceSpeedMin:1500 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } } diff --git a/GameData/RP-1/Science/Experiments/CrewScience/MatureCapsuleExperiments.cfg b/GameData/RP-1/Science/Experiments/CrewScience/MatureCapsuleExperiments.cfg index 9af22ae8828..4cdd1640047 100644 --- a/GameData/RP-1/Science/Experiments/CrewScience/MatureCapsuleExperiments.cfg +++ b/GameData/RP-1/Science/Experiments/CrewScience/MatureCapsuleExperiments.cfg @@ -51,7 +51,7 @@ EXPERIMENT_DEFINITION @data_rate /= 7200 //2 hours requires = CrewMin:3 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } } @@ -100,7 +100,7 @@ EXPERIMENT_DEFINITION @data_rate /= 172800 // 2 requires = CrewMin:2 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } } @@ -149,7 +149,7 @@ EXPERIMENT_DEFINITION @data_rate /= 43200 // 12 hours requires = CrewMin:2 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } } @@ -200,7 +200,7 @@ EXPERIMENT_DEFINITION @sample_amount /= 3 requires = CrewMin:2 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } } @@ -251,7 +251,7 @@ EXPERIMENT_DEFINITION @sample_amount /= 3 requires = CrewMin:2 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } } diff --git a/GameData/RP-1/Science/Experiments/CrewScience/SecondGenExperiments.cfg b/GameData/RP-1/Science/Experiments/CrewScience/SecondGenExperiments.cfg index c52dd6c5e78..09b5a15496c 100644 --- a/GameData/RP-1/Science/Experiments/CrewScience/SecondGenExperiments.cfg +++ b/GameData/RP-1/Science/Experiments/CrewScience/SecondGenExperiments.cfg @@ -101,7 +101,7 @@ EXPERIMENT_DEFINITION @data_rate /= 21600 //6 hours requires = CrewMin:2 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } } @@ -150,7 +150,7 @@ EXPERIMENT_DEFINITION @data_rate /= 172800 //48 hours requires = CrewMin:2 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } } @@ -253,7 +253,7 @@ EXPERIMENT_DEFINITION %sample_amount = 1 requires = CrewMin:2 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } } @@ -303,7 +303,7 @@ EXPERIMENT_DEFINITION %sample_amount = 1 requires = CrewMin:2 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } } @@ -354,7 +354,7 @@ EXPERIMENT_DEFINITION @data_rate /= 518400 //144 hours requires = CrewMin:2 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } } @@ -405,7 +405,7 @@ EXPERIMENT_DEFINITION @data_rate /= 3600 //1 hour requires = CrewMin:2 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } } @@ -456,7 +456,7 @@ EXPERIMENT_DEFINITION @data_rate /= 7200 //2hours requires = CrewMin:2,AstronoutComplexLevelMin:2 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } } @@ -557,7 +557,7 @@ EXPERIMENT_DEFINITION %sample_amount = 1 //Should be 0.5 if the experiment is meant to take 2 flights requires = CrewMin:2 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } } @@ -608,7 +608,7 @@ EXPERIMENT_DEFINITION @data_rate /= 86400 //24 hours requires = CrewMin:2 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } } diff --git a/GameData/RP-1/Science/ScienceLabs.cfg b/GameData/RP-1/Science/ScienceLabs.cfg index 24766d2cc09..1c799a7e97c 100644 --- a/GameData/RP-1/Science/ScienceLabs.cfg +++ b/GameData/RP-1/Science/ScienceLabs.cfg @@ -38,7 +38,7 @@ @data_rate /= 10800 //3 hours requires = CrewMin:1 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } MODULE @@ -50,7 +50,7 @@ @data_rate /= 14400 //4 hours requires = CrewMin:1 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } MODULE @@ -62,7 +62,7 @@ @data_rate /= 10800 //3 hours requires = CrewMin:1 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } MODULE @@ -75,7 +75,7 @@ @data_rate /= 21600 //6 hours requires = CrewMin:1 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } MODULE @@ -87,7 +87,7 @@ @data_rate /= 7200 //2 hours requires = CrewMin:3 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } MODULE @@ -99,7 +99,7 @@ @data_rate /= 172800 // 2 requires = CrewMin:2 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } MODULE @@ -111,7 +111,7 @@ @data_rate /= 43200 // 12 hours requires = CrewMin:2 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } MODULE @@ -125,7 +125,7 @@ @sample_amount /= 3 requires = CrewMin:2 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } MODULE @@ -139,7 +139,7 @@ @sample_amount /= 3 requires = CrewMin:2 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } MODULE @@ -163,7 +163,7 @@ @data_rate /= 21600 //6 hours requires = CrewMin:2 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } MODULE @@ -175,7 +175,7 @@ @data_rate /= 172800 //48 hours requires = CrewMin:2 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } MODULE @@ -200,7 +200,7 @@ %sample_amount = 1 requires = CrewMin:2 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } MODULE @@ -213,7 +213,7 @@ %sample_amount = 1 requires = CrewMin:2 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } MODULE @@ -225,7 +225,7 @@ @data_rate /= 518400 //144 hours requires = CrewMin:2 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } MODULE @@ -237,7 +237,7 @@ @data_rate /= 3600 //1 hour requires = CrewMin:2 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } MODULE @@ -249,7 +249,7 @@ @data_rate /= 7200 //2hours requires = CrewMin:2,AstronoutComplexLevelMin:2 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } MODULE @@ -274,7 +274,7 @@ %sample_amount = 1 //Should be 0.5 if the experiment is meant to take 2 flights requires = CrewMin:2 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } MODULE @@ -286,7 +286,7 @@ @data_rate /= 86400 //24 hours requires = CrewMin:2 resources = - crew_operate = True + crew_operate = CrewOnly hide_when_unavailable = True } diff --git a/GameData/RP-1/Strategies/Milestones.cfg b/GameData/RP-1/Strategies/Milestones.cfg index cc1672ff230..8db5250803c 100644 --- a/GameData/RP-1/Strategies/Milestones.cfg +++ b/GameData/RP-1/Strategies/Milestones.cfg @@ -2,7 +2,7 @@ RP0_MILESTONE { name = BreakSoundBarrierMilestone contractName = BreakSoundBarrier - screenshotContractParamName = BreakSoundBarrier + screenshotContractParamName = BSBVesselGroup headline = PLANE BREAKS BARRIER OF SOUND article = (tab)With the expert skills of <<1>>, <<2>> has traveled faster than sound. This experimental aircraft pushed through the immense turbulence of the transsonic region to surpass this impressive milestone. With the rate of progress at this new space program, new milestones are sure to follow.\n(tab)Historical Information: On October 14th, 1947, US Air Force pilot Chuck Yeager broke the sound barrier in a Bell X-1 that he nicknamed Glamorous Glennis. The rocket-powered aircraft was dropped from the bomb bay of a B-29 and acheived a speed of Mach 1.06 (361 m/s). The Soviets accomplished the feat in 1948 with a Lavochkin La-176 and the British in 1948 with a de Havilland DH.108. image = RP-1/Strategies/MilestoneImages/BreakSoundBarrier diff --git a/GameData/RP-1/Tree/ECM-Parts.cfg b/GameData/RP-1/Tree/ECM-Parts.cfg index 5041c81a31c..e14ff1b399f 100644 --- a/GameData/RP-1/Tree/ECM-Parts.cfg +++ b/GameData/RP-1/Tree/ECM-Parts.cfg @@ -463,8 +463,12 @@ RO-reactor-BES5 = 100000,PowerReactors RO-reactor-TOPAZI = 200000,PowerReactors RO-reactor-kilopower = 10000,RO-reactor-snap10a + RO-reactor-prometheus = 1000000,RO-reactor-snap50-300 RO-reactor-snap10a = 15000,PowerReactors + RO-reactor-snap2 = 10000,RO-reactor-snap10a,TurbineReactors RO-reactor-snap50 = 300000,TurbineReactors + RO-reactor-snap50-300 = 200000,RO-reactor-snap50 + RO-reactor-snap8 = 105000,RO-reactor-snap10a ROAJ10-137 = AJ10-137 ROAdvCapsule = capsulesGemini ROAerobeeSustainer = WAC-Corporal @@ -472,13 +476,17 @@ ROAerojet25KS18000 = 2-5KS18000 ROBabySergeant = T17-E2 ROC-APAS8995A = APAS8995Dock - ROC-APAS8995P = ROC-APAS8995A + ROC-APAS8995Av2 = APAS8995Dock + ROC-APAS8995P = APAS8995Dock + ROC-APAS8995Pv2 = APAS8995Dock ROC-AgenaFairing = ROC-AgenaPort ROC-AgenaPort = 9000,dockingProbeDrogue - ROC-ApolloAPAS75BDB = 5000,dockingAndro + ROC-ApolloAPAS75BDB = rn_apas75 ROC-ApolloASTPAdapterBDB = 5000,dockingAndro ROC-ApolloASTPUVXBDB = ROC-ApolloASTPAdapterBDB ROC-ApolloASTPVHFBDB = ROC-ApolloASTPAdapterBDB + ROC-ApolloCADSActive = APAS8995Dock + ROC-ApolloCADSPassive = APAS8995Dock ROC-ApolloCM = capsulesApollo ROC-ApolloCMBDB = capsulesApollo ROC-ApolloCMBDBBlockIII = capsulesApolloBIII @@ -1565,9 +1573,9 @@ radiator-universal-1 = 1 radiator-universal-2 = 1 radiator-universal-3 = 1 - reactor-0625 = 500000, RO-reactor-snap50 + reactor-0625 = 500000,RO-reactor-snap50-300 reactor-125 = 75000, RO-reactor-TOPAZI - reactor-25 = 400000, RO-reactor-snap50 + reactor-25 = 400000,RO-reactor-snap8 restock-decoupler-radial-tiny-1 = 1 restock-engine-125-pug = Aestus restock-engine-125-valiant = Viking-2 @@ -1598,7 +1606,7 @@ rn-almaz-dp = s1-dp rn-almaz-ops4 = 50000,almaz3-5 rn-almaz-rcs = almaz3-5,rcsMult - rn-apas75 = dockingAndro + rn-apas75 = 5000,dockingAndro rn-astp-bo = 5000,t-bo rn-brizm-me = S5-98M rn-centaurt-rl10-l = RL10A-4 @@ -1668,7 +1676,7 @@ roverWheel2 = wheelsEarly roverWheel3 = wheelsLate rtg = 50000,RTGlevel4 - rtg-0625 = 100000,RTGlevel6 + rtg-0625 = 35156,RTGlevel6 rtgMini = 50000,RTGlevel1 s1-dp = 17000,dockingProbeDrogue,dockingCrew s1-lsolar = 7k-ok-lsolar diff --git a/GameData/RP-1/Tree/EntryCostModifiers.cfg b/GameData/RP-1/Tree/EntryCostModifiers.cfg index fc5ec7112cd..013fadf821d 100644 --- a/GameData/RP-1/Tree/EntryCostModifiers.cfg +++ b/GameData/RP-1/Tree/EntryCostModifiers.cfg @@ -636,6 +636,14 @@ ENTRYCOSTMODS // NUCLEAR // * RTG's will progress in tiers in order to reduce the entry costs //********************************************************************************** +// sources: +// https://www.osti.gov/biblio/4110379 +// SNAP-50 reactor program cost ~21M USD/year (1965$) +// https://www.osti.gov/biblio/4101005 +// SNAP-50 power conversion program cost ~13M USD/year (1965$) +// https://apps.dtic.mil/dtic/tr/fulltext/u2/a146831.pdf +// 500M to 1B USD estimated to produce and test SNAP-50 + // RTG RTGlevel1 = 57550 // tech = firstRTG RTGlevel2 = 5660, RTGlevel1 // tech = earlyRTG @@ -645,10 +653,10 @@ ENTRYCOSTMODS RTGlevel6 = 6970, RTGlevel5 // tech = modernNuclearPower // Nuclear Reactors - SpaceReactors = 1000000 - PowerReactors = 50000, SpaceReactors, RTGlevel1 //For thermoelectrics - TurbineReactors = 100000, PowerReactors //more complex Rankine/Brayton Cycle power reactors - LiquidCoreReactors = 1000000, SpaceReactors + SpaceReactors = 126000 // Assuming same yearly cost as SNAP-50, and first-gen reactors (SNAP-10, BES-5) were developed in around 6 years. 21M/year*6 years = ~126M USD, 126000 funds + PowerReactors = 10000, SpaceReactors, RTGlevel1 //For thermoelectrics + TurbineReactors = 130000, PowerReactors //more complex Rankine/Brayton Cycle power reactors. SNAP-2 took about 10 years to develop power conversion unit, SNAP-50 would have been around 15? 13M/year*10 year = 130M, 130000 funds + FluidCoreReactors = 1000000, SpaceReactors //cover the gas-core stuff if anyone adds that I guess //********************************************************************************** diff --git a/GameData/RP-1/Tree/TREE-Parts.cfg b/GameData/RP-1/Tree/TREE-Parts.cfg index 2601ce660e1..07eee4beb7f 100644 --- a/GameData/RP-1/Tree/TREE-Parts.cfg +++ b/GameData/RP-1/Tree/TREE-Parts.cfg @@ -7237,6 +7237,14 @@ %MODULE[ModuleTagList] { tag = Nuclear } } +@PART[RO-reactor-prometheus]:FOR[xxxRP0] +{ + %TechRequired = modernNuclearPower + %cost = 24000 + %entryCost = 0 + RP0conf = true + @description ^=:$: From Near Future Electrical mod +} @PART[RO-reactor-snap10a]:FOR[xxxRP0] { %TechRequired = nuclearFissionReactors @@ -7247,10 +7255,32 @@ %MODULE[ModuleTagList] { tag = Nuclear } +} +@PART[RO-reactor-snap2]:FOR[xxxRP0] +{ + %TechRequired = improvedRTG + %cost = 5000 + %entryCost = 0 + RP0conf = true + @description ^=:$: From Near Future Electrical mod + + %MODULE[ModuleTagList] { tag = Nuclear } + } @PART[RO-reactor-snap50]:FOR[xxxRP0] { %TechRequired = improvedRTG + %cost = 10000 + %entryCost = 0 + RP0conf = true + @description ^=:$: From Near Future Electrical mod + + %MODULE[ModuleTagList] { tag = Nuclear } + +} +@PART[RO-reactor-snap50-300]:FOR[xxxRP0] +{ + %TechRequired = multihundredWattRTG %cost = 20000 %entryCost = 0 RP0conf = true @@ -7258,6 +7288,17 @@ %MODULE[ModuleTagList] { tag = Nuclear } +} +@PART[RO-reactor-snap8]:FOR[xxxRP0] +{ + %TechRequired = improvedRTG + %cost = 5000 + %entryCost = 0 + RP0conf = true + @description ^=:$: From Near Future Electrical mod + + %MODULE[ModuleTagList] { tag = Nuclear } + } @PART[RO-shockConeIntake125]:FOR[xxxRP0] { @@ -7351,6 +7392,14 @@ RP0conf = true @description ^=:$: From ROCapsules mod } +@PART[ROC-APAS8995Av2]:FOR[xxxRP0] +{ + %TechRequired = standardDockingPorts + %cost = 3500 + %entryCost = 0 + RP0conf = true + @description ^=:$: From ROCapsules mod +} @PART[ROC-APAS8995P]:FOR[xxxRP0] { %TechRequired = standardDockingPorts @@ -7359,6 +7408,14 @@ RP0conf = true @description ^=:$: From ROCapsules mod } +@PART[ROC-APAS8995Pv2]:FOR[xxxRP0] +{ + %TechRequired = standardDockingPorts + %cost = 3000 + %entryCost = 0 + RP0conf = true + @description ^=:$: From ROCapsules mod +} @PART[ROC-AgenaFairing]:FOR[xxxRP0] { %TechRequired = earlyDocking @@ -7410,6 +7467,22 @@ %MODULE[ModuleTagList] { tag = Instruments } } +@PART[ROC-ApolloCADSActive]:FOR[xxxRP0] +{ + %TechRequired = standardDockingPorts + %cost = 3500 + %entryCost = 0 + RP0conf = true + @description ^=:$: From ROCapsules mod +} +@PART[ROC-ApolloCADSPassive]:FOR[xxxRP0] +{ + %TechRequired = standardDockingPorts + %cost = 3000 + %entryCost = 0 + RP0conf = true + @description ^=:$: From ROCapsules mod +} @PART[ROC-ApolloCM]:FOR[xxxRP0] { %TechRequired = matureCapsules @@ -19404,6 +19477,9 @@ %entryCost = 0 RP0conf = true @description ^=:$: From Universal Storage 2 mod + + %MODULE[ModuleTagList] { tag = NuclearRTG } + } @PART[USRadialTanks]:FOR[xxxRP0] { @@ -29797,10 +29873,13 @@ @PART[rtg-0625]:FOR[xxxRP0] { %TechRequired = modernNuclearPower - %cost = 20045 - %entryCost = 200445 + %cost = 3550 + %entryCost = 0 RP0conf = true @description ^=:$: From Near Future Electrical mod + + %MODULE[ModuleTagList] { tag = NuclearRTG } + } @PART[rtg100]:FOR[xxxRP0] { diff --git a/GameData/RP-1/Tree/identicalParts.cfg b/GameData/RP-1/Tree/identicalParts.cfg index d346e6c101f..fe3225cf427 100644 --- a/GameData/RP-1/Tree/identicalParts.cfg +++ b/GameData/RP-1/Tree/identicalParts.cfg @@ -82,11 +82,15 @@ @PART[ROE-AltairIII]:FOR[xxxRP0] { %identicalParts = RO-AltairIII,ROE-AltairIII,ROE-AltairIII-RN } @PART[ROE-AltairIII-RN]:FOR[xxxRP0] { %identicalParts = RO-AltairIII,ROE-AltairIII,ROE-AltairIII-RN } @PART[ROEE-AMBR]:FOR[xxxRP0] { %identicalParts = ROEE-AMBR } -@PART[APAS89-95]:FOR[xxxRP0] { %identicalParts = APAS89-95,ROC-APAS8995A,ROC-APAS8995P,bluedog_CXA_APAS_A_L04F,bluedog_CXA_APAS_P } -@PART[bluedog_CXA_APAS_A_L04F]:FOR[xxxRP0] { %identicalParts = APAS89-95,ROC-APAS8995A,ROC-APAS8995P,bluedog_CXA_APAS_A_L04F,bluedog_CXA_APAS_P } -@PART[bluedog_CXA_APAS_P]:FOR[xxxRP0] { %identicalParts = APAS89-95,ROC-APAS8995A,ROC-APAS8995P,bluedog_CXA_APAS_A_L04F,bluedog_CXA_APAS_P } -@PART[ROC-APAS8995A]:FOR[xxxRP0] { %identicalParts = APAS89-95,ROC-APAS8995A,ROC-APAS8995P,bluedog_CXA_APAS_A_L04F,bluedog_CXA_APAS_P } -@PART[ROC-APAS8995P]:FOR[xxxRP0] { %identicalParts = APAS89-95,ROC-APAS8995A,ROC-APAS8995P,bluedog_CXA_APAS_A_L04F,bluedog_CXA_APAS_P } +@PART[rn_apas75]:FOR[xxxRP0] { %identicalParts = ROC-ApolloAPAS75BDB,rn_apas75 } +@PART[ROC-ApolloAPAS75BDB]:FOR[xxxRP0] { %identicalParts = ROC-ApolloAPAS75BDB,rn_apas75 } +@PART[APAS89-95]:FOR[xxxRP0] { %identicalParts = APAS89-95,ROC-APAS8995A,ROC-APAS8995Av2,ROC-APAS8995P,ROC-APAS8995Pv2,bluedog_CXA_APAS_A_L04F,bluedog_CXA_APAS_P } +@PART[bluedog_CXA_APAS_A_L04F]:FOR[xxxRP0] { %identicalParts = APAS89-95,ROC-APAS8995A,ROC-APAS8995Av2,ROC-APAS8995P,ROC-APAS8995Pv2,bluedog_CXA_APAS_A_L04F,bluedog_CXA_APAS_P } +@PART[bluedog_CXA_APAS_P]:FOR[xxxRP0] { %identicalParts = APAS89-95,ROC-APAS8995A,ROC-APAS8995Av2,ROC-APAS8995P,ROC-APAS8995Pv2,bluedog_CXA_APAS_A_L04F,bluedog_CXA_APAS_P } +@PART[ROC-APAS8995A]:FOR[xxxRP0] { %identicalParts = APAS89-95,ROC-APAS8995A,ROC-APAS8995Av2,ROC-APAS8995P,ROC-APAS8995Pv2,bluedog_CXA_APAS_A_L04F,bluedog_CXA_APAS_P } +@PART[ROC-APAS8995Av2]:FOR[xxxRP0] { %identicalParts = APAS89-95,ROC-APAS8995A,ROC-APAS8995Av2,ROC-APAS8995P,ROC-APAS8995Pv2,bluedog_CXA_APAS_A_L04F,bluedog_CXA_APAS_P } +@PART[ROC-APAS8995P]:FOR[xxxRP0] { %identicalParts = APAS89-95,ROC-APAS8995A,ROC-APAS8995Av2,ROC-APAS8995P,ROC-APAS8995Pv2,bluedog_CXA_APAS_A_L04F,bluedog_CXA_APAS_P } +@PART[ROC-APAS8995Pv2]:FOR[xxxRP0] { %identicalParts = APAS89-95,ROC-APAS8995A,ROC-APAS8995Av2,ROC-APAS8995P,ROC-APAS8995Pv2,bluedog_CXA_APAS_A_L04F,bluedog_CXA_APAS_P } @PART[bluedog_Apollo_Block3_MissionModule]:FOR[xxxRP0] { %identicalParts = ROC-ApolloMissionModule,bluedog_Apollo_Block3_MissionModule } @PART[ROC-ApolloMissionModule]:FOR[xxxRP0] { %identicalParts = ROC-ApolloMissionModule,bluedog_Apollo_Block3_MissionModule } @PART[bluedog_Apollo_Block3_Capsule]:FOR[xxxRP0] { %identicalParts = ROC-ApolloCMBDBBlockIII,ROC-ApolloCMBlockIII,bluedog_Apollo_Block3_Capsule } @@ -184,6 +188,8 @@ @PART[ntr-sc-25-1]:FOR[xxxRP0] { %identicalParts = ROE-BNTR,SXTNERVA,constellationBNTR,ntr-sc-25-1 } @PART[ROE-BNTR]:FOR[xxxRP0] { %identicalParts = ROE-BNTR,SXTNERVA,constellationBNTR,ntr-sc-25-1 } @PART[SXTNERVA]:FOR[xxxRP0] { %identicalParts = ROE-BNTR,SXTNERVA,constellationBNTR,ntr-sc-25-1 } +@PART[ROC-ApolloCADSActive]:FOR[xxxRP0] { %identicalParts = ROC-ApolloCADSActive,ROC-ApolloCADSPassive } +@PART[ROC-ApolloCADSPassive]:FOR[xxxRP0] { %identicalParts = ROC-ApolloCADSActive,ROC-ApolloCADSPassive } @PART[bluedog_castorSRB]:FOR[xxxRP0] { %identicalParts = ROE-Castor1,ROE-Castor1-RN,bluedog_castorSRB,rn_thor_castor,solidBooster1-1Small } @PART[rn_thor_castor]:FOR[xxxRP0] { %identicalParts = ROE-Castor1,ROE-Castor1-RN,bluedog_castorSRB,rn_thor_castor,solidBooster1-1Small } @PART[ROE-Castor1]:FOR[xxxRP0] { %identicalParts = ROE-Castor1,ROE-Castor1-RN,bluedog_castorSRB,rn_thor_castor,solidBooster1-1Small } diff --git a/GameData/RP-1/changelog.cfg b/GameData/RP-1/changelog.cfg index 6f0eddc40dc..e686f2a0d54 100644 --- a/GameData/RP-1/changelog.cfg +++ b/GameData/RP-1/changelog.cfg @@ -5,6 +5,60 @@ KERBALCHANGELOG author = KSP-RO team website = github.com/KSP-RO/RP-1 VERSION + { + version = 3.1.1.2 + versionKSP = 1.12.3 + CHANGE + { + change = What's Changed + subchange = Fix Procedural Avionics window EC amount unit (should be kJ not J) + } + } + VERSION + { + version = 3.1.1.1 + versionKSP = 1.12.3 + CHANGE + { + change = What's Changed + subchange = Fix LC modification validation failing when upgrading 1t LCs to 3t + subchange = Improve Proc Avionics window display of EC to show the avionics wattage of the proposed controllable mass + } + } + VERSION + { + version = 3.1.1.0 + versionKSP = 1.12.3 + CHANGE + { + change = What's Changed + subchange = Update for Kerbalism 3.18 + subchange = Spaceplane crew carrier pods require training, but those training times are minimal + } + } + VERSION + { + version = 3.1.0.0 + versionKSP = 1.12.3 + CHANGE + { + change = What's Changed + subchange = Remove Orbital Recovery contract mentioning it can be completed twice + subchange = Add a patch so that Kerbalism uses the actual inclination of a vessel when checking if an experiment could run (inclination was wrong for vessels not around the current body when Principia is installed due to how Principia implements axial tilt) + subchange = Add Astronaut Complex upgrade requirements to Early X-Planes and Early Crewed Orbit to signpost that upgrades to the AC will be needed + subchange = Fix various tips etc. that mention Astronaut Complex levels + subchange = Fix an issue where UI state could sometimes not be restored properly after closing a popup + subchange = When building a new LC that does not perfectly share commonality with an existing LC, its commonality percent is capped at 95%. This fixes an issue where LCs could be upgraded bit by bit with no efficiency loss + subchange = Highlight (in yellow) when the desired max mass for an LC is above the maximum possible modify limit (or below the minimum possible modify limit) + subchange = Fix an issue where RP-1 would hang on launch if KSPWheel was not installed + subchange = Fix lingering references to Renovate and Upgrade rather than just Modify for LCs + subchange = Update Kerbalism patches to match the existing Kerbalism PRs and make sure they will not be applied to forthcoming Kerbalism releases which have the PRs merged + subchange = Improve the Install Checker's text to be clearer that the issue could be either missing or outdated dependencies when RP-1 doesn't detect its dependencies or itself fails to load + subchange = Add support for new ROC docking ports + subchange = Add optional orbit contract to Crewed Lunar program + } + } + VERSION { version = 3.0.1.0 versionKSP = 1.12.3 diff --git a/README.md b/README.md index 99974147c1b..7b9ddb02691 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@

- +

Welcome to Realistic Progression One, the heavyweight career addon for Kerbal Space Program's Realism Overhaul. diff --git a/Source/GameData.csproj b/Source/GameData.csproj index 5f795ad5740..ca6acb1077f 100644 --- a/Source/GameData.csproj +++ b/Source/GameData.csproj @@ -341,6 +341,9 @@ Contracts\Lunar Crewed\CrewedLunarFlyby.cfg + + Contracts\Lunar Crewed\CrewedLunarOrbitRepeat.cfg + Contracts\Lunar Crewed\CrewedMoonLandingRover.cfg diff --git a/Source/InstallChecker/InstallChecker.cs b/Source/InstallChecker/InstallChecker.cs index 5944cc65b00..8914b59b7b8 100644 --- a/Source/InstallChecker/InstallChecker.cs +++ b/Source/InstallChecker/InstallChecker.cs @@ -7,8 +7,16 @@ namespace RP0InstallChecker [KSPAddon(KSPAddon.Startup.Instantly, true)] public class InstallChecker : MonoBehaviour { - protected void Start() + private bool _firstFrame = true; + + protected void Update() { + if (_firstFrame) + { + _firstFrame = false; + return; + } + Version minKSPCFVer = new Version(1, 30, 0); if (!AssemblyLoader.loadedAssemblies.Any(a => a.name.Equals("KSPCommunityFixes") && (new Version(a.versionMajor, a.versionMinor, a.versionRevision)) >= minKSPCFVer)) { @@ -22,7 +30,7 @@ protected void Start() if (assembliesToCheck.Any(an => !AssemblyLoader.loadedAssemblies.Any(a => a.name.Equals(an, StringComparison.OrdinalIgnoreCase)))) { string titleText = "Incorrect RP-1 Installation"; - string contentText = "This could be caused by downloading the RP-1 repo or some specific branch directly from GitHub. " + + string contentText = "This could be caused by downloading the RP-1 repo or some specific branch directly from GitHub, or by not installing or not updating dependencies. " + "Make sure to follow the install guide located in the RP-1 wiki.\n\n" + "If the goal was to obtain the latest developmental version of RP-1, then please use the link at the top of the RP-1 readme."; ShowErrorDialog(titleText, contentText); @@ -32,7 +40,7 @@ protected void Start() if (AssemblyLoader.loadedAssemblies.Any(a => a.name.Equals("KerbalConstructionTime", StringComparison.OrdinalIgnoreCase))) { string titleText = "Incorrect RP-1 Installation"; - string contentText = "You still have a KerbalConstructionTime dll (RP0KCT.dll). Please uninstall RP-1 and properly reinstall it to remove this dll." + + string contentText = "You still have a KerbalConstructionTime dll (RP0KCT.dll). Please uninstall RP-1 and properly reinstall it to remove this dll. " + "Make sure to follow the install guide located in the RP-1 wiki.\n\n" + "If the goal was to obtain the latest developmental version of RP-1, then please use the link at the top of the RP-1 readme after uninstalling this RP-1 install."; ShowErrorDialog(titleText, contentText); @@ -40,11 +48,14 @@ protected void Start() } assembliesToCheck = new[] { "ToolbarController", "ClickThroughBlocker", "RealFuels", "ContractConfigurator", "ModularFlightIntegrator" }; // These are values of KSPAssembly attribute - if (assembliesToCheck.Any(an => !AssemblyLoader.loadedAssemblies.Any(a => a.name.Equals(an, StringComparison.OrdinalIgnoreCase)))) + var kerbAssembly = AssemblyLoader.loadedAssemblies.FirstOrDefault(a => a.name.StartsWith("Kerbalism", StringComparison.OrdinalIgnoreCase)); + if (assembliesToCheck.Any(an => !AssemblyLoader.loadedAssemblies.Any(a => a.name.Equals(an, StringComparison.OrdinalIgnoreCase))) + || kerbAssembly == null + || kerbAssembly.assembly.GetName().Version < new Version("3.18")) { string titleText = "Incorrect RP-1 Installation"; - string contentText = "You are missing dependencies for RP-1. This could be caused by manually installing RP-1, or by not updating dependencies." + - "Make sure to follow the install guide located in the RP-1 wiki.\n\n" + + string contentText = "You are missing dependencies for RP-1. This could be caused by manually installing RP-1, or by not updating dependencies. " + + "Make sure to follow the install guide located in the RP-1 wiki and make sure to update your mods in CKAN.\n\n" + "If the goal was to obtain the latest developmental version of RP-1, then install normally through the guide and then use the link at the top of the RP-1 readme."; ShowErrorDialog(titleText, contentText); return; diff --git a/Source/RP0/Avionics/ModuleAvionics.cs b/Source/RP0/Avionics/ModuleAvionics.cs index 451004aca4f..3bf87eb6fe7 100644 --- a/Source/RP0/Avionics/ModuleAvionics.cs +++ b/Source/RP0/Avionics/ModuleAvionics.cs @@ -175,7 +175,7 @@ public override void OnAwake() base.OnAwake(); GameEvents.onStageActivate.Add(StageActivated); if (HighLogic.LoadedScene != GameScenes.LOADING) - KerbalismAPI ??= AssemblyLoader.loadedAssemblies.FirstOrDefault(x => x.name.StartsWith("Kerbalism"))?.assembly; + KerbalismAPI ??= KerbalismUtils.Assembly; } // OnStartFinished() instead of OnStart(), to let ModuleCommand configure itself first. diff --git a/Source/RP0/Avionics/ModuleProceduralAvionics.cs b/Source/RP0/Avionics/ModuleProceduralAvionics.cs index 2c883583801..107ce132bac 100644 --- a/Source/RP0/Avionics/ModuleProceduralAvionics.cs +++ b/Source/RP0/Avionics/ModuleProceduralAvionics.cs @@ -1,5 +1,4 @@ -using KSPAPIExtensions; -using RealFuels.Tanks; +using RealFuels.Tanks; using System; using System.Collections.Generic; using UniLinq; @@ -133,7 +132,7 @@ internal float GetShieldedAvionicsMass(float controllableMass) private float GetShieldingMass(float avionicsMass) => Mathf.Pow(avionicsMass, 2f / 3) * CurrentProceduralAvionicsTechNode.shieldingMassFactor; protected override float GetEnabledkW() => GetEnabledkW(CurrentProceduralAvionicsTechNode, GetInternalMassLimit()); - private static float GetEnabledkW(ProceduralAvionicsTechNode techNode, float controllableMass) => GetPolynomial(controllableMass, techNode.powerExponent, techNode.powerConstant, techNode.powerFactor) / 1000f; + internal static float GetEnabledkW(ProceduralAvionicsTechNode techNode, float controllableMass) => GetPolynomial(controllableMass, techNode.powerExponent, techNode.powerConstant, techNode.powerFactor) / 1000f; protected override float GetDisabledkW() => GetEnabledkW() * CurrentProceduralAvionicsTechNode.disabledPowerFactor; private static float GetPolynomial(float value, float exponent, float constant, float factor) => (Mathf.Pow(value, exponent) + constant) * factor; @@ -587,25 +586,21 @@ internal void RefreshDisplays() _window?.RefreshDisplays(); } - private void RefreshPowerDisplay() + public static string BuildPowerString(float enabledkW, float disabledkW) { var powerConsumptionBuilder = StringBuilderCache.Acquire(); - AppendPowerString(powerConsumptionBuilder, GetEnabledkW()); - float dkW = GetDisabledkW(); - if (dkW > 0) + powerConsumptionBuilder.Append(KERBALISM.Lib.HumanOrSIRate(enabledkW, KERBALISM.Lib.ECResID)); + if (disabledkW > 0) { - powerConsumptionBuilder.Append(" /"); - AppendPowerString(powerConsumptionBuilder, dkW); + powerConsumptionBuilder.Append(" / "); + powerConsumptionBuilder.Append(KERBALISM.Lib.HumanOrSIRate(disabledkW, KERBALISM.Lib.ECResID)); } - powerRequirementsDisplay = powerConsumptionBuilder.ToStringAndRelease(); + return powerConsumptionBuilder.ToStringAndRelease(); } - private void AppendPowerString(System.Text.StringBuilder builder, float val) + private void RefreshPowerDisplay() { - if (val >= 1) - builder.AppendFormat(KwFormat, val).Append("\u2009kW"); - else - builder.AppendFormat(WFormat, val * 1000).Append("\u2009W"); + powerRequirementsDisplay = BuildPowerString(GetEnabledkW(), GetDisabledkW()); } private void SetScienceContainer() diff --git a/Source/RP0/Harmony/CustomBarnKit.cs b/Source/RP0/Harmony/CustomBarnKit.cs index f95f60c7799..74c69fb4d84 100644 --- a/Source/RP0/Harmony/CustomBarnKit.cs +++ b/Source/RP0/Harmony/CustomBarnKit.cs @@ -19,7 +19,6 @@ internal static void Postfix_LoadUpgradesPrices(ref bool ___varLoaded, bool __st { if (___varLoaded && !__state) { - MaintenanceHandler.ClearFacilityCosts(); MaintenanceHandler.Instance?.ScheduleMaintenanceUpdate(); } } diff --git a/Source/RP0/Harmony/KSPWheel.cs b/Source/RP0/Harmony/KSPWheel.cs index 7f55501c198..4ddde1f6db3 100644 --- a/Source/RP0/Harmony/KSPWheel.cs +++ b/Source/RP0/Harmony/KSPWheel.cs @@ -1,12 +1,20 @@ using HarmonyLib; using System.Reflection; using UnityEngine; +using System.Linq; namespace RP0.Harmony { [HarmonyPatch] internal class PatchKSPWheel_KSPWheelDamage_wearUpdateSimple { + static bool Prepare() + { + bool foundKSPWheel = AssemblyLoader.loadedAssemblies.FirstOrDefault(a => a.name.Equals("KSPWheel", System.StringComparison.OrdinalIgnoreCase)) != null; + RP0Debug.Log("Attempting to patch KSPWheel. Found? " + foundKSPWheel.ToString(), true); + return foundKSPWheel; + } + static MethodBase TargetMethod() => AccessTools.TypeByName("KSPWheel.KSPWheelDamage")?.GetMethod("wearUpdateSimple", AccessTools.all); [HarmonyPrefix] diff --git a/Source/RP0/Harmony/KerbalismPatcher.cs b/Source/RP0/Harmony/KerbalismPatcher.cs index 23c25ad80a3..4ed5e84f563 100644 --- a/Source/RP0/Harmony/KerbalismPatcher.cs +++ b/Source/RP0/Harmony/KerbalismPatcher.cs @@ -4,6 +4,7 @@ using UnityEngine; using System.Collections.Generic; using System.Reflection; +using System.Linq; namespace RP0.Harmony { @@ -56,6 +57,8 @@ internal static void Postfix_SetDifficultyPreset(ref float ___shieldingEfficienc [HarmonyPatch(typeof(CrewSpecs))] internal class PatchKerbalism_CrewSpecs { + static bool Prepare() => KerbalismUtils.IsValidToPatch(new Version(3, 17, int.MaxValue, int.MaxValue), true); + [HarmonyPrefix] [HarmonyPatch("Check", new Type[] { typeof(ProtoCrewMember) })] internal static bool Prefix_Check(ProtoCrewMember c, ref bool __result) @@ -115,38 +118,53 @@ internal static void Postfix_Update(Experiment __instance) [HarmonyPatch(typeof(Sim))] internal class PatchKerbalism_Sim { + static bool Prepare() => KerbalismUtils.IsValidToPatch(new Version(3, 17, int.MaxValue, int.MaxValue), true); + [HarmonyPrefix] [HarmonyPatch("ShadowPeriod", new Type[] { typeof(Vessel) })] internal static bool Prefix_ShadowPeriod(Vessel v, ref double __result) { - Orbit obt = v.orbitDriver?.orbit; + // We have only 1 sun so don't try to figure out what's the current sunData. + Vector3d sunVec = (Planetarium.fetch.Sun.position - Lib.VesselPosition(v)).normalized; + __result = EclipseFraction(v, Planetarium.fetch.Sun, sunVec) * Sim.OrbitalPeriod(v); + return false; + } + + [HarmonyPrefix] + [HarmonyPatch("SampleSunFactor")] + internal static bool Prefix_SampleSunFactor(Vessel v, double elapsedSeconds, ref double __result) + { + // We have only 1 sun so don't try to figure out what's the current sunData. + __result = SampleSunFactor(v, elapsedSeconds, Planetarium.fetch.Sun); + return false; + } + + public static double EclipseFraction(Vessel v, CelestialBody sun, Vector3d sunVec) + { + var obt = v.orbitDriver?.orbit; if (obt == null) - { - __result = 0d; - return false; - } + return 0; bool incNaN = double.IsNaN(obt.inclination); if (Lib.Landed(v) || incNaN) { - var sun = Planetarium.fetch.Sun; var mb = v.mainBody; if (sun == mb) { - __result = 0d; + return 0; } - else if (mb.referenceBody == sun && mb.tidallyLocked) + + if (mb.referenceBody == sun && mb.tidallyLocked) { - Vector3d vPos = incNaN ? v.transform.position : v.orbitDriver.pos + mb.position; - Vector3d sunV = sun.position - vPos; + Vector3d vPos = incNaN ? (Vector3d)v.transform.position : v.orbitDriver.pos + mb.position; // We have to refind orbit pos in case inc is NaN - __result = Vector3d.Dot(sunV, mb.position - vPos) > 0d ? mb.rotationPeriod : 0d; + return Vector3d.Dot(sunVec, mb.position - vPos) < 0 ? 0 : 1.0; } - else - { - __result = mb.rotationPeriod * 0.5d; - } - return false; + + // Just assume half the body's rotation period (note that + // for landed vessels, the orbital period is considered the + // body's rotation period). + return 0.5 * mb.rotationPeriod; } double e = obt.eccentricity; @@ -154,11 +172,9 @@ internal static bool Prefix_ShadowPeriod(Vessel v, ref double __result) { // This is wrong, of course, but given the speed of an escape trajectory // you'll be in shadow for a very miniscule fraction of the period. - __result = 0d; - return false; + return 0; } Vector3d planeNormal = Vector3d.Cross(v.orbitDriver.vel, -v.orbitDriver.pos).normalized; - Vector3d sunVec = Planetarium.fetch.Sun.position - (v.mainBody.position + v.orbitDriver.pos).normalized; double sunDot = Math.Abs(Vector3d.Dot(sunVec, planeNormal)); double betaAngle = Math.PI * 0.5d - Math.Acos(sunDot); @@ -167,60 +183,86 @@ internal static bool Prefix_ShadowPeriod(Vessel v, ref double __result) // Now, branch depending on if we're in a low-ecc orbit // We check locally for betaStar because we might bail early in the Kerbalism case + double frac; if (e < 0.1d) - __result = FracEclipseCirc(betaAngle, a, R); + frac = FracEclipseCircular(betaAngle, a, R); else - __result = FracEclipseKerbalism(v, betaAngle, a, R, e, sunVec); - - __result *= obt.period; + frac = FracEclipseElliptical(v, betaAngle, a, R, e, sunVec); - return false; + return frac; } - internal static double FracEclipseCirc(double betaAngle, double sma, double R) + /// + /// This computes eclipse fraction for circular orbits + /// (well, realy circular _low_ orbits, but at higher altitudes + /// you're not spending much time in shadow anyway). + /// + /// The beta angle (angle between the solar normal and its projection on the orbital plane) + /// The semi-major axis + /// The body's radius + /// + private static double FracEclipseCircular(double betaAngle, double sma, double R) { // from https://commons.erau.edu/cgi/viewcontent.cgi?article=1412&context=ijaaa + // beta* is the angle above which there is no occlusion of the orbit double betaStar = Math.Asin(R / sma); if (Math.Abs(betaAngle) >= betaStar) - return 0d; + return 0; double avgHeight = sma - R; - return (1d / Math.PI) * Math.Acos(Math.Sqrt(avgHeight * avgHeight + 2 * R * avgHeight) / (sma * Math.Cos(betaAngle))); + return (1.0 / Math.PI) * Math.Acos(Math.Sqrt(avgHeight * avgHeight + 2.0 * R * avgHeight) / (sma * Math.Cos(betaAngle))); } - internal static double FracEclipseKerbalism(Vessel v, double betaAngle, double a, double R, double e, Vector3d sunVec) + /// + /// An analytic solution to the fraction of an orbit eclipsed by its primary + /// + /// The vessel + /// The beta angle (angle between the solar normal and its projection on the orbital plane) + /// semi-major axis + /// body radius + /// eccentricity + /// The normalized vector to the sun + /// + private static double FracEclipseElliptical(Vessel v, double betaAngle, double a, double R, double e, Vector3d sunVec) { var obt = v.orbit; double b = obt.semiMinorAxis; // Just bail if we were going to report NaN, or we're in a weird state // We've likely avoided this already due to the eccentricity check in the main call, though if (a < b || b < R) - return 0d; + return 0; // Compute where the Pe is with respect to the sun Vector3d PeToBody = -Planetarium.Zup.WorldToLocal(obt.semiLatusRectum / (1d + e) * obt.OrbitFrame.X).xzy; Vector3d orthog = Vector3d.Cross(obt.referenceBody.GetFrameVel().xzy.normalized, sunVec); Vector3d PeToBodyProj = (PeToBody - orthog * Vector3d.Dot(PeToBody, orthog)).normalized; + // Use these to calculate true anomaly for this projected orbit double tA = Math.Acos(Vector3d.Dot(sunVec, PeToBodyProj)); // Get distance to ellipse edge - double r = a * (1d - e * e) / (1 + e * Math.Cos(tA)); + double r = a * (1.0 - e * e) / (1.0 + e * Math.Cos(tA)); double betaStar = Math.Asin(R / r); double absBeta = Math.Abs(betaAngle); if (absBeta >= betaStar) return 0d; - double halfEclipsedv = Math.Asin(R / r); - double vAhead = tA + halfEclipsedv; - double vBehind = tA - halfEclipsedv; - double sqrtep = Math.Sqrt(1d + e); - double sqrten = Math.Sqrt(1d - e); - double Eahead = 2d * Math.Atan2(sqrten * Math.Sin(vAhead * 0.5d), sqrtep * Math.Cos(vAhead * 0.5d)); - double Mahead = Eahead - e * Math.Sin(Eahead); - double Ebehind = 2d * Math.Atan2(sqrten * Math.Sin(vBehind * 0.5d), sqrtep * Math.Cos(vBehind * 0.5d)); - double Mbehind = Ebehind - e * Math.Sin(Ebehind); - double eclipseFrac = (Mahead - Mbehind) / (2d * Math.PI); + // Get the vector to the center of the eclipse + double vecToHalfEclipsePortion = Math.Asin(R / r); + // Get the true anomalies at the front and rear of the eclipse portion + double vAhead = tA + vecToHalfEclipsePortion; + double vBehind = tA - vecToHalfEclipsePortion; + vAhead *= 0.5; + vBehind *= 0.5; + double ePlusOneSqrt = Math.Sqrt(1 + e); + double eMinusOneSqrt = Math.Sqrt(1 - e); + // Calculate eccentric and mean anomalies + double EAAhead = 2.0 * Math.Atan2(eMinusOneSqrt * Math.Sin(vAhead), ePlusOneSqrt * Math.Cos(vAhead)); + double MAhead = EAAhead - e * Math.Sin(EAAhead); + double EABehind = 2.0 * Math.Atan2(eMinusOneSqrt * Math.Sin(vBehind), ePlusOneSqrt * Math.Cos(vBehind)); + double Mbehind = EABehind - e * Math.Sin(EABehind); + // Finally, calculate the eclipse fraction from mean anomalies + double eclipseFrac = (MAhead - Mbehind) / (2.0 * Math.PI); // This is not quite correct I think, but it'll be close enough. // We just lerp between 0 occlusion at beta = betaStar, and full occlusion // at beta = 0. This takes advantage of the difference 1 degree makes being larger @@ -229,122 +271,55 @@ internal static double FracEclipseKerbalism(Vessel v, double betaAngle, double a return eclipseFrac * absBeta / betaStar; } - [HarmonyPrefix] - [HarmonyPatch("SampleSunFactor")] - internal static bool Prefix_SampleSunFactor(Vessel v, double elapsedSeconds, ref double __result) - { - __result = SampleSunFactor(v, elapsedSeconds); - return false; - } - - private static readonly List _cbPositions = new List(); - private static readonly List _cbParents = new List(); - private static readonly List _occluderToPos = new List(); - private static readonly List _cbSLRs = new List(); - - private static void InitBodies() - { - int c = FlightGlobals.Bodies.Count; - if (_cbPositions.Count == c) - return; - - _cbPositions.Clear(); - _cbParents.Clear(); - _cbSLRs.Clear(); - if (_cbPositions.Capacity < c) - _cbPositions.Capacity = c; - if (_cbParents.Capacity < c) - _cbParents.Capacity = c; - if (_cbSLRs.Capacity < c) - _cbSLRs.Capacity = c; - for (int i = 0; i < c; ++i) - { - var cb = FlightGlobals.Bodies[i]; - var parent = cb.orbitDriver?.orbit?.referenceBody; - if (parent != null && parent != cb) - { - _cbParents.Add(FlightGlobals.GetBodyIndex(parent)); - _cbSLRs.Add(cb.orbit.semiLatusRectum); - } - else - { - _cbParents.Add(-1); - _cbSLRs.Add(1d); - } - _cbPositions.Add(new Vector3d()); - } - } - - internal static void FillCBPositionsAtUT(double ut, List occluders) - { - // Start from unknown positions - for (int i = _cbPositions.Count; i-- > 0;) - _cbPositions[i] = new Vector3d(double.MaxValue, double.MaxValue); - - // Fill positions at UT, recursively (skipping calculated parents) - for (int i = occluders.Count; i-- > 0;) - _FillCBPositionAtUT(_occluderToPos[i], ut); - - - } - internal static void _FillCBPositionAtUT(int i, double ut) + /// + /// This expects to be called repeatedly + /// + public static double SampleSunFactor(Vessel v, double elapsedSeconds, CelestialBody sun) { - if (_cbPositions[i].x != double.MaxValue) - return; - - var cb = FlightGlobals.Bodies[i]; - int pIdx = _cbParents[i]; - if (pIdx == -1) - { - _cbPositions[i] = cb.position; - return; - } - _FillCBPositionAtUT(pIdx, ut); - _cbPositions[i] = _cbPositions[pIdx] + fastGetRelativePositionAtUT(cb.orbit, ut, _cbSLRs[i]); - } + UnityEngine.Profiling.Profiler.BeginSample("Kerbalism.Sim.SunFactor2"); - internal static double SampleSunFactor(Vessel v, double elapsedSeconds) - { bool isSurf = Lib.Landed(v); - if (v.orbitDriver == null || (!isSurf && (v.orbit == null || double.IsNaN(v.orbit.inclination)))) + if (v.orbitDriver == null || v.orbitDriver.orbit == null || (!isSurf && double.IsNaN(v.orbit.inclination))) + { + UnityEngine.Profiling.Profiler.EndSample(); return 1d; // fail safe - - UnityEngine.Profiling.Profiler.BeginSample("Kerbalism.Sim.SunFactor2"); + } int sunSamples = 0; var now = Planetarium.GetUniversalTime(); var vd = v.KerbalismData(); - CelestialBody sun = vd.EnvMainSun.SunData.body; - int sunIdx = FlightGlobals.GetBodyIndex(sun); List occluders = vd.EnvVisibleBodies; // set up CB position caches - InitBodies(); - foreach (var cb in occluders) - { - _occluderToPos.Add(FlightGlobals.GetBodyIndex(cb)); - } + bodyCache.SetForOccluders(occluders); // Set max time to calc double maxCalculation = elapsedSeconds * 1.01d; // cache values for speed double semiLatusRectum = 0d; - int bodyIdx = FlightGlobals.GetBodyIndex(v.orbit.referenceBody); - CelestialBody mb; - Vector3d surfPos = new Vector3d(); + CelestialBody mb = v.mainBody; + Vector3d surfPos; + Vector3d polarAxis; if (isSurf) { - mb = v.mainBody; - surfPos = v.mainBody.GetRelSurfacePosition(v.latitude, v.longitude, v.altitude); + surfPos = mb.GetRelSurfacePosition(v.latitude, v.longitude, v.altitude); + // Doing this manually instead of swizzling surfPos avoids one of the two swizzles + surfPos = (surfPos.x * mb.BodyFrame.X + surfPos.z * mb.BodyFrame.Y + surfPos.y * mb.BodyFrame.Z).xzy; + + // This will not be quite correct for Principia but at least it's + // using the BodyFrame, which Principia clobbers, rather than the + // transform. + polarAxis = mb.BodyFrame.Rotation.swizzle * Vector3d.up; } else { - mb = null; semiLatusRectum = v.orbit.semiLatusRectum; maxCalculation = Math.Min(maxCalculation, v.orbit.period); + surfPos = new Vector3d(); + polarAxis = new Vector3d(); } // Set up timimg @@ -364,65 +339,79 @@ internal static double SampleSunFactor(Vessel v, double elapsedSeconds) for (int i = sampleCount; i-- > 0;) { double ut = now - i * stepLength; - FillCBPositionsAtUT(ut, occluders); + bodyCache.SetForUT(ut, occluders); + Vector3d bodyPos = bodyCache.GetBodyPosition(mb.flightGlobalsIndex); Vector3d pos; - if (!isSurf) + if (isSurf) { - pos = _cbPositions[bodyIdx] + fastGetRelativePositionAtUT(v.orbit, ut, semiLatusRectum); + // Rotate the surface position based on where the body would have rotated in the past + // Note: rotation is around *down* so we flip the sign of the rotation + pos = QuaternionD.AngleAxis(mb.rotPeriodRecip * i * stepLength * 360d, polarAxis) * surfPos; } else { - // Doing this manually instead of calling LocalToWorld avoids a double swizzle (was LocalToWorld(surfPos.xzy).xzy ) - pos = surfPos.x * mb.BodyFrame.X + surfPos.y * mb.BodyFrame.Z + surfPos.z * mb.BodyFrame.Y; - // Now rotate the pos based on where the body would have rotated in the past - pos = QuaternionD.AngleAxis(mb.rotPeriodRecip * -i * stepLength * 360d, mb.transform.up) * pos; - pos += _cbPositions[bodyIdx]; // and apply the position + pos = FastGetRelativePositionAtUT(v.orbit, ut, semiLatusRectum); } - bool vis = IsSunVisibleAtTime(v, pos, sun, sunIdx, occluders, ut); + // Apply the body's position + pos += bodyPos; + + bool vis = IsSunVisibleAtTime(v, pos, sun, occluders, isSurf); if (vis) ++sunSamples; } - _occluderToPos.Clear(); UnityEngine.Profiling.Profiler.EndSample(); double sunFactor = (double)sunSamples / (double)sampleCount; + //Lib.Log("Vessel " + v + " sun factor: " + sunFactor + " " + sunSamples + "/" + sampleCount + " #s=" + sampleCount + " e=" + elapsedSeconds + " step=" + stepLength); return sunFactor; } - // We have to reimplement this code because we need to check at a specific time - internal static bool IsSunVisibleAtTime(Vessel vessel, Vector3d vesselPos, CelestialBody sun, int sunIdx, List occluders, double UT) + /// + /// A version of IsBodyVisibleAt that is optimized for suns + /// and supports using arbitrary time (assuming bodyCache is set) + /// + /// + /// Vessel position at time + /// + /// The body index of the sun + /// + /// + /// is the vessel landed + /// + internal static bool IsSunVisibleAtTime(Vessel vessel, Vector3d vesselPos, CelestialBody sun, List occluders, bool isSurf) { // generate ray parameters - Vector3d sunPos = _cbPositions[sunIdx] - vesselPos; + Vector3d sunPos = bodyCache.GetBodyPosition(sun.flightGlobalsIndex) - vesselPos; var sunDir = sunPos; var sunDist = sunDir.magnitude; sunDir /= sunDist; sunDist -= sun.Radius; // for very small bodies the analytic method is very unreliable at high latitudes - // So we use a modified version of the analytic method + // So we use a modified version of the analytic method (unlike IsBodyVisible) bool ignoreMainbody = false; - if (Lib.Landed(vessel) && vessel.mainBody.Radius < 100000.0) + if (isSurf && vessel.mainBody.Radius < 100000.0) { ignoreMainbody = true; - Vector3d mainBodyPos = _cbPositions[FlightGlobals.GetBodyIndex(vessel.mainBody)]; + Vector3d mainBodyPos = bodyCache.GetBodyPosition(vessel.mainBody.flightGlobalsIndex); Vector3d mainBodyDir = (mainBodyPos - vesselPos).normalized; double dotSunBody = Vector3d.Dot(mainBodyDir, sunDir); Vector3d mainBodyDirProjected = mainBodyDir * dotSunBody; // Assume the sun is far enough away that we can treat the line from the vessel - // to the sine as parallel to the line from the body center to the sun, which means + // to the sun as parallel to the line from the body center to the sun, which means // we can ignore testing further if we're very close to the plane orthogonal to the - // sun vector, and we only care if the dot is positive - if (mainBodyDirProjected.sqrMagnitude > 0.0001d && dotSunBody > 0d) // approx half a degree from the pole + // sun vector but on the opposite side of the body from the sun. + // We don't strictly test dot to give ourselves approx half a degree of slop + if (mainBodyDirProjected.sqrMagnitude > 0.0001d && dotSunBody > 0d) { return false; } } // check if the ray intersect one of the provided bodies - for (int i = 0; i < occluders.Count; ++i) + for (int i = occluders.Count; i-- > 0;) { CelestialBody occludingBody = occluders[i]; if (occludingBody == sun) @@ -430,7 +419,7 @@ internal static bool IsSunVisibleAtTime(Vessel vessel, Vector3d vesselPos, Celes if (ignoreMainbody && occludingBody == vessel.mainBody) continue; - Vector3d toBody = _cbPositions[_occluderToPos[i]] - vesselPos; + Vector3d toBody = bodyCache.GetBodyPosition(occludingBody.flightGlobalsIndex) - vesselPos; // projection of origin->body center ray over the raytracing direction double k = Vector3d.Dot(toBody, sunDir); // the ray doesn't hit body if its minimal analytical distance along the ray is less than its radius @@ -443,7 +432,136 @@ internal static bool IsSunVisibleAtTime(Vessel vessel, Vector3d vesselPos, Celes return true; } - internal static Vector3d fastGetRelativePositionAtUT(Orbit orbit, double UT, double semiLatusRectum) + /// + /// A cache to speed calculation of body positions at a given UT, based on + /// as set of occluders. Used when calculating solar exposure at analytic rates. + /// This creates storage for each body in FlightGlobals, but only caches + /// a lookup from occluder to body index, and then for each relevant occluder + /// and its parents a lookup to each parent (and on up the chain) and the + /// semilatus rectum. Then when set for a UT, it calculates positions + /// for each occluder on up the chain to the root CB. + /// + public class BodyCache + { + private Vector3d[] positions = null; + private int[] parents; + private double[] semiLatusRectums; + + public Vector3d GetBodyPosition(int idx) { return positions[idx]; } + + /// + /// Check and, if uninitialized, setup the body caches + /// + private void CheckInitBodies() + { + int c = FlightGlobals.Bodies.Count; + if (positions != null && positions.Length == c) + return; + + positions = new Vector3d[c]; + parents = new int[c]; + semiLatusRectums = new double[c]; + + for (int i = 0; i < c; ++i) + { + var cb = FlightGlobals.Bodies[i]; + // Set parent index lookup + var parent = cb.orbitDriver?.orbit?.referenceBody; + if (parent != null && parent != cb) + { + parents[i] = parent.flightGlobalsIndex; + } + else + { + parents[i] = -1; + } + } + } + + /// + /// Initialize the cache for a set of occluders. This + /// will set up the lookups for the occluder bodies and + /// cache the semi-latus recturm for each body and its + /// parents + /// + /// + public void SetForOccluders(List occluders) + { + CheckInitBodies(); + + // Now clear all SLRs and then set only the relevant ones + // (i.e. the occluders, their parents, their grandparents, etc) + for (int i = semiLatusRectums.Length; i-- > 0;) + semiLatusRectums[i] = double.MaxValue; + for (int i = occluders.Count; i-- > 0;) + SetSLRs(occluders[i].flightGlobalsIndex); + } + + private void SetSLRs(int i) + { + // Check if set + if (semiLatusRectums[i] != double.MaxValue) + return; + + // Check if parent + int pIdx = parents[i]; + if (pIdx == -1) + { + semiLatusRectums[i] = 1d; + return; + } + + semiLatusRectums[i] = FlightGlobals.Bodies[i].orbit.semiLatusRectum; + SetSLRs(pIdx); + } + + /// + /// Set the occluder body positions at the given UT + /// + /// + public void SetForUT(double ut, List occluders) + { + // Start from unknown positions + for (int i = positions.Length; i-- > 0;) + positions[i] = new Vector3d(double.MaxValue, double.MaxValue); + + // Fill positions at UT, recursively (skipping calculated parents) + for (int i = occluders.Count; i-- > 0;) + SetForUTInternal(occluders[i].flightGlobalsIndex, ut); + } + + private void SetForUTInternal(int i, double ut) + { + // If we've already been here, bail + if (positions[i].x != double.MaxValue) + return; + + // Check if we have a parent. If not + // position is just the body's position + var cb = FlightGlobals.Bodies[i]; + int pIdx = parents[i]; + if (pIdx == -1) + { + positions[i] = cb.position; + return; + } + + // If we do have a parent, recurse and then + // set position based on newly-set parent's pos + SetForUTInternal(pIdx, ut); + positions[i] = positions[pIdx] + FastGetRelativePositionAtUT(cb.orbit, ut, semiLatusRectums[i]); + } + } + + /// + /// A fast version of KSP's GetRelativePositionAtUT. + /// It skips a bunch of steps and uses cached values + /// + /// + /// + /// + /// + private static Vector3d FastGetRelativePositionAtUT(Orbit orbit, double UT, double semiLatusRectum) { double T = orbit.getObtAtUT(UT); @@ -456,6 +574,8 @@ internal static Vector3d fastGetRelativePositionAtUT(Orbit orbit, double UT, dou Vector3d pos = semiLatusRectum / (1.0 + orbit.eccentricity * cos) * (orbit.OrbitFrame.X * cos + orbit.OrbitFrame.Y * sin); return Planetarium.Zup.WorldToLocal(pos).xzy; } + + static readonly BodyCache bodyCache = new BodyCache(); } #endregion @@ -468,6 +588,8 @@ internal static Vector3d fastGetRelativePositionAtUT(Orbit orbit, double UT, dou [HarmonyPatch(typeof(SolarPanelFixer))] internal class PatchKerbalism_SolarPanelFixer { + static bool Prepare() => KerbalismUtils.IsValidToPatch(new Version(3, 17, int.MaxValue, int.MaxValue), true); + [HarmonyPostfix] [HarmonyPatch("Update")] internal static void Postfix_Update(SolarPanelFixer __instance) @@ -492,6 +614,8 @@ internal static void Postfix_Update(SolarPanelFixer __instance) [HarmonyPatch(typeof(Specifics))] internal class PatchKerbalism_Specifics { + static bool Prepare() => KerbalismUtils.IsValidToPatch(new Version(3, 17, int.MaxValue, int.MaxValue), true); + private static string _ecName; private static bool _needName = true; @@ -521,86 +645,6 @@ internal static void Prefix_Add(ref string label, ref string value) } } - // The following patches don't work, and are done instead - // by the hacky workarounds below them -#if disabled - // This throws: - // FormatException: Method static System.Void KERBALISM.Planner.Planner::AddSubPanelEC(KERBALISM.Panel p) cannot be patched. Reason: The type initializer for 'KERBALISM.Planner.Planner' threw an exception. - // HarmonyLib.PatchFunctions.UpdateWrapper - [HarmonyPatch(typeof(KERBALISM.Planner.Planner))] - internal class PatchKerbalism_Planner - { - [HarmonyPrefix] - [HarmonyPatch("AddSubPanelEC")] - internal static bool Prefix_AddSubPanelEC(Panel p, KERBALISM.Planner.ResourceSimulator ___resource_sim) - { - KERBALISM.Planner.SimulatedResource simulatedResource = ___resource_sim.Resource("ElectricCharge"); - string tooltip = simulatedResource.Tooltip(); - p.AddSection(Local.Planner_ELECTRICCHARGE); - p.AddContent(Local.Planner_storage, Lib.HumanReadableAmount(simulatedResource.storage), tooltip); - p.AddContent(Local.Planner_consumed, KSPUtil.PrintSI(simulatedResource.consumed * 1000d, "W", 3), tooltip); - p.AddContent(Local.Planner_produced, KSPUtil.PrintSI(simulatedResource.produced * 1000d, "W", 3), tooltip); - p.AddContent(Local.Planner_duration, Lib.HumanReadableDuration(simulatedResource.Lifetime())); - - return false; - } - } - - // This fails the same way. - - [HarmonyPatch(typeof(KERBALISM.Planner.Planner))] - internal class PatchKerbalism_Planner - { - private static readonly FieldInfo _resSimField = typeof(KERBALISM.Planner.Planner).GetField("resource_sim", AccessTools.all); - private static bool _needField = true; - private static KERBALISM.Planner.ResourceSimulator _resource_sim; - - private static readonly MethodInfo _addSubECMethod = typeof(KERBALISM.Planner.Planner).GetMethod("AddSubPanelEC", AccessTools.all); - private static readonly MethodInfo _replaceMethod = typeof(PatchKerbalism_Planner).GetMethod("ReplacementAddSubPanelEC", AccessTools.all); - - [HarmonyTranspiler] - [HarmonyPatch("Update")] - internal static IEnumerable Transpiler(IEnumerable instructions) - { - List code = new List(instructions); - for (int i = 0; i < code.Count; ++i) - { - if (code[i].Calls(_addSubECMethod)) - { - code[i] = new CodeInstruction(System.Reflection.Emit.OpCodes.Call, _replaceMethod); - break; - } - } - return code; - } - - internal static void ReplacementAddSubPanelEC(Panel p) - { - if (_needField) - { - _resource_sim = (KERBALISM.Planner.ResourceSimulator)_resSimField.GetValue(null); - _needField = false; - } - - KERBALISM.Planner.SimulatedResource simulatedResource = _resource_sim.Resource("ElectricCharge"); - string tooltip = simulatedResource.Tooltip(); - string[] splitTip = tooltip.Split('\n'); - for (int i = 0; i < splitTip.Length; ++i) - { - if (splitTip[i].Length > 0) - KerbalismUtils.HumanRateToSI(ref splitTip[i], "W", 1000d); - } - tooltip = string.Join("\n", splitTip); - - p.AddSection(Local.Planner_ELECTRICCHARGE); - p.AddContent(Local.Planner_storage, Lib.HumanReadableAmount(simulatedResource.storage), tooltip); - p.AddContent(Local.Planner_consumed, KSPUtil.PrintSI(simulatedResource.consumed * 1000d, "W", 4), tooltip); - p.AddContent(Local.Planner_produced, KSPUtil.PrintSI(simulatedResource.produced * 1000d, "W", 4), tooltip); - p.AddContent(Local.Planner_duration, Lib.HumanReadableDuration(simulatedResource.Lifetime())); - } - } -#endif - /// /// This exists to signal that we just ran the Analyze method. It's /// only run in one place, right before we create the EC subpanel @@ -609,6 +653,8 @@ internal static void ReplacementAddSubPanelEC(Panel p) [HarmonyPatch(typeof(KERBALISM.Planner.ResourceSimulator))] internal class PatchKerbalism_Planner_ResourceSimulator { + static bool Prepare() => KerbalismUtils.IsValidToPatch(new Version(3, 17, int.MaxValue, int.MaxValue), true); + public static bool JustRanAnalyze = false; [HarmonyPostfix] [HarmonyPatch("Analyze")] @@ -628,6 +674,8 @@ internal static void Postfix_Analyze() [HarmonyPatch(typeof(KERBALISM.Panel))] internal class PatchKerbalism_Panel { + static bool Prepare() => KerbalismUtils.IsValidToPatch(new Version(3, 17, int.MaxValue, int.MaxValue), true); + [HarmonyPrefix] [HarmonyPatch("AddContent")] internal static void Prefix_AddContent(string label, ref string value) @@ -657,6 +705,8 @@ internal static void Prefix_AddContent(string label, ref string value) [HarmonyPatch(typeof(KERBALISM.Planner.SimulatedResource))] internal class PatchKerbalism_Planner_SimulatedResource { + static bool Prepare() => KerbalismUtils.IsValidToPatch(new Version(3, 17, int.MaxValue, int.MaxValue), true); + public static bool IsEC = false; [HarmonyPrefix] @@ -683,6 +733,8 @@ internal static void Postfix_Tooltip() [HarmonyPatch(typeof(Telemetry))] internal class PatchKerbalism_Telemetry { + static bool Prepare() => KerbalismUtils.IsValidToPatch(new Version(3, 17, int.MaxValue, int.MaxValue), true); + public static bool IsRenderSupplies = false; public static bool IsEC = false; @@ -717,6 +769,8 @@ internal static void Postfix_Render_supplies() [HarmonyPatch(typeof(Lib))] internal class PatchKerbalism_Lib { + static bool Prepare() => KerbalismUtils.IsValidToPatch(new Version(3, 17, int.MaxValue, int.MaxValue), true); + private static string _ecName; private static bool _needName = true; @@ -757,4 +811,50 @@ internal static void Prefix_SpacesOnCaps(string s) } } #endregion + + [HarmonyPatch(typeof(ExperimentRequirements))] + internal class PatchKerbalism_ExperimentRequirements + { + // Don't even bother to patch if Principia isn't installed. + // Also, of course, don't patch if Kerbalism 3.18 is out with this fix inside it. + static bool Prepare() => KCTUtilities.IsPrincipiaInstalled && KerbalismUtils.IsValidToPatch(new Version(3, 17, int.MaxValue, int.MaxValue), true); + + private static double PrincipiaCorrectInclination(Orbit o) + { + if (KCTUtilities.IsPrincipiaInstalled && o.referenceBody != (FlightGlobals.currentMainBody ?? Planetarium.fetch.Home)) + { + Vector3d polarAxis = o.referenceBody.BodyFrame.Z; + + double hSqrMag = o.h.sqrMagnitude; + if (hSqrMag == 0d) + { + return Math.Acos(Vector3d.Dot(polarAxis, o.pos) / o.pos.magnitude) * (180.0 / Math.PI); + } + else + { + Vector3d orbitZ = o.h / Math.Sqrt(hSqrMag); + return Math.Atan2((orbitZ - polarAxis).magnitude, (orbitZ + polarAxis).magnitude) * (2d * (180.0 / Math.PI)); + } + } + else + { + return o.inclination; + } + } + + [HarmonyPrefix] + [HarmonyPatch("TestRequirements")] + internal static void Prefix_TestRequirements(Vessel v, out double __state) + { + __state = v.orbit.inclination; + v.orbit.inclination = PrincipiaCorrectInclination(v.orbit); + } + + [HarmonyPostfix] + [HarmonyPatch("TestRequirements")] + internal static void Postfix_TestRequirements(Vessel v, double __state) + { + v.orbit.inclination = __state; + } + } } \ No newline at end of file diff --git a/Source/RP0/Maintenance/MaintenanceHandler.cs b/Source/RP0/Maintenance/MaintenanceHandler.cs index a2e31553e01..87e3d9e3995 100644 --- a/Source/RP0/Maintenance/MaintenanceHandler.cs +++ b/Source/RP0/Maintenance/MaintenanceHandler.cs @@ -24,9 +24,7 @@ public class MaintenanceHandler : ScenarioModule public static MaintenanceHandler Instance { get; private set; } = null; private bool _isFirstLoad = true; - private static readonly Dictionary _facilityLevelCosts = new Dictionary(); - public static void ClearFacilityCosts() { _facilityLevelCosts.Clear(); } - + public static EventVoid OnRP0MaintenanceChanged = new EventVoid("OnRP0MaintenanceChanged"); [KSPField(isPersistant = true)] @@ -48,7 +46,6 @@ public class MaintenanceHandler : ScenarioModule private bool _wasWarpingHigh = false; private int _frameCount = 0; - private bool _waitingForLevelLoad = false; #region Component costs @@ -173,32 +170,6 @@ public void Start() OnRP0MaintenanceChanged.Add(ScheduleMaintenanceUpdate); } - protected double SumCosts(float[] costs, int idx) - { - double s = 0d; - for (int i = idx + 1; i-- > 0;) - s += costs[i]; - - return s; - } - - protected double SumCosts(float[] costs, float fractionalIdx) - { - double s = 0d; - int i = (int)fractionalIdx; - if (i != fractionalIdx && i + 1 < costs.Length) - { - float fractionOverFullLvl = fractionalIdx - i; - float fractionCost = costs[i + 1] * fractionOverFullLvl; - s = fractionCost; - } - - for (; i >= 0; i--) - s += costs[i]; - - return s; - } - public void ScheduleMaintenanceUpdate() { nextUpdate = 0d; @@ -354,8 +325,6 @@ public void UpdateUpkeep() UpdateKCTSalaries(); - EnsureFacilityLvlCostsLoaded(); - LCsCostPerDay = 0d; foreach (var ksc in SpaceCenterManagement.Instance.KSCs) { @@ -368,14 +337,14 @@ public void UpdateUpkeep() if (Database.LockedFacilities.Contains(facility)) continue; - if (!_facilityLevelCosts.TryGetValue(facility, out float[] facCosts)) + if (!Database.FacilityLevelCosts.TryGetValue(facility, out var facCosts)) continue; - double cost = ComputeDailyMaintenanceCost(SumCosts(facCosts, KCTUtilities.GetFacilityLevel(facility))); + double cost = ComputeDailyMaintenanceCost(KCTUtilities.SumThrough(facCosts, KCTUtilities.GetFacilityLevel(facility))); double ratio = GetFacilityUpgradeRatio(facility); if (ratio > 0d) { - double newCost = ComputeDailyMaintenanceCost(SumCosts(facCosts, 1 + KCTUtilities.GetFacilityLevel(facility))); + double newCost = ComputeDailyMaintenanceCost(KCTUtilities.SumThrough(facCosts, 1 + KCTUtilities.GetFacilityLevel(facility))); cost = UtilMath.LerpUnclamped(cost, newCost, ratio); } FacilityMaintenanceCosts[facility] = cost; @@ -384,24 +353,21 @@ public void UpdateUpkeep() TrainingUpkeepPerDay = 0d; - if (_facilityLevelCosts.TryGetValue(SpaceCenterFacility.AstronautComplex, out float[] costs)) + if (CrewHandler.Instance?.TrainingCourses != null) { - if (CrewHandler.Instance?.TrainingCourses != null) + foreach (var course in CrewHandler.Instance.TrainingCourses) { - foreach (var course in CrewHandler.Instance.TrainingCourses) - { - if (!course.Started) - continue; - - TrainingDatabase.FillBools(course.Target, Database.SettingsSC.nautUpkeepTrainings, Database.SettingsSC.nautUpkeepTrainingBools); - double trainingTypeCost = GetTrainingCostFromBools(); - Database.SettingsSC.ResetBools(); - TrainingUpkeepPerDay += course.Students.Count * - (Database.SettingsSC.nautTrainingCostPerFacLevel[KCTUtilities.GetFacilityLevel(SpaceCenterFacility.AstronautComplex)] - + trainingTypeCost * Database.SettingsSC.nautTrainingTypeCostMult); - } - TrainingUpkeepPerDay /= 365.25d; + if (!course.Started) + continue; + + TrainingDatabase.FillBools(course.Target, Database.SettingsSC.nautUpkeepTrainings, Database.SettingsSC.nautUpkeepTrainingBools); + double trainingTypeCost = GetTrainingCostFromBools(); + Database.SettingsSC.ResetBools(); + TrainingUpkeepPerDay += course.Students.Count * + (Database.SettingsSC.nautTrainingCostPerFacLevel[KCTUtilities.GetFacilityLevel(SpaceCenterFacility.AstronautComplex)] + + trainingTypeCost * Database.SettingsSC.nautTrainingTypeCostMult); } + TrainingUpkeepPerDay /= 365.25d; } @@ -578,29 +544,6 @@ private void SettingsChanged() UpdateUpkeep(); } - private bool EnsureFacilityLvlCostsLoaded() - { - if(_waitingForLevelLoad) - return false; - - if (_facilityLevelCosts.Count == 0) - { - // Facility level upgrade costs should be loaded only once. These do not change and are actually unavailable - // when outside HomePlanet's SOI and also in the tracking station in some cases. - foreach (UpgradeableFacility facility in FindObjectsOfType()) - { - var costArr = new float[facility.UpgradeLevels.Length]; - for (int i = 0; i < facility.UpgradeLevels.Length; i++) - { - costArr[i] = facility.UpgradeLevels[i].levelCost; - } - _facilityLevelCosts[(SpaceCenterFacility)Enum.Parse(typeof(SpaceCenterFacility), facility.name)] = costArr; - } - RP0Debug.Log($"Updated facilityLevelsCosts, count: {_facilityLevelCosts.Count}"); - } - return true; - } - public double GetSubsidyAmount(double startUT, double endUT) { double delta = endUT - startUT; diff --git a/Source/RP0/Singletons/Database.cs b/Source/RP0/Singletons/Database.cs index ac1ebd91310..585562c2a3c 100644 --- a/Source/RP0/Singletons/Database.cs +++ b/Source/RP0/Singletons/Database.cs @@ -42,7 +42,8 @@ public class Database : MonoBehaviour public static readonly PersistentDictionaryValueTypes NodeTypes = new PersistentDictionaryValueTypes(); public static readonly List LockedFacilities = new List(); public static readonly Dictionary> FacilityLevelCosts = new Dictionary>(); - public static int GetFacilityLevelCount(SpaceCenterFacility fac) { return FacilityLevelCosts.ValueOrDefault(fac)?.Count ?? 0; } + public static int GetFacilityLevelCount(SpaceCenterFacility fac) { return FacilityLevelCosts.ValueOrDefault(fac)?.Count ?? 1; } + public static int GetFacilityLevelCount(string facilityID) { return Database.GetFacilityLevelCount(Database.FacilityIDToFacility.ValueOrDefault(facilityID)); } public static readonly Dictionary FacilityIDToFacility = new Dictionary(); public static readonly Dictionary TechNameToTitle = new Dictionary(); public static readonly Dictionary> TechNameToParents = new Dictionary>(); diff --git a/Source/RP0/SpaceCenter/LaunchComplex/LCData.cs b/Source/RP0/SpaceCenter/LaunchComplex/LCData.cs index b4b60e671d3..7839d12e7ad 100644 --- a/Source/RP0/SpaceCenter/LaunchComplex/LCData.cs +++ b/Source/RP0/SpaceCenter/LaunchComplex/LCData.cs @@ -14,15 +14,30 @@ public enum LaunchComplexType public class LCData { [Persistent] public string Name; + /// + /// Max vessel mass that the LC can support. + /// [Persistent] public float massMax; + /// + /// The mass that LC was originally built with. + /// [Persistent] public float massOrig; [Persistent] public Vector3 sizeMax; [Persistent] public LaunchComplexType lcType = LaunchComplexType.Pad; [Persistent] public bool isHumanRated; [Persistent] public PersistentDictionaryValueTypes resourcesHandled = new PersistentDictionaryValueTypes(); - public float MaxPossibleMass => Mathf.Floor(massOrig * 2f); - public float MinPossibleMass => Mathf.Ceil(massOrig * 0.5f); + /// + /// Max allowable mass that the LC can be upgraded to. + /// + public float MaxPossibleMass => Math.Max(3f, Mathf.Floor(massOrig * 2f)); + /// + /// Min allowable mass that the LC can be downgraded to. + /// + public float MinPossibleMass => Math.Max(1, Mathf.Ceil(massOrig * 0.5f)); + public bool IsMassWithinUpgradeMargin => massMax <= MaxPossibleMass; + public bool IsMassWithinDowngradeMargin => massMax >= MinPossibleMass; + public bool IsMassWithinUpAndDowngradeMargins => IsMassWithinUpgradeMargin && IsMassWithinDowngradeMargin; public static float CalcMassMin(float massMax) => massMax == float.MaxValue ? 0f : Mathf.Floor(massMax * 0.75f); public float MassMin => CalcMassMin(massMax); public static float CalcMassMaxFromMin(float massMin) => Mathf.Ceil(massMin / 0.75f); diff --git a/Source/RP0/SpaceCenter/LaunchComplex/LCEfficiency.cs b/Source/RP0/SpaceCenter/LaunchComplex/LCEfficiency.cs index 2a0cb53b06d..8c99a8e003c 100644 --- a/Source/RP0/SpaceCenter/LaunchComplex/LCEfficiency.cs +++ b/Source/RP0/SpaceCenter/LaunchComplex/LCEfficiency.cs @@ -262,6 +262,10 @@ public static LCEfficiency FindClosest(LCData data, out double bestCloseness) bestItem = e; } } + + if (bestCloseness < 1d && bestCloseness > 0.95d) + bestCloseness = 0.95d; + return bestItem; } diff --git a/Source/RP0/SpaceCenter/Projects/FacilityUpgradeProject.cs b/Source/RP0/SpaceCenter/Projects/FacilityUpgradeProject.cs index fe11b7792cb..b4335314039 100644 --- a/Source/RP0/SpaceCenter/Projects/FacilityUpgradeProject.cs +++ b/Source/RP0/SpaceCenter/Projects/FacilityUpgradeProject.cs @@ -66,7 +66,7 @@ public void Apply() facility.SetLevel(upgradeLevel); } - int newLvl = KCTUtilities.GetBuildingUpgradeLevel(id); + int newLvl = KCTUtilities.GetFacilityLevel(id); upgradeProcessed = newLvl == upgradeLevel; if (upgradeProcessed) { diff --git a/Source/RP0/SpaceCenter/Projects/VesselProject.cs b/Source/RP0/SpaceCenter/Projects/VesselProject.cs index 72b98583356..89e0ff28f51 100644 --- a/Source/RP0/SpaceCenter/Projects/VesselProject.cs +++ b/Source/RP0/SpaceCenter/Projects/VesselProject.cs @@ -597,7 +597,7 @@ public bool ResourcesOK(LCData stats, List failedReasons = null) return false; pass = false; - failedReasons.Add($"Insufficient {kvp.Key} at LC: {kvp.Value:N0} required, {lcAmount:N0} available. Renovate or Upgrade {(stats.lcType == LaunchComplexType.Pad ? "LC" : "the Hangar")}."); + failedReasons.Add($"Insufficient {kvp.Key} at LC: {kvp.Value:N0} required, {lcAmount:N0} available. Modify {(stats.lcType == LaunchComplexType.Pad ? "LC" : "the Hangar")}."); } return pass; diff --git a/Source/RP0/SpaceCenter/SpaceCenterManagement.cs b/Source/RP0/SpaceCenter/SpaceCenterManagement.cs index 5be36ca7cf6..fba17c1a37a 100644 --- a/Source/RP0/SpaceCenter/SpaceCenterManagement.cs +++ b/Source/RP0/SpaceCenter/SpaceCenterManagement.cs @@ -1546,7 +1546,7 @@ private IEnumerator UpdateFacilityLevels() { if (ActiveSC.ActiveLC.ActiveLPInstance is LCLaunchPad pad) { - if (KCTUtilities.GetBuildingUpgradeLevel(SpaceCenterFacility.LaunchPad) != pad.level) + if (KCTUtilities.GetFacilityLevel(SpaceCenterFacility.LaunchPad) != pad.level) { ActiveSC.ActiveLC.SwitchLaunchPad(ActiveSC.ActiveLC.ActiveLaunchPadIndex, false); pad.UpdateLaunchpadDestructionState(false); diff --git a/Source/RP0/UI/KCT/GUI_Editor.cs b/Source/RP0/UI/KCT/GUI_Editor.cs index cad55bc3e1c..a1e0279e189 100644 --- a/Source/RP0/UI/KCT/GUI_Editor.cs +++ b/Source/RP0/UI/KCT/GUI_Editor.cs @@ -282,8 +282,8 @@ private static void RenderEditorLaunchComplexControls() // _centralWindowPosition.width = 300; // } //} - if (GUILayout.Button(new GUIContent("Upgrade", - $"Upgrade the {(activeLC.LCType == LaunchComplexType.Pad ? "launch complex" : "hangar")} to support the current vessel, keeping existing support where possible.{(canModify ? string.Empty : modifyFailTooltip)}"), + if (GUILayout.Button(new GUIContent("Modify", + $"Modify the {(activeLC.LCType == LaunchComplexType.Pad ? "launch complex" : "hangar")} to support the current vessel, keeping existing support where possible.{(canModify ? string.Empty : modifyFailTooltip)}"), canModify ? GUI.skin.button : _yellowButton)) { if (EditorLogic.fetch.ship.parts.Count == 0) diff --git a/Source/RP0/UI/KCT/GUI_FirstRun.cs b/Source/RP0/UI/KCT/GUI_FirstRun.cs index e6cff1992f2..b7ca9b2a291 100644 --- a/Source/RP0/UI/KCT/GUI_FirstRun.cs +++ b/Source/RP0/UI/KCT/GUI_FirstRun.cs @@ -62,7 +62,7 @@ public static void DrawFirstRun(int windowID) if (!SpaceCenterManagement.Instance.StarterLCBuilding) { GUILayout.Label($"{step++}) Build a starting Launch Complex."); - GUILayout.Label("With a contract accepted, now it's time to create and integrate a vessel to complete it. If it's a rocket, you'll need a launch complex to launch it. Go to the VAB and make your rocket, then click New the Integration Info (was KCT) window. The LC properties will be set to support that vessel. Once you have LCs built you can also modify them the same way, either a simple Upgrade or a bigger Reconstruction. Reconstructions remove support for any vessel but the current, but lead to lower maintenance over time."); + GUILayout.Label("With a contract accepted, now it's time to create and integrate a vessel to complete it. If it's a rocket, you'll need a launch complex to launch it. Go to the VAB and make your rocket, then click New the Integration Info (was KCT) window. The LC properties will be set to support that vessel. Once you have LCs built you can also modify them the same way."); if (GUILayout.Button($"Go to VAB", HighLogic.Skin.button)) { EnterVAB(); diff --git a/Source/RP0/UI/KCT/GUI_NewLC.cs b/Source/RP0/UI/KCT/GUI_NewLC.cs index 8b2e84433d4..a0d4e3ceb98 100644 --- a/Source/RP0/UI/KCT/GUI_NewLC.cs +++ b/Source/RP0/UI/KCT/GUI_NewLC.cs @@ -303,32 +303,43 @@ public static void DrawNewLCWindow(int windowID) if (isModify) { + _newLCData.massOrig = isModify ? activeLC.MassOrig : 0; + int maxMax = (int)_newLCData.MaxPossibleMass; + int maxMin = (int)_newLCData.MinPossibleMass; GUILayout.BeginHorizontal(); - GUILayout.Label("Upgrade Limit for max tng:"); - GUILayout.Label($"{(int)(_newLCData.massOrig * 2f):N0}", GetLabelRightAlignStyle(), GUILayout.ExpandWidth(false)); + if (maxMax < _newLCData.massMax) + GUILayout.Label("Upgrade Limit for max tng:", GetLabelStyleYellow()); + else + GUILayout.Label("Upgrade Limit for max tng:"); + GUILayout.Label($"{maxMax:N0}", + maxMax < _newLCData.massMax ? GetLabelRightAlignStyleYellow() : GetLabelRightAlignStyle(), + GUILayout.ExpandWidth(false)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); - GUILayout.Label("Downgrade Limit for max tng:"); - GUILayout.Label($"{Math.Max(1, (int)(_newLCData.massOrig * 0.5f)):N0}", GetLabelRightAlignStyle(), GUILayout.ExpandWidth(false)); + if (maxMin > _newLCData.massMax) + GUILayout.Label("Downgrade Limit for max tng:", GetLabelStyleYellow()); + else + GUILayout.Label("Downgrade Limit for max tng:"); + GUILayout.Label($"{maxMin:N0}", + maxMin > _newLCData.massMax ? GetLabelRightAlignStyleYellow() : GetLabelRightAlignStyle(), + GUILayout.ExpandWidth(false)); GUILayout.EndHorizontal(); - - } else { _newLCData.massOrig = _newLCData.massMax; - if (_newLCData.massOrig < 1.5f) - _newLCData.massOrig = 1.5f; + int maxMax = (int)_newLCData.MaxPossibleMass; + int maxMin = (int)_newLCData.MinPossibleMass; GUILayout.BeginHorizontal(); GUILayout.Label("Upgrade Limit for max tng:"); - GUILayout.Label($"{Math.Max(3, _newLCData.massOrig * 2):N0}", GetLabelRightAlignStyle(), GUILayout.ExpandWidth(false)); + GUILayout.Label($"{_newLCData.MaxPossibleMass:N0}", GetLabelRightAlignStyle(), GUILayout.ExpandWidth(false)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Downgrade Limit for max tng:"); - GUILayout.Label($"{Math.Max(1, _newLCData.massOrig / 2):N0}", GetLabelRightAlignStyle(), GUILayout.ExpandWidth(false)); + GUILayout.Label($"{_newLCData.MinPossibleMass:N0}", GetLabelRightAlignStyle(), GUILayout.ExpandWidth(false)); GUILayout.EndHorizontal(); } } @@ -429,7 +440,7 @@ public static void DrawNewLCWindow(int windowID) double buildTime = ConstructionProject.CalculateBuildTime(totalCost, oldTotalCost, SpaceCenterFacility.LaunchPad, null); double buildCost = -CurrencyUtils.Funds(TransactionReasonsRP0.StructureConstructionLC, -totalCost); string sBuildTime = KSPUtil.PrintDateDelta(buildTime, includeTime: false); - string costString = isModify ? "Renovate Cost:" : "Build Cost:"; + string costString = isModify ? "Modify Cost:" : "Build Cost:"; GUILayout.BeginHorizontal(); GUILayout.Label(costString, GUILayout.ExpandWidth(false)); GUILayout.Label(new GUIContent($"√{buildCost:N0}", $"Daily: √{(buildCost * 86400d / buildTime):N1}"), GetLabelRightAlignStyle()); @@ -495,7 +506,7 @@ public static void DrawNewLCWindow(int windowID) GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); - if (GUILayout.Button(isModify ? "Renovate" : "Build") && ValidateLCCreationParameters(_newLCData.Name, _newLCData.GetPadFracLevel(), _newLCData.massMax, _newLCData.sizeMax, isModify ? activeLC : null)) + if (GUILayout.Button(isModify ? "Modify" : "Build") && ValidateLCCreationParameters(_newLCData, isModify ? activeLC : null)) { if (HighLogic.LoadedSceneIsEditor && !SpaceCenterManagement.Instance.EditorVessel.MeetsFacilityRequirements(_newLCData, null)) { @@ -781,25 +792,34 @@ private static bool ModifyFailure(out string failedVessels) return failedVessels != string.Empty; } - private static bool ValidateLCCreationParameters(string newName, float fractionalPadLvl, float tonnageLimit, Vector3 curPadSize, LaunchComplex lc) + private static bool ValidateLCCreationParameters(LCData newLCData, LaunchComplex existingLC) { - if (curPadSize == Vector3.zero) + if (newLCData.sizeMax == Vector3.zero) { ScreenMessages.PostScreenMessage("Please enter a valid size"); return false; } - if (lc != null && lc.LCType == LaunchComplexType.Hangar) + if (existingLC != null && existingLC.LCType == LaunchComplexType.Hangar) return true; - if (fractionalPadLvl == -1 || tonnageLimit == 0 || (lc != null && (tonnageLimit < Math.Max(1, (int)lc.MassOrig / 2) || tonnageLimit > lc.MassOrig * 2))) + if (newLCData.GetPadFracLevel() == -1 || newLCData.massMax == 0) { ScreenMessages.PostScreenMessage("Please enter a valid tonnage limit"); - RP0Debug.Log($"Invalid LC tonnage set, fractional: {fractionalPadLvl}, tonnageLimit {tonnageLimit}, orig {(lc != null ? lc.MassOrig : -1f)}"); + RP0Debug.Log($"Invalid LC tonnage set, fractional: {newLCData.GetPadFracLevel()}, tonnageLimit {newLCData.massMax}"); return false; } - if (lc != null && !lc.CanModifyReal) + if (existingLC != null && !newLCData.IsMassWithinUpAndDowngradeMargins) + { + string msg = !newLCData.IsMassWithinUpgradeMargin ? $"Cannot upgrade tonnage above the limit of {newLCData.MaxPossibleMass}t" + : $"Cannot downgrade tonnage below the limit of {newLCData.MinPossibleMass}t"; + ScreenMessages.PostScreenMessage(msg); + RP0Debug.Log($"LC tonnage exceeding upgrade margins, fractional: {newLCData.GetPadFracLevel()}, tonnageLimit {newLCData.massMax}, orig {(existingLC != null ? existingLC.MassOrig : -1f)}"); + return false; + } + + if (existingLC != null && !existingLC.CanModifyReal) { ScreenMessages.PostScreenMessage("Please wait for any reconditioning, rollout, rollback, or recovery to complete"); RP0Debug.Log($"Can't modify LC, recon_rollout in progress"); @@ -807,10 +827,10 @@ private static bool ValidateLCCreationParameters(string newName, float fractiona } // Don't bother with name if it's a modify. - if (lc != null) + if (existingLC != null) return true; - if (string.IsNullOrEmpty(newName)) + if (string.IsNullOrEmpty(newLCData.Name)) { ScreenMessages.PostScreenMessage("Enter a name for the new launch complex"); return false; @@ -819,7 +839,7 @@ private static bool ValidateLCCreationParameters(string newName, float fractiona for (int i = 0; i < SpaceCenterManagement.Instance.ActiveSC.LaunchComplexes.Count; i++) { var lp = SpaceCenterManagement.Instance.ActiveSC.LaunchComplexes[i]; - if (string.Equals(lp.Name, newName, StringComparison.OrdinalIgnoreCase)) + if (string.Equals(lp.Name, newLCData.Name, StringComparison.OrdinalIgnoreCase)) { ScreenMessages.PostScreenMessage("Another launch complex with the same name already exists"); return false; diff --git a/Source/RP0/UI/ProceduralAvionicsWindow.cs b/Source/RP0/UI/ProceduralAvionicsWindow.cs index 2582326680b..0affd56fa1d 100644 --- a/Source/RP0/UI/ProceduralAvionicsWindow.cs +++ b/Source/RP0/UI/ProceduralAvionicsWindow.cs @@ -171,7 +171,7 @@ private void WindowFunction(int windowID) if (float.TryParse(ControllableMass, out _newControlMass)) { float avionicsMass = _module.GetShieldedAvionicsMass(_newControlMass); - GUILayout.Label($" ({avionicsMass * 1000:0.#} kg)", HighLogic.Skin.label, GUILayout.Width(150)); + GUILayout.Label($" ({MathUtils.PrintMass(avionicsMass)})", HighLogic.Skin.label, GUILayout.Width(150)); } if (oldControlMass != _newControlMass) @@ -187,12 +187,15 @@ private void WindowFunction(int windowID) GUILayout.BeginHorizontal(GUILayout.Width(250)); GUILayout.Label("EC amount: ", HighLogic.Skin.label, GUILayout.Width(150)); _sECAmount = GUILayout.TextField(_sECAmount, HighLogic.Skin.textField); + GUILayout.Label("kJ", HighLogic.Skin.label); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(GUILayout.MaxWidth(50)); if (float.TryParse(_sECAmount, out float ecAmount)) { - GUILayout.Label($" ({_ecTank.mass * ecAmount:0.#} kg)", HighLogic.Skin.label, GUILayout.Width(150)); + float ekW = ModuleProceduralAvionics.GetEnabledkW(_module.CurrentProceduralAvionicsTechNode, _newControlMass); + float dkW = _module.CurrentProceduralAvionicsTechNode.disabledPowerFactor * ekW; + GUILayout.Label($" ({MathUtils.PrintMass(_ecTank.mass * ecAmount / _ecTank.utilization)}, {ModuleProceduralAvionics.BuildPowerString(ekW, dkW)})", HighLogic.Skin.label, GUILayout.Width(150)); } GUILayout.EndHorizontal(); GUILayout.EndHorizontal(); @@ -205,7 +208,7 @@ private void WindowFunction(int windowID) GUI.enabled = false; _sExtraVolume = GUILayout.TextField(_sExtraVolume, HighLogic.Skin.textField); GUI.enabled = true; - GUILayout.Label("l", HighLogic.Skin.label); + GUILayout.Label("L", HighLogic.Skin.label); GUILayout.EndHorizontal(); if (_showROTankSizeWarning) diff --git a/Source/RP0/Utilities/Formula.cs b/Source/RP0/Utilities/Formula.cs index 13776f18f18..85b485a9c5c 100644 --- a/Source/RP0/Utilities/Formula.cs +++ b/Source/RP0/Utilities/Formula.cs @@ -245,13 +245,13 @@ public static double ResourceTankCost(string res, double amount, bool isModify, /// public static double GetLCCloseness(LCData ourStats, LCData otherStats) { - if (ourStats.Compare(otherStats)) + if (ourStats.lcType == LaunchComplexType.Hangar) return 1d; if (otherStats.lcType != ourStats.lcType) return 0d; - if (ourStats.lcType == LaunchComplexType.Hangar) + if (ourStats.Compare(otherStats)) return 1d; LCData bigger, smaller; diff --git a/Source/RP0/Utilities/KCTUtilities.cs b/Source/RP0/Utilities/KCTUtilities.cs index 4cc3ff41da3..b6a1974d71e 100644 --- a/Source/RP0/Utilities/KCTUtilities.cs +++ b/Source/RP0/Utilities/KCTUtilities.cs @@ -883,46 +883,6 @@ public static bool PartIsProcedural(Part part) return false; } - public static int GetBuildingUpgradeLevel(SpaceCenterFacility facility) - { - int lvl = GetBuildingUpgradeMaxLevel(facility); - if (HighLogic.CurrentGame.Mode == Game.Modes.CAREER) - { - lvl = (int)Math.Round(lvl * ScenarioUpgradeableFacilities.GetFacilityLevel(facility)); - } - return lvl; - } - - public static int GetBuildingUpgradeLevel(string facilityID) - { - int lvl = GetBuildingUpgradeMaxLevel(facilityID); - if (HighLogic.CurrentGame.Mode == Game.Modes.CAREER) - { - lvl = (int)Math.Round(lvl * ScenarioUpgradeableFacilities.GetFacilityLevel(facilityID)); - } - return lvl; - } - - public static int GetBuildingUpgradeMaxLevel(string facilityID) - { - int lvl = ScenarioUpgradeableFacilities.GetFacilityLevelCount(facilityID); - if (lvl < 0) - { - return Database.GetFacilityLevelCount(Database.FacilityIDToFacility.ValueOrDefault(facilityID)); - } - return lvl; - } - - public static int GetBuildingUpgradeMaxLevel(SpaceCenterFacility facility) - { - int lvl = ScenarioUpgradeableFacilities.GetFacilityLevelCount(facility); - if (lvl < 0) - { - return Database.GetFacilityLevelCount(facility); - } - return lvl; - } - public static bool RecoverActiveVesselToStorage(ProjectType listType) { try @@ -1606,22 +1566,25 @@ public static bool IsVesselKCTRecovering(ProtoVessel v) public static int GetFacilityLevel(SpaceCenterFacility facility) { - if (ScenarioUpgradeableFacilities.facilityStrings.TryGetValue(facility, out string str)) - return GetFacilityLevel(str); - - return GetFacilityLevel(facility.ToString()); + return GetIndexFromNorm(ScenarioUpgradeableFacilities.GetFacilityLevel(facility), Database.GetFacilityLevelCount(facility)); } - public static int GetFacilityLevel(string facilityId) + public static int GetFacilityLevel(string facility) { - facilityId = ScenarioUpgradeableFacilities.SlashSanitize(facilityId); - if (!ScenarioUpgradeableFacilities.protoUpgradeables.TryGetValue(facilityId, out var value)) - return 0; - - if (value.facilityRefs.Count < 1) - return 0; + return GetIndexFromNorm(ScenarioUpgradeableFacilities.GetFacilityLevel(facility), Database.GetFacilityLevelCount(facility)); + } - return value.facilityRefs[0].facilityLevel; + /// + /// Takes a normalized value and converts it to an array index + /// + /// + /// + /// + public static int GetIndexFromNorm(float norm, int levels) + { + norm *= levels; + norm += 0.01f; + return (int)norm / levels; } public static string ToCommaString(this List list) diff --git a/Source/RP0/Utilities/KSPUtils.cs b/Source/RP0/Utilities/KSPUtils.cs index 36566cf6633..b029b9f700e 100644 --- a/Source/RP0/Utilities/KSPUtils.cs +++ b/Source/RP0/Utilities/KSPUtils.cs @@ -54,7 +54,7 @@ public static List GetAllLoadedTypes(bool instantiableOnly = true) /// optional (will use default if not specified and locking controls) /// optional: runs on dialog spawn /// optional: runs when dialog is destroyed - public static void PrePostActions(this PopupDialog dialog, ControlTypes lockType = ControlTypes.None, string lockName = null, Action onCreateAction = null, Action onDestroyAction = null) + public static void PrePostActions(this PopupDialog dialog, ControlTypes lockType = ControlTypes.None, string lockName = null, Callback onCreateAction = null, Callback onDestroyAction = null) { if (dialog == null) return; @@ -74,12 +74,47 @@ public static void PrePostActions(this PopupDialog dialog, ControlTypes lockType public class LockRemover : MonoBehaviour { private string _lockName; - private Action _action; + private Callback _dismissAction; + private bool _dismissActionRun = false; - public void Setup(string lockName, Action action) + public void Setup(string lockName, Callback dismissAction) { _lockName = lockName; - _action = action; + _dismissAction = dismissAction; + + // If the dialog is dismissed by a button, we need to run the + // postaction _before_ the button's own callback. This is because + // usually we are restoring UI elements, and the button's callback + // *also* probably tocuhes UI elements. So we need to restore state + // prior to the callback running. To do this, we combine the callbacks + // on all child buttons that dismiss on select. + if (_dismissAction != null && gameObject.GetComponent() is PopupDialog dlg && dlg.dialogToDisplay != null) + { + Callback cb = () => + { + if (!_dismissActionRun) + { + _dismissActionRun = true; + _dismissAction(); + } + }; + + foreach (var d in dlg.dialogToDisplay.Options) + CombineCallbackAndRecurse(d, cb); + } + } + + private void CombineCallbackAndRecurse(DialogGUIBase dlg, Callback cb) + { + if (dlg is DialogGUIButton b && b.DismissOnSelect) + { + if (b.onOptionSelected == null) + b.onOptionSelected = cb; + else + b.onOptionSelected = (Callback)Callback.Combine(cb, b.onOptionSelected); + } + foreach (var d in dlg.children) + CombineCallbackAndRecurse(d, cb); } public void OnDestroy() @@ -87,8 +122,11 @@ public void OnDestroy() if (_lockName != null) InputLockManager.RemoveControlLock(_lockName); - if (_action != null) - _action(); + if (_dismissAction != null && !_dismissActionRun) + { + _dismissActionRun = true; + _dismissAction(); + } } } diff --git a/Source/RP0/Utilities/KerbalismUtils.cs b/Source/RP0/Utilities/KerbalismUtils.cs index 63dab3643f4..4b0273c8627 100644 --- a/Source/RP0/Utilities/KerbalismUtils.cs +++ b/Source/RP0/Utilities/KerbalismUtils.cs @@ -1,11 +1,47 @@ -using System.Collections.Generic; -using UnityEngine; +using System; +using System.Reflection; +using System.Linq; using KERBALISM; namespace RP0 { public static class KerbalismUtils { + private static bool _needCheck = true; + private static Version _version = null; + private static Assembly _assembly = null; + + public static Assembly Assembly + { + get + { + Check(); + return _assembly; + } + } + + private static void Check() + { + if (_needCheck) + { + _needCheck = false; + _assembly = AssemblyLoader.loadedAssemblies.FirstOrDefault(a => a.name.StartsWith("Kerbalism", StringComparison.OrdinalIgnoreCase))?.assembly; + if (_assembly != null) + _version = new Version(_assembly.GetName().Version.ToString()); + RP0Debug.Log("Kerbalism version: " + (_version?.ToString() ?? "assembly not found"), true); + } + } + + public static bool IsValidToPatch(Version v, bool isMax) + { + Check(); + + if (_version == null) + return false; + + return isMax ? _version <= v : _version >= v; + } + public static ExperimentSituations ToExperimentSituations(this KERBALISM.ScienceSituation sit) { int sitInt = 1 << (int)ScienceSituationUtils.ToValidStockSituation(sit); diff --git a/Source/RP0/Utilities/MathUtils.cs b/Source/RP0/Utilities/MathUtils.cs index 5f3d49c3338..50aa448529e 100644 --- a/Source/RP0/Utilities/MathUtils.cs +++ b/Source/RP0/Utilities/MathUtils.cs @@ -3,7 +3,7 @@ using UnityEngine; // ReSharper disable once CheckNamespace -namespace KSPAPIExtensions +namespace RP0 { public static class MathUtils { @@ -350,10 +350,15 @@ public static string FormatMass(float mass, int sigFigs = 4, int exponent = 0) /// public static string FormatMass(double mass, int sigFigs = 4, int exponent = 0) { - return mass < 1.0f ? + return mass < 1.0d ? mass.ToStringSI(sigFigs, exponent + 6, "g") : mass.ToStringSI(sigFigs, exponent, "t"); } + + public static string PrintMass(double mass, int sigFigs = 3, bool longPrefix = false) + { + return mass < 1d ? KSPUtil.PrintSI(mass * 1000d * 1000d, longPrefix ? "grams" : "g", sigFigs, longPrefix) : KSPUtil.PrintSI(mass, longPrefix ? "tons" : "t", sigFigs, longPrefix); + } } /// diff --git a/Source/Tech Tree/Parts Browser/data/Near_Future_Electrical.json b/Source/Tech Tree/Parts Browser/data/Near_Future_Electrical.json index 8e9cb1dea4f..b457a491a61 100644 --- a/Source/Tech Tree/Parts Browser/data/Near_Future_Electrical.json +++ b/Source/Tech Tree/Parts Browser/data/Near_Future_Electrical.json @@ -71,6 +71,27 @@ "Nuclear" ] }, + { + "name": "RO-reactor-prometheus", + "title": "Prometheus 200 KWe Nuclear Reactor", + "description": "", + "mod": "Near Future Electrical", + "cost": 24000, + "entry_cost": "0", + "category": "NUCLEAR", + "info": "Nuclear Reactor", + "year": "2016", + "technology": "modernNuclearPower", + "ro": true, + "orphan": false, + "rp0_conf": true, + "spacecraft": "JIMO", + "engine_config": "", + "upgrade": false, + "entry_cost_mods": "1000000,RO-reactor-snap50-300", + "identical_part_name": "", + "module_tags": [] + }, { "name": "RO-reactor-snap10a", "title": "NASA SNAP-10A Nuclear Reactor", @@ -95,13 +116,36 @@ "Nuclear" ] }, + { + "name": "RO-reactor-snap2", + "title": "NASA SNAP-2 Nuclear Reactor", + "description": "", + "mod": "Near Future Electrical", + "cost": 5000, + "entry_cost": "0", + "category": "NUCLEAR", + "info": "Nuclear Reactor", + "year": "1967", + "technology": "improvedRTG", + "ro": true, + "orphan": false, + "rp0_conf": true, + "spacecraft": "", + "engine_config": "", + "upgrade": false, + "entry_cost_mods": "10000,RO-reactor-snap10a,TurbineReactors", + "identical_part_name": "", + "module_tags": [ + "Nuclear" + ] + }, { "name": "RO-reactor-snap50", - "title": "NASA SNAP-50 Nuclear Reactor", + "title": "NASA SNAP-50 35 kWe Nuclear Reactor", "description": "", "mod": "Near Future Electrical", - "cost": 20000, - "entry_cost": 0, + "cost": 10000, + "entry_cost": "0", "category": "NUCLEAR", "info": "Nuclear Reactor", "year": "1975", @@ -119,6 +163,52 @@ "Nuclear" ] }, + { + "name": "RO-reactor-snap50-300", + "title": "NASA SNAP-50 300 kWe Nuclear Reactor", + "description": "", + "mod": "Near Future Electrical", + "cost": 20000, + "entry_cost": "0", + "category": "NUCLEAR", + "info": "Nuclear Reactor", + "year": "1976", + "technology": "multihundredWattRTG", + "ro": true, + "orphan": false, + "rp0_conf": true, + "spacecraft": "", + "engine_config": "", + "upgrade": false, + "entry_cost_mods": "200000,RO-reactor-snap50", + "identical_part_name": "", + "module_tags": [ + "Nuclear" + ] + }, + { + "name": "RO-reactor-snap8", + "title": "NASA SNAP-8 Nuclear Reactor", + "description": "", + "mod": "Near Future Electrical", + "cost": 5000, + "entry_cost": "0", + "category": "NUCLEAR", + "info": "Nuclear Reactor", + "year": "1971", + "technology": "improvedRTG", + "ro": true, + "orphan": false, + "rp0_conf": true, + "spacecraft": "", + "engine_config": "", + "upgrade": false, + "entry_cost_mods": "105000,RO-reactor-snap10a", + "identical_part_name": "", + "module_tags": [ + "Nuclear" + ] + }, { "name": "nuclear-recycler-25", "title": "Whirlijig Nuclear Reprocessor", @@ -225,7 +315,7 @@ "spacecraft": "", "engine_config": "", "upgrade": false, - "entry_cost_mods": "500000, RO-reactor-snap50", + "entry_cost_mods": "500000,RO-reactor-snap50-300", "identical_part_name": "", "module_tags": [ "Nuclear" @@ -273,7 +363,7 @@ "spacecraft": "", "engine_config": "", "upgrade": false, - "entry_cost_mods": "400000, RO-reactor-snap50", + "entry_cost_mods": "400000,RO-reactor-snap8", "identical_part_name": "", "module_tags": [ "Nuclear" @@ -308,8 +398,8 @@ "title": "NASA & DOE Advanced Sterling RG", "description": "A much lighter and more efficient radioisotope generator by using the sterling cycle.", "mod": "Near Future Electrical", - "cost": 20045, - "entry_cost": 200445, + "cost": 3550, + "entry_cost": 0, "category": "NUCLEAR", "info": "RTG", "year": "2015", @@ -322,8 +412,10 @@ "spacecraft": "", "engine_config": "", "upgrade": false, - "entry_cost_mods": "100000,RTGlevel6", + "entry_cost_mods": "35156,RTGlevel6", "identical_part_name": "", - "module_tags": [] + "module_tags": [ + "NuclearRTG" + ] } ] \ No newline at end of file diff --git a/Source/Tech Tree/Parts Browser/data/RN_Soviet_Rockets.json b/Source/Tech Tree/Parts Browser/data/RN_Soviet_Rockets.json index c32b2043133..b369807cd2b 100644 --- a/Source/Tech Tree/Parts Browser/data/RN_Soviet_Rockets.json +++ b/Source/Tech Tree/Parts Browser/data/RN_Soviet_Rockets.json @@ -86,8 +86,8 @@ "spacecraft": "APAS-75 (ASTP)", "engine_config": "", "upgrade": false, - "entry_cost_mods": "dockingAndro", - "identical_part_name": "", + "entry_cost_mods": "5000,dockingAndro", + "identical_part_name": "APAS-75", "module_tags": [] }, { diff --git a/Source/Tech Tree/Parts Browser/data/ROCapsules.json b/Source/Tech Tree/Parts Browser/data/ROCapsules.json index 7df24777d44..212e2a58b95 100644 --- a/Source/Tech Tree/Parts Browser/data/ROCapsules.json +++ b/Source/Tech Tree/Parts Browser/data/ROCapsules.json @@ -1,7 +1,7 @@ [ { "name": "ROC-APAS8995A", - "title": "APAS 89/95 Active Docking Port", + "title": "APAS 89/95 Active Docking Port (Deprecated)", "description": "", "mod": "ROCapsules", "cost": 3500, @@ -21,9 +21,30 @@ "identical_part_name": "APAS-89/95", "module_tags": [] }, + { + "name": "ROC-APAS8995Av2", + "title": "APAS 89/95 Active Docking Port", + "description": "", + "mod": "ROCapsules", + "cost": "3500", + "entry_cost": "0", + "category": "RCS", + "info": "Docking", + "year": "1989", + "technology": "standardDockingPorts", + "ro": true, + "orphan": false, + "rp0_conf": true, + "spacecraft": "", + "engine_config": "", + "upgrade": false, + "entry_cost_mods": "APAS8995Dock", + "identical_part_name": "APAS-89/95", + "module_tags": [] + }, { "name": "ROC-APAS8995P", - "title": "APAS 89/95 Passive Docking Port", + "title": "APAS 89/95 Passive Docking Port (Deprecated)", "description": "", "mod": "ROCapsules", "cost": 3000, @@ -39,7 +60,28 @@ "spacecraft": "Shuttle", "engine_config": "", "upgrade": false, - "entry_cost_mods": "ROC-APAS8995A", + "entry_cost_mods": "APAS8995Dock", + "identical_part_name": "APAS-89/95", + "module_tags": [] + }, + { + "name": "ROC-APAS8995Pv2", + "title": "APAS 89/95 Passive Docking Port", + "description": "", + "mod": "ROCapsules", + "cost": "3000", + "entry_cost": "0", + "category": "RCS", + "info": "Docking", + "year": "1989", + "technology": "standardDockingPorts", + "ro": true, + "orphan": false, + "rp0_conf": true, + "spacecraft": "", + "engine_config": "", + "upgrade": false, + "entry_cost_mods": "APAS8995Dock", "identical_part_name": "APAS-89/95", "module_tags": [] }, @@ -105,8 +147,8 @@ "spacecraft": "", "engine_config": "", "upgrade": false, - "entry_cost_mods": "5000,dockingAndro", - "identical_part_name": "", + "entry_cost_mods": "rn_apas75", + "identical_part_name": "APAS-75", "module_tags": [] }, { @@ -177,6 +219,48 @@ "Instruments" ] }, + { + "name": "ROC-ApolloCADSActive", + "title": "Apollo Block IV CADS Active Docking Port", + "description": "", + "mod": "ROCapsules", + "cost": "3500", + "entry_cost": "0", + "category": "RCS", + "info": "Docking", + "year": "1988", + "technology": "standardDockingPorts", + "ro": true, + "orphan": false, + "rp0_conf": true, + "spacecraft": "", + "engine_config": "", + "upgrade": false, + "entry_cost_mods": "APAS8995Dock", + "identical_part_name": "CADS", + "module_tags": [] + }, + { + "name": "ROC-ApolloCADSPassive", + "title": "Apollo Block IV CADS Passive Docking Port", + "description": "", + "mod": "ROCapsules", + "cost": "3000", + "entry_cost": "0", + "category": "RCS", + "info": "Docking", + "year": "1988", + "technology": "standardDockingPorts", + "ro": true, + "orphan": false, + "rp0_conf": true, + "spacecraft": "", + "engine_config": "", + "upgrade": false, + "entry_cost_mods": "APAS8995Dock", + "identical_part_name": "CADS", + "module_tags": [] + }, { "name": "ROC-ApolloCM", "title": "Apollo Command Module (CM)", diff --git a/Source/Tech Tree/Parts Browser/data/Universal_Storage_2.json b/Source/Tech Tree/Parts Browser/data/Universal_Storage_2.json index 9cfade777c7..9b0d5232ab7 100644 --- a/Source/Tech Tree/Parts Browser/data/Universal_Storage_2.json +++ b/Source/Tech Tree/Parts Browser/data/Universal_Storage_2.json @@ -793,7 +793,9 @@ "upgrade": false, "entry_cost_mods": "RO-MMRTG", "identical_part_name": "", - "module_tags": [] + "module_tags": [ + "NuclearRTG" + ] }, { "name": "USRadialTanks", From c731e323e2d3540d76f3de54b398f4050d216005 Mon Sep 17 00:00:00 2001 From: Ballatik <67292986+Ballatik@users.noreply.github.com> Date: Sun, 5 Nov 2023 07:48:47 -0500 Subject: [PATCH 14/27] Whitespace fixes --- .../EarlyMolniyaSat.cfg | 2 +- GameData/RP-1/Contracts/Groups.cfg | 4 +- GameData/RP-1/Programs/Programs.cfg | 220 +++++++++--------- 3 files changed, 119 insertions(+), 107 deletions(-) diff --git a/GameData/RP-1/Contracts/Commercial Applications 1/EarlyMolniyaSat.cfg b/GameData/RP-1/Contracts/Commercial Applications 1/EarlyMolniyaSat.cfg index b53a8a30a44..e5e8d7f1337 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 1/EarlyMolniyaSat.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 1/EarlyMolniyaSat.cfg @@ -2,7 +2,7 @@ CONTRACT_TYPE { name = EarlyMolniyaSat title = Molniya Communications Satellite (Early) - group = CommApp + group = CommApp description = Program: Early Commercial Applications
Type: Optional


Now that satellite communications technology has been proven, launch more capable satellites to expand communication coverage further around Earth. Some customers want satellites that dwell longer over the higher latitudes using Molniya orbits. Launch a new communications satellite with the required specifications with the unique Molniya orbital parameters.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.

The reward of this contract will slowly increase over time but will be reset to 0 after each completion.&br;Current reward is at @rewardFactorPercent % of its nominal value. Elapsed/Expected Days: @elapsedDays / @RP0:expectedDays_EarlyComSat
Number of Contracts Completed: @index / unlimited
genericDescription = Put a satellite with the required amount of communications satellite payload into the desired orbit. diff --git a/GameData/RP-1/Contracts/Groups.cfg b/GameData/RP-1/Contracts/Groups.cfg index 973fcfcd44f..ad683a79096 100644 --- a/GameData/RP-1/Contracts/Groups.cfg +++ b/GameData/RP-1/Contracts/Groups.cfg @@ -49,7 +49,7 @@ CONTRACT_GROUP } CONTRACT_GROUP { - name = EarlySatellites-Heavy + name = EarlySatellites-Heavy displayName = Early Satellite (Heavy) minVersion = 1.12.2 sortKey = 15 @@ -57,7 +57,7 @@ CONTRACT_GROUP } CONTRACT_GROUP { - name = TargetedSats + name = TargetedSats displayName = Targeted Satellite minVersion = 1.12.2 sortKey = 16 diff --git a/GameData/RP-1/Programs/Programs.cfg b/GameData/RP-1/Programs/Programs.cfg index 91212a68514..1e4f8f8ece7 100644 --- a/GameData/RP-1/Programs/Programs.cfg +++ b/GameData/RP-1/Programs/Programs.cfg @@ -44,6 +44,7 @@ RP0_PROGRAM name = XPlanesKarman } } + OPTIONALS { XPlanesSupersonicOptionalLow = true @@ -54,6 +55,7 @@ RP0_PROGRAM XPlanesSuborbital = true XPlanesHypersonicOptional = true } + CONFIDENCECOSTS { Normal = 350 @@ -81,11 +83,13 @@ RP0_PROGRAM complete_contract = DownrangeEarly complete_contract = Downrange } + OPTIONALS { DownrangeSoundingIntermediate = true DistanceSoundingDifficult = true } + CONFIDENCECOSTS { Normal = 150 @@ -112,20 +116,23 @@ RP0_PROGRAM { name = KarmanLine } + COMPLETE_CONTRACT { name = SoundingRocketFilm } - + COMPLETE_CONTRACT { name = SoundingRocketBio } + COMPLETE_CONTRACT { name = SoundingRocketAdvancedBio } } + OPTIONALS { SoundingDifficult = true @@ -134,6 +141,7 @@ RP0_PROGRAM SoundingRocketBioOptional = true SoundingRocketAdvancedBioOptional = true } + CONFIDENCECOSTS { Normal = 150 @@ -229,12 +237,13 @@ RP0_PROGRAM { EarlySatellites = true } + OPTIONALS { Downrange6000-Heavy = true Downrange7500-Heavy = true } - + CONFIDENCECOSTS { Normal = 600 @@ -274,6 +283,7 @@ RP0_PROGRAM complete_contract = FirstMolniyaSat complete_contract = FirstTundraSat } + OPTIONALS { ComTestSat = true @@ -290,7 +300,7 @@ RP0_PROGRAM { name = EarthObservationScience1 title = Early Earth Observation Satellites - description = Now that you have proven the ability to send satellites into orbit, the next step is to send them into more useful orbits with more beneficial payloads. This program will focus on satellites for observing the Earth and the space environment around it. This will advance scientific knowledge of not just physical processes within our atmosphere, but also those in space, all of which influence our lives here on Earth. + description = Now that you have proven the ability to send satellites into orbit, the next step is to send them into more useful orbits with more beneficial payloads. This program will focus on satellites for observing the Earth and the space environment around it. This will advance scientific knowledge of not just physical processes within our atmosphere, but also those in space, all of which influence our lives here on Earth. requirementsPrettyText = Complete Early Satellites program objectivesPrettyText = Launch satellites to photograph the Earth, analyze weather, measure solar wind and cosmic rays, and determine the extent of the Magnetosphere. nominalDurationYears = 4 @@ -318,7 +328,7 @@ RP0_PROGRAM complete_contract = first_OrbitRecover complete_contract = EOSCorona } - + OPTIONALS { EOSGrav1 = true @@ -338,9 +348,9 @@ RP0_PROGRAM { name = CommercialApplications1 title = Early Commercial Applications - description = Although the earliest satellites were launched through government programs, commercial uses had been envisioned for a long time. Through this program, you will launch the earliest iterations of commercial-use satellites. With wildly varying needs, each satellite is dedicated to a specific requirement, typically with far more focused requirements than the earlier, broader scientific satellites. + description = Although the earliest satellites were launched through government programs, commercial uses had been envisioned for a long time. Through this program, you will launch the earliest iterations of commercial-use satellites. With wildly varying needs, each satellite is dedicated to a specific requirement, typically with far more focused requirements than the earlier, broader scientific satellites. requirementsPrettyText = Complete Early Satellites program - objectivesPrettyText = Launch the first commercial-use satellites and build a satellite communication network. + objectivesPrettyText = Launch the first commercial-use satellites and build a satellite communication network. nominalDurationYears = 4 baseFunding = 560000 fundingCurve = MildRampupCurve @@ -372,7 +382,7 @@ RP0_PROGRAM complete_contract = EarlyComNetwork4-CA } } - + OPTIONALS { EarlyComSat-CA = true @@ -419,7 +429,7 @@ RP0_PROGRAM complete_contract = EarlyComNetwork4 } } - + OPTIONALS { ComTestSat = true @@ -436,8 +446,8 @@ RP0_PROGRAM RP0_PROGRAM { name = GEOCommNetwork - isDisabled = True - title = Geostationary Communication Network + isDisabled = true + title = Geostationary Communication Network description = With geostationary orbits, satellites can be placed at specific spots over the equator where they will stay. This allows communications satellites to be put exactly where they will have the greatest benefit. This program tasks you with creating a 4-satellite Geostationary Network for communication. Each satellite will require 315 units of ComSatPayload. requirementsPrettyText = Complete the Targeted Satellites Program objectivesPrettyText = Complete the Geostationary Communications Network. @@ -465,11 +475,12 @@ RP0_PROGRAM complete_contract = GeoComSatNetwork4 } } + OPTIONALS { GEORepeatComSats = true } - + CONFIDENCECOSTS { Normal = 450 @@ -490,44 +501,45 @@ RP0_PROGRAM repPenaltyPerYearLate = 420 slots = 2 - REQUIREMENTS + REQUIREMENTS + { + ANY { - ANY - { - complete_program = TargetedSats - complete_program = CommercialApplications1 - } + complete_program = TargetedSats + complete_program = CommercialApplications1 } + } - OBJECTIVES + OBJECTIVES + { + complete_contract = FirstGEOSat + complete_contract = FirstTargetedGeo + complete_contract = FirstTargetedMolniya + complete_contract = FirstTargetedTundra + ANY { - complete_contract = FirstGEOSat - complete_contract = FirstTargetedGeo - complete_contract = FirstTargetedMolniya - complete_contract = FirstTargetedTundra - ANY - { - complete_contract = GeoComSatNetwork3 - complete_contract = GeoComSatNetwork4 - complete_contract = MolniyaNetwork3 - } + complete_contract = GeoComSatNetwork3 + complete_contract = GeoComSatNetwork4 + complete_contract = MolniyaNetwork3 } + } - OPTIONALS - { - FirstGeosync = true - FirstTundraSat = true - GEORepeatComSats = true - MolniyaRepeatComSats = true - TundraRepeatComSats = true - } + OPTIONALS + { + FirstGeosync = true + FirstTundraSat = true + GEORepeatComSats = true + MolniyaRepeatComSats = true + TundraRepeatComSats = true + } - CONFIDENCECOSTS - { - Normal = 450 - Fast = 900 - } + CONFIDENCECOSTS + { + Normal = 450 + Fast = 900 } +} + RP0_PROGRAM { name = EarlyLunarProbes @@ -542,7 +554,7 @@ RP0_PROGRAM slots = 2 REQUIREMENTS - { + { ANY { complete_contract = FirstScienceSat @@ -566,13 +578,13 @@ RP0_PROGRAM complete_contract = LunarImpactor complete_contract = LunarOrbiter } - + OPTIONALS { LunarImpactorOptional = true LunarOrbiterOptional = true } - + CONFIDENCECOSTS { Normal = 550 @@ -584,7 +596,7 @@ RP0_PROGRAM { name = UncrewedLunarSurface title = Uncrewed Lunar Surface Exploration - description = Landing uncrewed probes on the Moon is the next step in exploring the Solar System. Successfully landing on the Moon is a difficult problem to solve. You will need to develop even more capable launch vehicles to be able to launch a large enough payload. These uncrewed landings will give you the data you need to plan for your crewed landings to follow. You will need to research deeply-throttleable engines from the Early Landing node (recommended) or figure out how to perform a landing with RCS. + description = Landing uncrewed probes on the Moon is the next step in exploring the Solar System. Successfully landing on the Moon is a difficult problem to solve. You will need to develop even more capable launch vehicles to be able to launch a large enough payload. These uncrewed landings will give you the data you need to plan for your crewed landings to follow. You will need to research deeply-throttleable engines from the Early Landing node (recommended) or figure out how to perform a landing with RCS. requirementsPrettyText = Complete the Early Lunar Probes program objectivesPrettyText = Land probes on the Moon. nominalDurationYears = 5 @@ -606,7 +618,7 @@ RP0_PROGRAM complete_contract = MoonOrbiter complete_contract = MoonLandingFarSide } - + OPTIONALS { MoonLandingOptional = true @@ -615,7 +627,7 @@ RP0_PROGRAM MoonRover = true MoonLandingReturn = true } - + CONFIDENCECOSTS { Normal = 900 @@ -639,7 +651,7 @@ RP0_PROGRAM repPenaltyPerYearLate = 895 repToConfidence = 3 slots = 3 - + REQUIREMENTS { ANY @@ -663,7 +675,7 @@ RP0_PROGRAM complete_contract = Rendezvous complete_contract = first_Docking } - + CONFIDENCECOSTS { Normal = 2400 @@ -697,7 +709,7 @@ RP0_PROGRAM repPenaltyPerYearLate = 315 repToConfidence = 3 slots = 3 - + REQUIREMENTS { ANY @@ -719,7 +731,7 @@ RP0_PROGRAM complete_contract = first_OrbitCrewed complete_contract = CollectCrewedScienceBasic } - + CONFIDENCECOSTS { Normal = 800 @@ -753,7 +765,7 @@ RP0_PROGRAM repPenaltyPerYearLate = 575 repToConfidence = 3 slots = 3 - + REQUIREMENTS { complete_program = CrewedOrbitEarly @@ -770,7 +782,7 @@ RP0_PROGRAM complete_contract = Rendezvous complete_contract = first_Docking } - + CONFIDENCECOSTS { Normal = 1450 @@ -823,7 +835,7 @@ RP0_PROGRAM OrbitalPlane3 = true CrewedSpaceplaneSuborbital = true } - + CONFIDENCECOSTS { Normal = 2500 @@ -834,7 +846,7 @@ RP0_PROGRAM RP0_PROGRAM { name = EarlyInnerPlanetProbes - title = Early Inner Planet Probes + title = Early Inner Planet Probes description = This program tasks you with exploring Venus and Mars. Though these may be Earth's closest neighbors, the distance between us and them still averages in the hundreds of millions of kilometers. Staying in contact with these probes will require advances in communication technology. Maintaining functionality and power over such great distances and long times will present new challenges in spacecraft design. requirementsPrettyText = Complete contracts X and Y objectivesPrettyText = Orbit Venus and Mars. @@ -862,13 +874,13 @@ RP0_PROGRAM complete_contract = orbitMars complete_contract = orbitVenus } - + CONFIDENCECOSTS { Normal = 1300 Fast = 2600 } - + OPTIONALS { MarsOrbitRepeatable = true @@ -883,7 +895,7 @@ RP0_PROGRAM title = Crewed Lunar Exploration description = You are tasked with sending to the Moon, 240,000 miles away from the control station in Houston, a giant rocket more than 300 feet tall, made of new metal alloys, some of which have not yet been invented, capable of standing heat and stresses several times more than have ever been experienced, fitted together with a precision better than the finest watch, carrying all the equipment needed for propulsion, guidance, control, communications, food, and survival, on an untried mission, to an unknown celestial body, and then return it safely to earth, reentering the atmosphere at speeds of over 25,000 miles per hour, causing heat about half that of the temperature of the sun. Alternatively, this could be an opportunity for some command chair antics. But a proper rocket is probably your best bet. You will need to upgrade your astronaut complex to level five to plant a flag on the Moon and complete the first crewed landing contract. requirementsPrettyText = Complete contracts X and Y - objectivesPrettyText = Send crew to flyby, orbit, and land on the Moon. + objectivesPrettyText = Send crew to flyby, orbit, and land on the Moon. nominalDurationYears = 12 baseFunding = 15720000 fundingCurve = MildMidFundingCurve @@ -917,12 +929,12 @@ RP0_PROGRAM { name = first_MoonFlybyCrewed } - + COMPLETE_CONTRACT { name = FirstCrewedLunarOrbit } - + ANY { complete_contract = first_MoonLandingCrewed @@ -935,13 +947,13 @@ RP0_PROGRAM minCount = 2 } } - + CONFIDENCECOSTS { Normal = 5250 Fast = 10500 } - + OPTIONALS { CrewedLunarOrbitRepeat = true @@ -976,7 +988,7 @@ disabled_RP0_PROGRAM complete_contract = first_ISScrew complete_contract = second_ISScrew } - + CONFIDENCECOSTS { Normal = 5000 @@ -987,10 +999,10 @@ disabled_RP0_PROGRAM RP0_PROGRAM { name = MarsSurfaceExp - title = Mars Surface Exploration - description = Send probes to Mars to survey its atmosphere, land on the surface, and even drive around with a rover. The thin atmosphere of Mars is enough to produce quite a bit of reentry heating, but it's not thick enough to safely land with only parachutes. + title = Mars Surface Exploration + description = Send probes to Mars to survey its atmosphere, land on the surface, and even drive around with a rover. The thin atmosphere of Mars is enough to produce quite a bit of reentry heating, but it's not thick enough to safely land with only parachutes. requirementsPrettyText = Complete contracts X and Y - objectivesPrettyText = Complete the program by sending a rover to Mars. + objectivesPrettyText = Complete the program by sending a rover to Mars. nominalDurationYears = 8 baseFunding = 4800000 repDeltaOnCompletePerYearEarly = 620 @@ -1008,13 +1020,13 @@ RP0_PROGRAM complete_contract = landingMars complete_contract = roverMars } - + CONFIDENCECOSTS { Normal = 2500 Fast = 5000 } - + OPTIONALS { flybyDeimos = true @@ -1025,13 +1037,13 @@ RP0_PROGRAM samplesPhobos = true MarsOrbitRepeatable = true } - + } RP0_PROGRAM { name = VenusSurfaceExp - title = Venus Surface Exploration + title = Venus Surface Exploration description = Send probes to Venus to see what the surface and atmosphere are really like. The dense clouds hide the surface from view, while the corrosive atmosphere and high heat present challenges for anything trying to descend to the surface. Keeping a probe operational for any length of time presents significant challenges. Even with heat-resistant materials, nothing seems able to survive for more than a few hours. requirementsPrettyText = Complete contracts X and Y objectivesPrettyText = Land a probe on Venus. @@ -1052,13 +1064,13 @@ RP0_PROGRAM complete_contract = landingVenus minCount = 3 } - + CONFIDENCECOSTS { Normal = 1800 Fast = 3600 } - + OPTIONALS { probeVenus = true @@ -1094,7 +1106,7 @@ RP0_PROGRAM complete_contract = flybyVesta } } - + CONFIDENCECOSTS { Normal = 2650 @@ -1108,7 +1120,7 @@ RP0_PROGRAM title = Mercury Exploration description = Mercury is the least explored of the inner planets, due to the difficulty of orbiting it. Send some probes there to find out more about it. Current data suggests that Mercury is tidally locked with the Sun. How will this affect its surface? Or did we just flyby it at remarkably synchronized times? Either way, sending probes to orbit and land on Mercury will provide fascinating data on the closest planet to the Sun. requirementsPrettyText = Do this and that - objectivesPrettyText = Orbit and land on Mercury. + objectivesPrettyText = Orbit and land on Mercury. nominalDurationYears = 8 baseFunding = 4800000 repDeltaOnCompletePerYearEarly = 415 @@ -1126,13 +1138,13 @@ RP0_PROGRAM complete_contract = orbitMercury complete_contract = landingMercury } - + CONFIDENCECOSTS { Normal = 3200 Fast = 6400 } - + OPTIONALS { orbitMercury_Rep = true @@ -1164,13 +1176,13 @@ RP0_PROGRAM complete_contract = orbitCeres complete_contract = orbitVesta } - + CONFIDENCECOSTS { Normal = 5600 Fast = 11200 } - + OPTIONALS { orbitCeres_Rep = true @@ -1184,7 +1196,7 @@ RP0_PROGRAM { name = JupiterObservation title = Jupiter Observation - description = Jupiter presents many opportunities for exploration, but also many challenges: it requires almost the same amount of energy for a spacecraft to reach Jupiter from Earth's orbit as it does to lift it into orbit in the first place. Gravity assists can be used to save delta-v at the cost of flight duration. Once there, a rich and diverse system awaits any explorer. Along with the largest planet in the Solar System, the Jovian system is also home to the largest moon, Ganymede, a planetary-mass moon. This program will send uncrewed scientific probes to Jupiter and its moons.

Historically, Jupiter is the most-visited outer planet, with 9 missions having completed flybys or entered orbits, most notably by the Voyager missions in 1979 on their flybys towards the outer Solar System, and by the Juno orbiter whose mission continues today. Most recently, ESA's JUICE mission departed in 2023 enroute to the Galilean moons. + description = Jupiter presents many opportunities for exploration, but also many challenges: it requires almost the same amount of energy for a spacecraft to reach Jupiter from Earth's orbit as it does to lift it into orbit in the first place. Gravity assists can be used to save delta-v at the cost of flight duration. Once there, a rich and diverse system awaits any explorer. Along with the largest planet in the Solar System, the Jovian system is also home to the largest moon, Ganymede, a planetary-mass moon. This program will send uncrewed scientific probes to Jupiter and its moons.

Historically, Jupiter is the most-visited outer planet, with 9 missions having completed flybys or entered orbits, most notably by the Voyager missions in 1979 on their flybys towards the outer Solar System, and by the Juno orbiter whose mission continues today. Most recently, ESA's JUICE mission departed in 2023 enroute to the Galilean moons. requirementsPrettyText = Complete contracts X and Y objectivesPrettyText = Orbit Jupiter and flyby at least two Galilean moons. nominalDurationYears = 8 @@ -1214,13 +1226,13 @@ RP0_PROGRAM } } } - + CONFIDENCECOSTS { Normal = 2650 Fast = 5300 } - + OPTIONALS { orbitJupiter_Rep = true @@ -1245,7 +1257,7 @@ disabled_RP0_PROGRAM { complete_program = JupiterObservation } - + OBJECTIVES { ATLEAST @@ -1257,13 +1269,13 @@ disabled_RP0_PROGRAM complete_contract = landingGanymede } } - + CONFIDENCECOSTS { Normal = 9600 Fast = 19200 } - + OPTIONALS { orbitJupiter_Rep = true @@ -1274,7 +1286,7 @@ RP0_PROGRAM { name = SaturnObservation title = Saturn Observation - description = Known for its photogenic rings, Saturn has long been a subject of observation and exploration. Visible from Earth with little more than a set of binoculars, Saturn's rings have intrigued observers for centuries. Further, with the highest number of moons in the entire Solar System, and more discovered with each additional mission, the Saturn system is a destination with extensive exploration opportunities. Titan, the largest moon of Saturn, may have an atmosphere conducive to life, while Enceladus is thought to contain liquid water below its icy exterior. Explore the Saturn system with uncrewed probes, analyzing the atmospheres of Saturn and Titan, and take a closer look at the larger moons of the system.

Historical missions to Saturn include flybys from Pioneer 11 and both Voyagers, while the Cassini orbiter mission operated from 2004 to 2017. + description = Known for its photogenic rings, Saturn has long been a subject of observation and exploration. Visible from Earth with little more than a set of binoculars, Saturn's rings have intrigued observers for centuries. Further, with the highest number of moons in the entire Solar System, and more discovered with each additional mission, the Saturn system is a destination with extensive exploration opportunities. Titan, the largest moon of Saturn, may have an atmosphere conducive to life, while Enceladus is thought to contain liquid water below its icy exterior. Explore the Saturn system with uncrewed probes, analyzing the atmospheres of Saturn and Titan, and take a closer look at the larger moons of the system.

Historical missions to Saturn include flybys from Pioneer 11 and both Voyagers, while the Cassini orbiter mission operated from 2004 to 2017. requirementsPrettyText = Complete contracts X and Y objectivesPrettyText = Send an orbiter to Saturn, an atmospheric probe to Titan or Saturn, and flyby two more moons in addition to Titan. @@ -1313,13 +1325,13 @@ RP0_PROGRAM } } } - + CONFIDENCECOSTS { Normal = 3650 Fast = 7300 } - + OPTIONALS { orbitSaturn_Rep = true @@ -1359,13 +1371,13 @@ disabled_RP0_PROGRAM complete_contract = landingRhea } } - + CONFIDENCECOSTS { Normal = 14400 Fast = 28800 } - + OPTIONALS { orbitSaturn_Rep = true @@ -1390,7 +1402,7 @@ RP0_PROGRAM { complete_program = EarlyInnerPlanetProbes } - + OBJECTIVES { ATLEAST @@ -1403,13 +1415,13 @@ RP0_PROGRAM complete_contract = flybyPluto } } - + CONFIDENCECOSTS { Normal = 3600 Fast = 7200 } - + OPTIONALS { flybyCharon = true @@ -1419,7 +1431,7 @@ RP0_PROGRAM RP0_PROGRAM { name = OuterGasGiantSurvey - title = Outer Gas Giant Survey + title = Outer Gas Giant Survey description = Pictures can help expand our knowledge of the outer Solar System, but scientific instruments and dwell times much longer than a hasty flyby are necessary to increase our understanding of these distant neighbors. Send orbiters to the two furthest gas giants and probe their atmospheres. While in the furthest reaches of our system, explore the moons of these giants as well. An upgraded Tracking Station and higher level comm tech will be necessary in order to receive scientific data over such great distances. requirementsPrettyText = Complete contracts X and Y objectivesPrettyText = Do this and that @@ -1434,10 +1446,10 @@ RP0_PROGRAM { complete_program = OuterPlanetFlyby } - + OBJECTIVES { - All + All { complete_contract = orbitUranus Any @@ -1457,13 +1469,13 @@ RP0_PROGRAM } } } - + CONFIDENCECOSTS { Normal = 7200 Fast = 14400 } - + OPTIONALS { orbitNeptune_Rep = true @@ -1475,7 +1487,7 @@ RP0_PROGRAM RP0_PROGRAM { name = PlutoLandings - title = Plutonian Landings + title = Plutonian Landings description = The only known double planetary system in the Solar System, Pluto and Charon have been tidally locked in orbit of each other in the darkest, coldest reaches of our system for eons. It is now time for you to land on them, quite possibly within a century of their discovery. Very little is known about these distant, icy worlds. Historically, even our most advanced probes have returned relatively little data compared to what we know about our closer neighbors. Explore the furthest reaches of the Solar System and land on this intriguing pair of dwarf planets. requirementsPrettyText = Complete contracts X and Y objectivesPrettyText = Land on Pluto and Charon. @@ -1497,13 +1509,13 @@ RP0_PROGRAM complete_contract = landingPluto complete_contract = landingCharon } - + CONFIDENCECOSTS { Normal = 16800 Fast = 33600 } - + OPTIONALS { roverPluto = true @@ -1539,7 +1551,7 @@ disabled_RP0_PROGRAM { complete_contract = TODO } - + CONFIDENCECOSTS { Normal = 13350 @@ -1571,7 +1583,7 @@ disabled_RP0_PROGRAM { complete_contract = TODO } - + CONFIDENCECOSTS { Normal = 28000 @@ -1603,7 +1615,7 @@ disabled_RP0_PROGRAM { complete_contract = TODO } - + CONFIDENCECOSTS { Normal = 10000 @@ -1635,7 +1647,7 @@ disabled_RP0_PROGRAM { complete_contract = TODO } - + CONFIDENCECOSTS { Normal = 40000 From 0b6b81f3d583dc199ae944740ace9aa237611f16 Mon Sep 17 00:00:00 2001 From: Ballatik <67292986+Ballatik@users.noreply.github.com> Date: Sun, 5 Nov 2023 07:52:58 -0500 Subject: [PATCH 15/27] More whitespace fixes --- .../Commercial Applications 1/EarlyMolniyaSat.cfg | 2 +- GameData/RP-1/Contracts/Groups.cfg | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/GameData/RP-1/Contracts/Commercial Applications 1/EarlyMolniyaSat.cfg b/GameData/RP-1/Contracts/Commercial Applications 1/EarlyMolniyaSat.cfg index e5e8d7f1337..93f337abf5a 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 1/EarlyMolniyaSat.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 1/EarlyMolniyaSat.cfg @@ -2,7 +2,7 @@ CONTRACT_TYPE { name = EarlyMolniyaSat title = Molniya Communications Satellite (Early) - group = CommApp + group = CommApp description = Program: Early Commercial Applications
Type: Optional


Now that satellite communications technology has been proven, launch more capable satellites to expand communication coverage further around Earth. Some customers want satellites that dwell longer over the higher latitudes using Molniya orbits. Launch a new communications satellite with the required specifications with the unique Molniya orbital parameters.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.

The reward of this contract will slowly increase over time but will be reset to 0 after each completion.&br;Current reward is at @rewardFactorPercent % of its nominal value. Elapsed/Expected Days: @elapsedDays / @RP0:expectedDays_EarlyComSat
Number of Contracts Completed: @index / unlimited
genericDescription = Put a satellite with the required amount of communications satellite payload into the desired orbit. diff --git a/GameData/RP-1/Contracts/Groups.cfg b/GameData/RP-1/Contracts/Groups.cfg index ad683a79096..6e8998b58dc 100644 --- a/GameData/RP-1/Contracts/Groups.cfg +++ b/GameData/RP-1/Contracts/Groups.cfg @@ -49,16 +49,16 @@ CONTRACT_GROUP } CONTRACT_GROUP { - name = EarlySatellites-Heavy - displayName = Early Satellite (Heavy) + name = EarlySatellites-Heavy + displayName = Early Satellite (Heavy) minVersion = 1.12.2 sortKey = 15 agent = Satellites } CONTRACT_GROUP { - name = TargetedSats - displayName = Targeted Satellite + name = TargetedSats + displayName = Targeted Satellite minVersion = 1.12.2 sortKey = 16 agent = Satellites @@ -79,7 +79,7 @@ CONTRACT_GROUP sortKey = 18 agent = Satellites } - CONTRACT_GROUP + CONTRACT_GROUP { name = CommApp displayName = Commercial Application Satellites From 34a1b3936280a611b7a8d6e219654d2bfb96a225 Mon Sep 17 00:00:00 2001 From: Ballatik <67292986+Ballatik@users.noreply.github.com> Date: Mon, 13 Nov 2023 18:32:57 -0500 Subject: [PATCH 16/27] balance and display tweaks Made repeatable contracts not acceptable at the same time. They share the same anti-grind cooldown, but could be circumvented by accepting all 3 at once. Removed waypoint messages from targeted GEO contracts. between the standard and ideal locations, you could see quite a few in/out messages while getting to the right spot, and you can see it in the contract window anyway. Lowered duration from 4 to 3 years. Required contracts took me just over 2 years if I did it right after ComApp1, but only 6 months if I did it after. --- .../MolniyaRepeatComSats.cfg | 14 ++++++++++++++ .../TundraRepeatComSats.cfg | 14 ++++++++++++++ GameData/RP-1/Programs/Programs.cfg | 2 +- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaRepeatComSats.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaRepeatComSats.cfg index 706cef26565..57f17d6ebc3 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaRepeatComSats.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaRepeatComSats.cfg @@ -56,6 +56,20 @@ CONTRACT_TYPE contractType = MolniyaNetwork3 invertRequirement = true } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = GEORepeatComSats + invertRequirement = true + } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = TundraRepeatComSats + invertRequirement = true + } BEHAVIOUR { diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg index 4a0c4962e4f..79404c7aa6b 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg @@ -48,6 +48,20 @@ CONTRACT_TYPE type = CompleteContract contractType = FirstTargetedTundra } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = GEORepeatComSats + invertRequirement = true + } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = MolniyaRepeatComSats + invertRequirement = true + } BEHAVIOUR diff --git a/GameData/RP-1/Programs/Programs.cfg b/GameData/RP-1/Programs/Programs.cfg index 1e4f8f8ece7..93667275b1c 100644 --- a/GameData/RP-1/Programs/Programs.cfg +++ b/GameData/RP-1/Programs/Programs.cfg @@ -494,7 +494,7 @@ RP0_PROGRAM description = Geosynchronous, Geostationary, Molniya, and Tundra orbits have the potential to improve satellite coverage and simplify ground antenna tracking. This program tasks you with exploring these orbits for commercial customers, and creating a 3 or 4 satellite Geostationary or Molniya Network for communication. requirementsPrettyText = Complete the Early Commercial Applications Program objectivesPrettyText = Complete a Geostationary or Molniya Communications Network. - nominalDurationYears = 4 + nominalDurationYears = 3 baseFunding = 800000 fundingCurve = MildBackloadedFundingCurve repDeltaOnCompletePerYearEarly = 420 From e41d9bd6a0169d20a407132b26a71a8f4be35f92 Mon Sep 17 00:00:00 2001 From: Ballatik <67292986+Ballatik@users.noreply.github.com> Date: Mon, 13 Nov 2023 18:33:42 -0500 Subject: [PATCH 17/27] Balance and display tweaks part 2 --- .../FirstTargetedGeo.cfg | 3 ++- .../GEORepeatComSats.cfg | 17 ++++++++++++++++- .../GeoComSatNetwork3.cfg | 6 +++--- .../GeoComSatNetwork4.cfg | 8 ++++---- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedGeo.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedGeo.cfg index f903c020e89..4abb9116539 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedGeo.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedGeo.cfg @@ -111,7 +111,7 @@ CONTRACT_TYPE index = 0 //distance = 42736000 horizontalDistance = 4000.0 - showMessages = true + showMessages = false disableOnStateChange = false } PARAMETER @@ -141,6 +141,7 @@ CONTRACT_TYPE index = 0 //distance = 42736000 horizontalDistance = 2000.0 + showMessages = false disableOnStateChange = false } } diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/GEORepeatComSats.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/GEORepeatComSats.cfg index a73cef33f04..eda520bf4fb 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/GEORepeatComSats.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/GEORepeatComSats.cfg @@ -63,6 +63,20 @@ CONTRACT_TYPE contractType = GeoComSatNetwork4 invertRequirement = true } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = MolniyaRepeatComSats + invertRequirement = true + } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = TundraRepeatComSats + invertRequirement = true + } BEHAVIOUR { @@ -172,7 +186,7 @@ CONTRACT_TYPE index = 0 //distance = 42736000 horizontalDistance = 4000.0 - showMessages = true + showMessages = false disableOnStateChange = false } PARAMETER @@ -202,6 +216,7 @@ CONTRACT_TYPE index = 0 //distance = 42736000 horizontalDistance = 2000.0 + showMessages = false disableOnStateChange = false } } diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg index d0386e8c51f..24d74ba8d76 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg @@ -121,7 +121,7 @@ CONTRACT_TYPE index = 0 //distance = 42736000 horizontalDistance = 4000 - showMessages = true + showMessages = false disableOnStateChange = false } @@ -184,7 +184,7 @@ CONTRACT_TYPE index = 1 //distance = 42736000 horizontalDistance = 4000.0 - showMessages = true + showMessages = false disableOnStateChange = false } @@ -247,7 +247,7 @@ CONTRACT_TYPE index = 2 //distance = 42736000 horizontalDistance = 4000.0 - showMessages = true + showMessages = false disableOnStateChange = false } diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg index 3cb216c27c6..f7ce0eb2eda 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg @@ -128,7 +128,7 @@ CONTRACT_TYPE index = 0 //distance = 42736000 horizontalDistance = 4000 - showMessages = true + showMessages = false disableOnStateChange = false } @@ -198,7 +198,7 @@ CONTRACT_TYPE index = 1 //distance = 42736000 horizontalDistance = 4000.0 - showMessages = true + showMessages = false disableOnStateChange = false } @@ -269,7 +269,7 @@ CONTRACT_TYPE index = 2 //distance = 42736000 horizontalDistance = 4000.0 - showMessages = true + showMessages = false disableOnStateChange = false } @@ -339,7 +339,7 @@ CONTRACT_TYPE index = 3 //distance = 42736000 horizontalDistance = 4000.0 - showMessages = true + showMessages = false disableOnStateChange = false } From 0f9b5226a7aec0fc22df89dc1dc0cb6d2beb0dc3 Mon Sep 17 00:00:00 2001 From: Ballatik <67292986+Ballatik@users.noreply.github.com> Date: Sun, 7 Jan 2024 18:01:57 -0500 Subject: [PATCH 18/27] Tweaks Made firstTargetedMolniya optional since you do a Molniya in CA1. Changed Molniya and Tundra targeting to use waypoints instead of orbit parameters. It allows for a bit more play in LAN and eccentricity while still making you do what those orbits are meant to do. --- .../FirstTargetedMolniya.cfg | 64 ++++++++++++------- .../FirstTargetedTundra.cfg | 62 +++++++++++------- .../MolniyaNetwork3.cfg | 1 - .../MolniyaRepeatComSats.cfg | 55 ++++++++++------ .../TundraRepeatComSats.cfg | 57 +++++++++++------ GameData/RP-1/Programs/Programs.cfg | 2 +- 6 files changed, 157 insertions(+), 84 deletions(-) diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg index 73b8b5a80d5..fa20527c589 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg @@ -5,7 +5,7 @@ CONTRACT_TYPE group = CommApp2 agent = Federation Aeronautique Internationale - description = Program: Advanced Commercial Applications
Type: Required

A Molniya orbit is a type of highly elliptical orbit with an inclination of 63.4 degrees, an argument of perigee of -90 degrees, and an orbital period of one half of a sidereal day. This keeps the satellite mostly to the northern hemisphere of the Earth. Place a satellite into a Specific Molniya orbit for the customer.

Historical example: Molniya 1-1 (1,600kg, Molniya)

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer. + description = Program: Advanced Commercial Applications
Type: Optional

A Molniya orbit is a type of highly elliptical orbit with an inclination of 63.4 degrees, an argument of perigee in the very high or low latitudes, and an orbital period of one half of a sidereal day. This causes it to spend most of its time over two areas on the ground at opposing longitudes. Place a commercial satellite into a Molniya orbit so that it loiters over the specified ground location for at least 6 consecutive hours.

Historical example: Molniya 1-1 (1,600kg, Molniya)

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer. synopsis = Launch a satellite into a Molniya orbit @@ -47,13 +47,24 @@ CONTRACT_TYPE BEHAVIOUR { - name = MolniyaOrbit - type = OrbitGenerator + name = WaypointGenerator + type = WaypointGenerator - RANDOM_ORBIT - { - type = KOLNIYA - } + WAYPOINT + { + name = Molniya Orbit Target + icon = thermometer + altitude = 0 + latitude = @/targetLat + longitude = @/targetLon + } + } + + DATA + { + type = int + targetLon = Random(-180,180) + targetLat = [63,-63].Random() } PARAMETER @@ -91,24 +102,31 @@ CONTRACT_TYPE } PARAMETER { - name = ReachSpecificOrbit - type = ReachSpecificOrbit - title = Reach the specified orbit. - displayNotes = true - index = 0 - deviationWindow = 3.0 - - PARAMETER - { - name = Duration - type = Duration + name = Orbit + type = Orbit + minPeriod = 11h 53m + maxPeriod = 12h 7m + disableOnStateChange = false + title = Have an orbital period of half a day. + } + PARAMETER + { + name = waypointLoiter + type = VisitWaypoint + index = 0 + horizontalDistance = 2000.0 - duration = 2m + } + PARAMETER + { + name = Duration + type = Duration - preWaitText = Check for stable orbit - waitingText = Checking for stable orbit - completionText = Stable orbit: Confirmed - } + duration = 6h + + preWaitText = Fly over the target area + waitingText = Checking loiter time + completionText = Stable Orbit: Confirmed } } diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg index 757f4c83747..e1e526f25d4 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg @@ -55,13 +55,24 @@ CONTRACT_TYPE BEHAVIOUR { - name = TundraOrbit - type = OrbitGenerator + name = WaypointGenerator + type = WaypointGenerator - RANDOM_ORBIT - { - type = TUNDRA - } + WAYPOINT + { + name = Tundra Orbit Target + icon = thermometer + altitude = 0 + latitude = @/targetLat + longitude = @/targetLon + } + } + + DATA + { + type = int + targetLon = Random(-180,180) + targetLat = [63,-63].Random() } PARAMETER @@ -99,24 +110,31 @@ CONTRACT_TYPE } PARAMETER { - name = ReachSpecificOrbit - type = ReachSpecificOrbit - title = Reach the specified orbit. - displayNotes = true - index = 0 - deviationWindow = 3.0 - - PARAMETER - { - name = Duration - type = Duration + name = Orbit + type = Orbit + minPeriod = 23h 53m + maxPeriod = 23h 59m + disableOnStateChange = false + title = Have an orbital period of one day. + } + PARAMETER + { + name = waypointLoiter + type = VisitWaypoint + index = 0 + horizontalDistance = 2000.0 - duration = 2m + } + PARAMETER + { + name = Duration + type = Duration - preWaitText = Check for stable orbit - waitingText = Checking for stable orbit - completionText = Stable orbit: Confirmed - } + duration = 8h + + preWaitText = Fly over the target area + waitingText = Checking loiter time + completionText = Stable Orbit: Confirmed } } diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg index 90b0e673e7e..b2a97322196 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg @@ -59,7 +59,6 @@ CONTRACT_TYPE name = MolniyaCom1 type = VesselParameterGroup define = Molniya Network Sat I - dissassociateVesselsOnContractCompletion = true PARAMETER { diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaRepeatComSats.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaRepeatComSats.cfg index 57f17d6ebc3..42b7df47294 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaRepeatComSats.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaRepeatComSats.cfg @@ -5,7 +5,7 @@ CONTRACT_TYPE group = CommApp2 agent = Federation Aeronautique Internationale - description = Program: Advanced Commercial Applications
Type: Optional


We have a customer requesting a new Communications Satellite over a specified area in the high latitudes. Design a satellite within their specs and launch into an orbit with the proper orbital parameters as outlined in the contract.&br;&br;This contract can be completed as many times as you would like.&br;&br;NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.&br;&br;The reward of this contract will slowly increase over time but will be reset to 0 after each completion.&br;Current reward is at @rewardFactorPercent % of its nominal value. Elapsed/Expected Days: @elapsedDays / @RP0:expectedDays_GEORepeatComSats
Number of Contracts Completed: @index / unlimited
+ description = Program: Advanced Commercial Applications
Type: Optional


We have a customer requesting a new Communications Satellite over a specified area. Design a satellite within their specs and launch into an orbit so that it loiters over the specified ground target for at least 6 consecutive hours.&br;&br;This contract can be completed as many times as you would like.&br;&br;NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.&br;&br;The reward of this contract will slowly increase over time but will be reset to 0 after each completion.&br;Current reward is at @rewardFactorPercent % of its nominal value. Elapsed/Expected Days: @elapsedDays / @RP0:expectedDays_GEORepeatComSats
Number of Contracts Completed: @index / unlimited
genericDescription = Put a satellite into the requested orbit. synopsis = Launch a new Commercial Communications Satellite @@ -73,15 +73,26 @@ CONTRACT_TYPE BEHAVIOUR { - name = OrbitGenerator - type = OrbitGenerator + name = WaypointGenerator + type = WaypointGenerator - RANDOM_ORBIT + WAYPOINT { - type = KOLNIYA + name = Molniya Orbit Target + icon = thermometer + altitude = 0 + latitude = @/targetLat + longitude = @/targetLon } } + DATA + { + type = int + targetLon = Random(-180,180) + targetLat = [63,-63].Random() + } + DATA { type = int @@ -161,23 +172,31 @@ CONTRACT_TYPE } PARAMETER { - name = ReachSpecificOrbit - type = ReachSpecificOrbit - displayNotes = true + name = Orbit + type = Orbit + minPeriod = 11h 53m + maxPeriod = 12h 7m + disableOnStateChange = false + title = Have an orbital period of half a day. + } + PARAMETER + { + name = waypointLoiter + type = VisitWaypoint index = 0 - deviationWindow = 4 + horizontalDistance = 2000.0 - PARAMETER - { - name = Duration - type = Duration + } + PARAMETER + { + name = Duration + type = Duration - duration = 2m + duration = 6h - preWaitText = Check for Stable Orbit - waitingText = Checking for Stable Orbit - completionText = Stable Orbit: Confirmed - } + preWaitText = Fly over the target area + waitingText = Checking loiter time + completionText = Stable Orbit: Confirmed } } diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg index 79404c7aa6b..7e94df3ca7b 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg @@ -5,7 +5,7 @@ CONTRACT_TYPE group = CommApp2 agent = Federation Aeronautique Internationale - description = Program: Advanced Commercial Applications
Type: Optional


We have a customer requesting a new Communications Satellite over a specified area in the high latitudes. Design a satellite within their specs and launch into an orbit with the proper orbital parameters as outlined in the contract.&br;&br;This contract can be completed as many times as you would like.&br;&br;NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.&br;&br;The reward of this contract will slowly increase over time but will be reset to 0 after each completion.&br;Current reward is at @rewardFactorPercent % of its nominal value. Elapsed/Expected Days: @elapsedDays / @RP0:expectedDays_GEORepeatComSats
Number of Contracts Completed: @index / unlimited
+ description = Program: Advanced Commercial Applications
Type: Optional


We have a customer requesting a new Communications Satellite over a specified area. Design a satellite within their specs and launch into a tundra orbit so that it loiters over the desired area for at least 8 consecutive hours.&br;&br;This contract can be completed as many times as you would like.&br;&br;NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.&br;&br;The reward of this contract will slowly increase over time but will be reset to 0 after each completion.&br;Current reward is at @rewardFactorPercent % of its nominal value. Elapsed/Expected Days: @elapsedDays / @RP0:expectedDays_GEORepeatComSats
Number of Contracts Completed: @index / unlimited
genericDescription = Put a satellite into the requested orbit. synopsis = Launch a new Commercial Communications Satellite @@ -66,15 +66,26 @@ CONTRACT_TYPE BEHAVIOUR { - name = OrbitGenerator - type = OrbitGenerator + name = WaypointGenerator + type = WaypointGenerator - RANDOM_ORBIT + WAYPOINT { - type = TUNDRA + name = Tundra Orbit Target + icon = thermometer + altitude = 0 + latitude = @/targetLat + longitude = @/targetLon } } + DATA + { + type = int + targetLon = Random(-180,180) + targetLat = [63,-63].Random() + } + DATA { type = int @@ -154,25 +165,33 @@ CONTRACT_TYPE } PARAMETER { - name = ReachSpecificOrbit - type = ReachSpecificOrbit - displayNotes = true + name = Orbit + type = Orbit + minPeriod = 23h 53m + maxPeriod = 23h 59m + disableOnStateChange = false + title = Have an orbital period of one day. + } + PARAMETER + { + name = waypointLoiter + type = VisitWaypoint index = 0 - deviationWindow = 4 + horizontalDistance = 2000.0 - PARAMETER - { - name = Duration - type = Duration + } + PARAMETER + { + name = Duration + type = Duration - duration = 2m + duration = 8h - preWaitText = Check for Stable Orbit - waitingText = Checking for Stable Orbit - completionText = Stable Orbit: Confirmed - } + preWaitText = Fly over the target area + waitingText = Checking loiter time + completionText = Stable Orbit: Confirmed } - } +} BEHAVIOUR { diff --git a/GameData/RP-1/Programs/Programs.cfg b/GameData/RP-1/Programs/Programs.cfg index 93667275b1c..dd41c3e15ec 100644 --- a/GameData/RP-1/Programs/Programs.cfg +++ b/GameData/RP-1/Programs/Programs.cfg @@ -514,7 +514,6 @@ RP0_PROGRAM { complete_contract = FirstGEOSat complete_contract = FirstTargetedGeo - complete_contract = FirstTargetedMolniya complete_contract = FirstTargetedTundra ANY { @@ -526,6 +525,7 @@ RP0_PROGRAM OPTIONALS { + FirstTargetedMolniya = true FirstGeosync = true FirstTundraSat = true GEORepeatComSats = true From b27b3353ff543f4450e678dbe1a44379c6f390c5 Mon Sep 17 00:00:00 2001 From: Ballatik <67292986+Ballatik@users.noreply.github.com> Date: Sat, 3 Feb 2024 10:37:24 -0500 Subject: [PATCH 19/27] Molniya fix, text updates Adjusted Molniya network intermediate orbit to make it clearer. Changed some descriptions to make it easier to see which satellites you keep. --- .../RP-1/Contracts/Commercial Applications 2/FirstGEOSat.cfg | 4 ++-- .../RP-1/Contracts/Commercial Applications 2/FirstGeosync.cfg | 4 ++-- .../Contracts/Commercial Applications 2/FirstTargetedGeo.cfg | 2 +- .../Commercial Applications 2/FirstTargetedMolniya.cfg | 2 +- .../Commercial Applications 2/FirstTargetedTundra.cfg | 2 +- .../Contracts/Commercial Applications 2/FirstTundraSat.cfg | 4 ++-- .../Contracts/Commercial Applications 2/MolniyaNetwork3.cfg | 2 +- GameData/RP-1/Programs/Programs.cfg | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstGEOSat.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstGEOSat.cfg index c20df61077e..346a90624d0 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstGEOSat.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstGEOSat.cfg @@ -1,12 +1,12 @@ CONTRACT_TYPE { name = FirstGEOSat - title = First Geostationary Satellite + title = Geostationary Test Satellite group = CommApp2 agent = Federation Aeronautique Internationale description = Program: Advanced Commercial Applications
Type: Required


Having a communication satellite that remains stationary relative to a ground station means that the antenna wouldn't need to track movements to stay connected. This would greatly simplify communication relay and mass transmission systems.
Historical example: Syncom 3 (39 kg, Thor-Delta) launched in August of 1964. - synopsis = Launch a satellite into a Geostationary Orbit + synopsis = Launch a test satellite into a Geostationary Orbit completedMessage = Congratulations! The satellite is in orbit over a constant area. diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstGeosync.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstGeosync.cfg index a143b10aafe..6f266510724 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstGeosync.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstGeosync.cfg @@ -1,13 +1,13 @@ CONTRACT_TYPE { name = FirstGeosync - title = First Geosynchronous Satellite + title = Geosynchronous Test Satellite group = CommApp2 agent = Federation Aeronautique Internationale description = Program: Advanced Commercial Applications
Type: Optional


With an orbital period of an earth day, a satellite will remain above a constant longitude, appearing to drift north and south through the day. This will allow for constant connection to a ground station.
Historical example: Syncom 2 (39kg, Thor-Delta) launched in July of 1963. - synopsis = Launch a geosynchronous satellite + synopsis = Launch a geosynchronous test satellite completedMessage = Congratulations! The satellite is in orbit and connected to the groundstation. diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedGeo.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedGeo.cfg index 4abb9116539..e4669959e77 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedGeo.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedGeo.cfg @@ -7,7 +7,7 @@ CONTRACT_TYPE description = Program: Advanced Commercial Applications
Type: Required


Now that we have shown the benefits of Geostationary orbits, launch a satellite to cover a specific ground area.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer. - synopsis = Launch a geostationary satellite over the targeted point + synopsis = Launch a commercial geostationary satellite over the targeted point completedMessage = Congratulations! The satellite has been placed in the customer's desired location. diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg index fa20527c589..220e74404b4 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg @@ -7,7 +7,7 @@ CONTRACT_TYPE description = Program: Advanced Commercial Applications
Type: Optional

A Molniya orbit is a type of highly elliptical orbit with an inclination of 63.4 degrees, an argument of perigee in the very high or low latitudes, and an orbital period of one half of a sidereal day. This causes it to spend most of its time over two areas on the ground at opposing longitudes. Place a commercial satellite into a Molniya orbit so that it loiters over the specified ground location for at least 6 consecutive hours.

Historical example: Molniya 1-1 (1,600kg, Molniya)

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer. - synopsis = Launch a satellite into a Molniya orbit + synopsis = Launch a commercial satellite into a Molniya orbit completedMessage = Success! The satellite is in orbit to loiter over the desired area. diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg index e1e526f25d4..c1fc1472270 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg @@ -7,7 +7,7 @@ CONTRACT_TYPE description = Program: Advanced Commercial Applications
Type: Required

A Tundra orbit is a highly elliptical geosynchronous orbit (note: not geostationary orbit) with a high inclination (usually near 63.4) and an orbital period of one sidereal day. A satellite placed in this orbit spends most of its time over a chosen area of the Earth, a phenomenon known as apogee dwell. Place the customer's satellite in a tundra orbit over the desired area.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer. - synopsis = Launch a satellite into the desired Tundra orbit + synopsis = Launch a commercial satellite into the desired Tundra orbit completedMessage = Success! The satellite is in orbit to loiter over the desired area. diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTundraSat.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTundraSat.cfg index c8de2830181..731cdafc969 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTundraSat.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTundraSat.cfg @@ -1,12 +1,12 @@ CONTRACT_TYPE { name = FirstTundraSat - title = First Tundra Orbit Satellite + title = Tundra Orbit Test Satellite group = CommApp2 agent = Federation Aeronautique Internationale description = Program: Advanced Commercial Applications
Type: Optional


A Tundra orbit is a highly elliptical geosynchronous orbit (note: not geostationary orbit) with a high inclination (usually near 63.4) and an orbital period of one sidereal day. A satellite placed in this orbit spends most of its time over a chosen area of the Earth, a phenomenon known as apogee dwell. The ground track of a satellite in a tundra orbit is a closed figure eight. An extreme version of this orbit puts the perigee around 1000 km and the apogee around 70,000 km. The orbit in this contract is actually using data from the Sirius satellites, the only known satellites using a Tundra orbit. - synopsis = Launch a satellite into a Tundra Orbit + synopsis = Launch a test satellite into a Tundra Orbit completedMessage = Success! The Tundra orbit is highly eccentric and lets the satellite spend most of its time over a point in the high latitudes. diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg index b2a97322196..ef8fe0c86e6 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg @@ -107,7 +107,7 @@ CONTRACT_TYPE name = ReachOrbit type = Orbit title = Reach an intermediate orbit with a single satellite. - minPeriod = 1h + minPeriod = 3h maxPeriod = 6h completeInSequence = true disableOnStateChange = true diff --git a/GameData/RP-1/Programs/Programs.cfg b/GameData/RP-1/Programs/Programs.cfg index dd41c3e15ec..06ecd3b5dc9 100644 --- a/GameData/RP-1/Programs/Programs.cfg +++ b/GameData/RP-1/Programs/Programs.cfg @@ -491,7 +491,7 @@ RP0_PROGRAM { name = CommercialApplications2 title = Advanced Commercial Applications - description = Geosynchronous, Geostationary, Molniya, and Tundra orbits have the potential to improve satellite coverage and simplify ground antenna tracking. This program tasks you with exploring these orbits for commercial customers, and creating a 3 or 4 satellite Geostationary or Molniya Network for communication. + description = Geosynchronous, Geostationary, Molniya, and Tundra orbits have the potential to improve satellite coverage and simplify ground antenna tracking. This program tasks you with testing these orbits, launching satellites into them for commercial customers, and creating a 3 or 4 satellite Geostationary or Molniya Network for communication. requirementsPrettyText = Complete the Early Commercial Applications Program objectivesPrettyText = Complete a Geostationary or Molniya Communications Network. nominalDurationYears = 3 From 35bb51642229f5046056ada2b2d22d6cc1f7ccb3 Mon Sep 17 00:00:00 2001 From: Ballatik <67292986+Ballatik@users.noreply.github.com> Date: Wed, 28 Feb 2024 05:51:55 -0500 Subject: [PATCH 20/27] Clarity and Principia changes Added notes to Tundra and Molniya contracts to remind player about the orbital parameters since they aren't explicitly required. Loosened time requirements to allow for principia orbit shifts. --- .../Commercial Applications 2/FirstTargetedMolniya.cfg | 5 +++-- .../Commercial Applications 2/FirstTargetedTundra.cfg | 4 ++-- .../Commercial Applications 2/MolniyaRepeatComSats.cfg | 5 +++-- .../Commercial Applications 2/TundraRepeatComSats.cfg | 3 ++- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg index 220e74404b4..7132f8f6658 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg @@ -73,6 +73,7 @@ CONTRACT_TYPE type = VesselParameterGroup define = FirstMolniyaSat title = Molniya Satellite + notes = Your orbit should have high eccentricity, an inclination of around 63 degrees, with your periapsis on the same or opposite longitude as the target (@/targetLon) in the opposite North/South hemisphere. PARAMETER @@ -104,8 +105,8 @@ CONTRACT_TYPE { name = Orbit type = Orbit - minPeriod = 11h 53m - maxPeriod = 12h 7m + minPeriod = 11h 50m + maxPeriod = 12h 5m disableOnStateChange = false title = Have an orbital period of half a day. } diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg index c1fc1472270..f6d20519a65 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg @@ -81,7 +81,7 @@ CONTRACT_TYPE type = VesselParameterGroup define = TundraSat title = Tundra Satellite - + notes = Your orbit should have high eccentricity, an inclination of around 63 degrees, with your periapsis on the same longitude as the target (@/targetLon) in the opposite North/South hemisphere. PARAMETER { @@ -112,7 +112,7 @@ CONTRACT_TYPE { name = Orbit type = Orbit - minPeriod = 23h 53m + minPeriod = 23h 36m maxPeriod = 23h 59m disableOnStateChange = false title = Have an orbital period of one day. diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaRepeatComSats.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaRepeatComSats.cfg index 42b7df47294..77571e01901 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaRepeatComSats.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaRepeatComSats.cfg @@ -144,6 +144,7 @@ CONTRACT_TYPE type = VesselParameterGroup define = AdvComSatellite title = Commercial Communications Satellite + notes = Your orbit should have high eccentricity, an inclination of around 63 degrees, with your periapsis on the same or opposite longitude as the target (@/targetLon) in the opposite North/South hemisphere. PARAMETER { @@ -174,8 +175,8 @@ CONTRACT_TYPE { name = Orbit type = Orbit - minPeriod = 11h 53m - maxPeriod = 12h 7m + minPeriod = 11h 50m + maxPeriod = 12h 5m disableOnStateChange = false title = Have an orbital period of half a day. } diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg index 7e94df3ca7b..c9a23cb9cae 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg @@ -137,6 +137,7 @@ CONTRACT_TYPE type = VesselParameterGroup define = AdvComSatellite title = Commercial Communications Satellite + notes = Your orbit should have high eccentricity, an inclination of around 63 degrees, with your periapsis on the same longitude as the target (@/targetLon) in the opposite North/South hemisphere. PARAMETER { @@ -167,7 +168,7 @@ CONTRACT_TYPE { name = Orbit type = Orbit - minPeriod = 23h 53m + minPeriod = 23h 36m maxPeriod = 23h 59m disableOnStateChange = false title = Have an orbital period of one day. From 73569918869dfe97d660dd0e7194bfb7d5ddb6f5 Mon Sep 17 00:00:00 2001 From: Ballatik <67292986+Ballatik@users.noreply.github.com> Date: Wed, 28 Feb 2024 05:52:59 -0500 Subject: [PATCH 21/27] Add waypoint loiter requirement Changed Molniya Network to track waypoint loiter instead of orbital parameters to match the rest of the contracts. --- .../MolniyaNetwork3.cfg | 151 +++++++++++------- 1 file changed, 90 insertions(+), 61 deletions(-) diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg index ef8fe0c86e6..31cc060585b 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg @@ -5,7 +5,7 @@ CONTRACT_TYPE group = CommApp2 agent = Federation Aeronautique Internationale - description = Program: Advanced Commercial Applications
Type: Required


Geostationary satellites do not provide good coverage in the higher latitudes. Molniya orbits loiter over those latitudes for longer periods, to provide constant coverage with fewer satellites.
Historical example: Molniya 1-1 (1.6t, Molniya 8K78) launched starting in April of 1965.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.

NOTE: If you are completing this with a single launch, you must separate the 3 vessels before entering the specified orbit. + description = Program: Advanced Commercial Applications
Type: Required


Geostationary satellites do not provide good coverage in the higher latitudes. Molniya orbits loiter over those latitudes for longer periods, to provide constant coverage with fewer satellites.
Historical example: Molniya 1-1 (1.6t, Molniya 8K78) launched starting in April of 1965.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.

NOTE: Your orbit should have high eccentricity, an inclination of around 63 degrees, with your periapsis on the same or opposite longitude as the target (@/targetLon) in the opposite North/South hemisphere. If you are completing this with a single launch, you must separate the 3 vessels before entering the specified orbit. synopsis = Launch a 3 Satellite Molniya Communications Network @@ -54,6 +54,28 @@ CONTRACT_TYPE invertRequirement = true } + BEHAVIOUR + { + name = WaypointGenerator + type = WaypointGenerator + + WAYPOINT + { + name = Molniya Network Target + icon = thermometer + altitude = 0 + latitude = @/targetLat + longitude = @/targetLon + } + } + + DATA + { + type = int + targetLon = Random(-180,180) + targetLat = [63,-63].Random() + } + PARAMETER { name = MolniyaCom1 @@ -107,35 +129,38 @@ CONTRACT_TYPE name = ReachOrbit type = Orbit title = Reach an intermediate orbit with a single satellite. - minPeriod = 3h + minPeriod = 1h maxPeriod = 6h completeInSequence = true disableOnStateChange = true } PARAMETER { - name = ReachOrbit + name = Orbit type = Orbit - title = Reach the correct orbit within the parameters. Note, the argument of periapsis values mean that the apogee needs to be high in the northern latitudes. - minInclination = 61.4 - maxInclination = 65.4 - minEccentricity = 0.7 - minArgumentOfPeriapsis = 220 - maxArgumentOfPeriapsis = 320 - minPeA = 500000 - minPeriod = 11h 56m 2s - maxPeriod = 12h 00m 2s + minPeriod = 11h 50m + maxPeriod = 12h 5m disableOnStateChange = false + title = Have an orbital period of half a day. + } + PARAMETER + { + name = waypointLoiter + type = VisitWaypoint + index = 0 + horizontalDistance = 3000.0 - PARAMETER - { - name = Duration - type = Duration - duration = 2m - preWaitText = Check for stable orbit - waitingText = Checking for stable orbit - completionText = Stable orbit: Confirmed - } + } + PARAMETER + { + name = Duration + type = Duration + + duration = 6h + + preWaitText = Fly over the target area + waitingText = Checking loiter time + completionText = Stable Orbit: Confirmed } } PARAMETER @@ -143,7 +168,6 @@ CONTRACT_TYPE name = MolniyaCom2 type = VesselParameterGroup define = Molniya Network Sat II - dissassociateVesselsOnContractCompletion = true PARAMETER { @@ -199,28 +223,31 @@ CONTRACT_TYPE } PARAMETER { - name = ReachOrbit + name = Orbit type = Orbit - title = Reach the correct orbit within the parameters. Note, the argument of periapsis values mean that the apogee needs to be high in the northern latitudes. - minInclination = 61.4 - maxInclination = 65.4 - minEccentricity = 0.7 - minArgumentOfPeriapsis = 220 - maxArgumentOfPeriapsis = 320 - minPeA = 500000 - minPeriod = 11h 56m 2s - maxPeriod = 12h 00m 2s + minPeriod = 11h 50m + maxPeriod = 12h 5m disableOnStateChange = false + title = Have an orbital period of half a day. + } + PARAMETER + { + name = waypointLoiter + type = VisitWaypoint + index = 0 + horizontalDistance = 3000.0 - PARAMETER - { - name = Duration - type = Duration - duration = 2m - preWaitText = Check for stable orbit - waitingText = Checking for stable orbit - completionText = Stable orbit: Confirmed - } + } + PARAMETER + { + name = Duration + type = Duration + + duration = 6h + + preWaitText = Fly over the target area + waitingText = Checking loiter time + completionText = Stable Orbit: Confirmed } } PARAMETER @@ -228,7 +255,6 @@ CONTRACT_TYPE name = MolniyaCom3 type = VesselParameterGroup define = Molniya Network Sat III - dissassociateVesselsOnContractCompletion = true PARAMETER { @@ -284,28 +310,31 @@ CONTRACT_TYPE } PARAMETER { - name = ReachOrbit + name = Orbit type = Orbit - title = Reach the correct orbit within the parameters. Note, the argument of periapsis values mean that the apogee needs to be high in the northern latitudes. - minInclination = 61.4 - maxInclination = 65.4 - minEccentricity = 0.7 - minArgumentOfPeriapsis = 220 - maxArgumentOfPeriapsis = 320 - minPeA = 500000 - minPeriod = 11h 56m 2s - maxPeriod = 12h 00m 2s + minPeriod = 11h 50m + maxPeriod = 12h 5m disableOnStateChange = false + title = Have an orbital period of half a day. + } + PARAMETER + { + name = waypointLoiter + type = VisitWaypoint + index = 0 + horizontalDistance = 3000.0 - PARAMETER - { - name = Duration - type = Duration - duration = 2m - preWaitText = Check for stable orbit - waitingText = Checking for stable orbit - completionText = Stable orbit: Confirmed - } + } + PARAMETER + { + name = Duration + type = Duration + + duration = 6h + + preWaitText = Fly over the target area + waitingText = Checking loiter time + completionText = Stable Orbit: Confirmed } } From 2918b0a3eaff0c149707074f16e96c3194a4343d Mon Sep 17 00:00:00 2001 From: Ballatik <67292986+Ballatik@users.noreply.github.com> Date: Sun, 3 Mar 2024 08:19:53 -0500 Subject: [PATCH 22/27] Difficulty and progression tweaks Adjust Tundra target range. Limit to one GEO network contract --- .../Commercial Applications 2/FirstTargetedTundra.cfg | 2 +- .../Commercial Applications 2/GeoComSatNetwork3.cfg | 7 +++++++ .../Commercial Applications 2/GeoComSatNetwork4.cfg | 7 +++++++ .../Commercial Applications 2/TundraRepeatComSats.cfg | 2 +- 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg index f6d20519a65..eeccccb649b 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg @@ -122,7 +122,7 @@ CONTRACT_TYPE name = waypointLoiter type = VisitWaypoint index = 0 - horizontalDistance = 2000.0 + horizontalDistance = 3000.0 } PARAMETER diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg index 24d74ba8d76..bf315b532df 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg @@ -72,6 +72,13 @@ CONTRACT_TYPE contractType = GeoComSatNetwork4 invertRequirement = true } + REQUIREMENT + { + name = CompleteContract + type = CompleteContract + contractType = GeoComSatNetwork4 + invertRequirement = true + } PARAMETER { diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg index f7ce0eb2eda..ee78ed51b30 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg @@ -72,6 +72,13 @@ CONTRACT_TYPE contractType = GeoComSatNetwork3 invertRequirement = true } + REQUIREMENT + { + name = CompleteContract + type = CompleteContract + contractType = GeoComSatNetwork3 + invertRequirement = true + } PARAMETER { diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg index c9a23cb9cae..06cc234c6d1 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg @@ -178,7 +178,7 @@ CONTRACT_TYPE name = waypointLoiter type = VisitWaypoint index = 0 - horizontalDistance = 2000.0 + horizontalDistance = 2500.0 } PARAMETER From 752ca66760985cbeefd0eac248b26993a048f5c7 Mon Sep 17 00:00:00 2001 From: Ballatik <67292986+Ballatik@users.noreply.github.com> Date: Sun, 24 Mar 2024 15:07:09 -0400 Subject: [PATCH 23/27] Fix first repeatable timer Reset RepeatSat_Completion on completion of prerequisite contracts to avoid overly rewarding first repeat. --- .../Commercial Applications 2/FirstTargetedGeo.cfg | 11 +++++++++++ .../FirstTargetedMolniya.cfg | 11 +++++++++++ .../Commercial Applications 2/FirstTargetedTundra.cfg | 11 +++++++++++ 3 files changed, 33 insertions(+) diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedGeo.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedGeo.cfg index e4669959e77..6dde7b9c62e 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedGeo.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedGeo.cfg @@ -61,6 +61,17 @@ CONTRACT_TYPE contractType = FirstGEOSat } + BEHAVIOUR + { + name = ResetTimer + type = Expression + + CONTRACT_COMPLETED_SUCCESS + { + RepeatSat_Completion = UniversalTime() + } + } + PARAMETER { name = TargetedGeo diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg index 7132f8f6658..61f6265c2e8 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg @@ -60,6 +60,17 @@ CONTRACT_TYPE } } + BEHAVIOUR + { + name = ResetTimer + type = Expression + + CONTRACT_COMPLETED_SUCCESS + { + RepeatSat_Completion = UniversalTime() + } + } + DATA { type = int diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg index eeccccb649b..ce7418c1fc8 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg @@ -68,6 +68,17 @@ CONTRACT_TYPE } } + BEHAVIOUR + { + name = ResetTimer + type = Expression + + CONTRACT_COMPLETED_SUCCESS + { + RepeatSat_Completion = UniversalTime() + } + } + DATA { type = int From 285617412a7d3b8e336abbbd1a5e4efac88a4a46 Mon Sep 17 00:00:00 2001 From: Ballatik <67292986+Ballatik@users.noreply.github.com> Date: Mon, 25 Mar 2024 22:21:45 -0400 Subject: [PATCH 24/27] Fix spacing, adjust rep delta --- .../Commercial Applications 2/FirstTargetedMolniya.cfg | 2 +- .../Commercial Applications 2/FirstTargetedTundra.cfg | 2 +- .../Commercial Applications 2/GeoComSatNetwork3.cfg | 6 +++--- .../Commercial Applications 2/GeoComSatNetwork4.cfg | 8 ++++---- .../Commercial Applications 2/MolniyaNetwork3.cfg | 2 +- .../Commercial Applications 2/MolniyaRepeatComSats.cfg | 2 +- .../Commercial Applications 2/TundraRepeatComSats.cfg | 2 +- GameData/RP-1/Programs/Programs.cfg | 4 ++-- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg index 61f6265c2e8..afb7266a822 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg @@ -56,7 +56,7 @@ CONTRACT_TYPE icon = thermometer altitude = 0 latitude = @/targetLat - longitude = @/targetLon + longitude = @/targetLon } } diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg index ce7418c1fc8..e47a368b20e 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg @@ -64,7 +64,7 @@ CONTRACT_TYPE icon = thermometer altitude = 0 latitude = @/targetLat - longitude = @/targetLon + longitude = @/targetLon } } diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg index bf315b532df..a2d32f82652 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg @@ -280,7 +280,7 @@ CONTRACT_TYPE icon = thermometer altitude = 0 latitude = 0 - longitude = 0 + longitude = 0 } WAYPOINT { @@ -288,7 +288,7 @@ CONTRACT_TYPE icon = thermometer altitude = 0 latitude = 0 - longitude = 120 + longitude = 120 } WAYPOINT { @@ -296,7 +296,7 @@ CONTRACT_TYPE icon = thermometer altitude = 0 latitude = 0 - longitude = 240 + longitude = 240 } } diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg index ee78ed51b30..fdc1bed6bb6 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg @@ -372,7 +372,7 @@ CONTRACT_TYPE icon = thermometer altitude = 0 latitude = 0 - longitude = 0 + longitude = 0 } WAYPOINT { @@ -380,7 +380,7 @@ CONTRACT_TYPE icon = thermometer altitude = 0 latitude = 0 - longitude = 90 + longitude = 90 } WAYPOINT { @@ -388,7 +388,7 @@ CONTRACT_TYPE icon = thermometer altitude = 0 latitude = 0 - longitude = 180 + longitude = 180 } WAYPOINT { @@ -396,7 +396,7 @@ CONTRACT_TYPE icon = thermometer altitude = 0 latitude = 0 - longitude = 270 + longitude = 270 } } diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg index 31cc060585b..a79dc7645ff 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg @@ -65,7 +65,7 @@ CONTRACT_TYPE icon = thermometer altitude = 0 latitude = @/targetLat - longitude = @/targetLon + longitude = @/targetLon } } diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaRepeatComSats.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaRepeatComSats.cfg index 77571e01901..0699504176d 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaRepeatComSats.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaRepeatComSats.cfg @@ -82,7 +82,7 @@ CONTRACT_TYPE icon = thermometer altitude = 0 latitude = @/targetLat - longitude = @/targetLon + longitude = @/targetLon } } diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg index 06cc234c6d1..3c029393545 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/TundraRepeatComSats.cfg @@ -75,7 +75,7 @@ CONTRACT_TYPE icon = thermometer altitude = 0 latitude = @/targetLat - longitude = @/targetLon + longitude = @/targetLon } } diff --git a/GameData/RP-1/Programs/Programs.cfg b/GameData/RP-1/Programs/Programs.cfg index c61f266b553..95cf8ec5ac9 100644 --- a/GameData/RP-1/Programs/Programs.cfg +++ b/GameData/RP-1/Programs/Programs.cfg @@ -497,8 +497,8 @@ RP0_PROGRAM nominalDurationYears = 3 baseFunding = 800000 fundingCurve = MildBackloadedFundingCurve - repDeltaOnCompletePerYearEarly = 420 - repPenaltyPerYearLate = 420 + repDeltaOnCompletePerYearEarly = 270 + repPenaltyPerYearLate = 270 slots = 2 REQUIREMENTS From beaa81989f75dd45f664c8155db9648685f0ad03 Mon Sep 17 00:00:00 2001 From: Ballatik <67292986+Ballatik@users.noreply.github.com> Date: Tue, 26 Mar 2024 10:29:53 -0400 Subject: [PATCH 25/27] Update MolniyaNetwork3.cfg Clarified separation mechanic. Upped payload requirement to bring difficulty closer to GEO network --- .../MolniyaNetwork3.cfg | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg index a79dc7645ff..d6ed85fdc8c 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg @@ -5,7 +5,7 @@ CONTRACT_TYPE group = CommApp2 agent = Federation Aeronautique Internationale - description = Program: Advanced Commercial Applications
Type: Required


Geostationary satellites do not provide good coverage in the higher latitudes. Molniya orbits loiter over those latitudes for longer periods, to provide constant coverage with fewer satellites.
Historical example: Molniya 1-1 (1.6t, Molniya 8K78) launched starting in April of 1965.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.

NOTE: Your orbit should have high eccentricity, an inclination of around 63 degrees, with your periapsis on the same or opposite longitude as the target (@/targetLon) in the opposite North/South hemisphere. If you are completing this with a single launch, you must separate the 3 vessels before entering the specified orbit. + description = Program: Advanced Commercial Applications
Type: Required


Geostationary satellites do not provide good coverage in the higher latitudes. Molniya orbits loiter over those latitudes for longer periods, to provide constant coverage with fewer satellites.
Historical example: Molniya 1-1 (1.6t, Molniya 8K78) launched starting in April of 1965.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.

NOTE: Your orbit should have high eccentricity, an inclination of around 63 degrees, with your periapsis on the same or opposite longitude as the target (@/targetLon) in the opposite North/South hemisphere.

NOTE: If you are completing this with a single launch, you must separate the 3 vessels while in an orbit with a period of less than 6 hours or the payload requirement will not complete. This is to ensure spacing of the network. synopsis = Launch a 3 Satellite Molniya Communications Network @@ -119,16 +119,16 @@ CONTRACT_TYPE name = HasComSatPayload type = HasResource resource = ComSatPayload - minQuantity = 124.9 - maxQuantity = 249.0 - title = Have a ComSatPayload of at least 125 units on the craft + minQuantity = 300.0 + maxQuantity = 599.9 + title = Have a ComSatPayload of at least 300 units on the craft disableOnStateChange = false } PARAMETER { name = ReachOrbit type = Orbit - title = Reach an intermediate orbit with a single satellite. + title = If launching multiple at once, separate them while in an intermediate orbit. minPeriod = 1h maxPeriod = 6h completeInSequence = true @@ -206,16 +206,16 @@ CONTRACT_TYPE name = HasComSatPayload type = HasResource resource = ComSatPayload - minQuantity = 124.9 - maxQuantity = 249.0 - title = Have a ComSatPayload of at least 125 units on the craft + minQuantity = 300.0 + maxQuantity = 599.9 + title = Have a ComSatPayload of at least 300 units on the craft disableOnStateChange = false } PARAMETER { name = ReachOrbit type = Orbit - title = Reach an intermediate orbit with a single satellite. + title = If launching multiple at once, separate them while in an intermediate orbit. minPeriod = 1h maxPeriod = 6h completeInSequence = true @@ -293,16 +293,16 @@ CONTRACT_TYPE name = HasComSatPayload type = HasResource resource = ComSatPayload - minQuantity = 124.9 - maxQuantity = 249.0 - title = Have a ComSatPayload of at least 125 units on the craft + minQuantity = 300.0 + maxQuantity = 599.9 + title = Have a ComSatPayload of at least 300 units on the craft disableOnStateChange = false } PARAMETER { name = ReachOrbit type = Orbit - title = Reach an intermediate orbit with a single satellite. + title = If launching multiple at once, separate them while in an intermediate orbit. minPeriod = 1h maxPeriod = 6h completeInSequence = true From 9293d70316865f6840a5b9e5aa9247c46864bed8 Mon Sep 17 00:00:00 2001 From: Ballatik <67292986+Ballatik@users.noreply.github.com> Date: Tue, 26 Mar 2024 19:02:15 -0400 Subject: [PATCH 26/27] Adjust rep, confidence, and clarity --- .../Contracts/Commercial Applications 2/FirstGEOSat.cfg | 1 + .../Contracts/Commercial Applications 2/FirstGeosync.cfg | 3 ++- .../Commercial Applications 2/FirstTundraSat.cfg | 1 + .../Commercial Applications 2/GeoComSatNetwork3.cfg | 3 +++ .../Commercial Applications 2/GeoComSatNetwork4.cfg | 4 ++++ .../Commercial Applications 2/MolniyaNetwork3.cfg | 9 ++++++--- GameData/RP-1/Programs/Programs.cfg | 4 ++-- 7 files changed, 19 insertions(+), 6 deletions(-) diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstGEOSat.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstGEOSat.cfg index 346a90624d0..dfa8bc6dbc5 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstGEOSat.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstGEOSat.cfg @@ -93,6 +93,7 @@ CONTRACT_TYPE resource = ElectricCharge minRate = -1000000 maxRate = 0.00001 + hideChildren = true } PARAMETER { diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstGeosync.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstGeosync.cfg index 6f266510724..515c6af9106 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstGeosync.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstGeosync.cfg @@ -31,7 +31,7 @@ CONTRACT_TYPE rewardScience = 0 rewardFunds = 0 failureFunds = 0 - rewardReputation = 40 + rewardReputation = 60 failureReputation = 0 // was @rewardReputation // ************ REQUIREMENTS ************ @@ -89,6 +89,7 @@ CONTRACT_TYPE resource = ElectricCharge minRate = -1000000 maxRate = 0.00001 + hideChildren = true } PARAMETER { diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTundraSat.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTundraSat.cfg index 731cdafc969..848747d46ef 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTundraSat.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTundraSat.cfg @@ -87,6 +87,7 @@ CONTRACT_TYPE resource = ElectricCharge minRate = -1000000 maxRate = 0.00001 + hideChildren = true } PARAMETER { diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg index a2d32f82652..08c89321d06 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork3.cfg @@ -109,6 +109,7 @@ CONTRACT_TYPE minQuantity = 124.9 title = Have a ComSatPayload of at least 125 units on the craft disableOnStateChange = false + hideChildren = true } PARAMETER @@ -172,6 +173,7 @@ CONTRACT_TYPE minQuantity = 124.9 title = Have a ComSatPayload of at least 125 units on the craft disableOnStateChange = false + hideChildren = true } PARAMETER @@ -235,6 +237,7 @@ CONTRACT_TYPE minQuantity = 124.9 title = Have a ComSatPayload of at least 125 units on the craft disableOnStateChange = false + hideChildren = true } PARAMETER diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg index fdc1bed6bb6..a39c0812457 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/GeoComSatNetwork4.cfg @@ -116,6 +116,7 @@ CONTRACT_TYPE minQuantity = 124.9 title = Have a ComSatPayload of at least 125 units on the craft disableOnStateChange = false + hideChildren = true } PARAMETER @@ -186,6 +187,7 @@ CONTRACT_TYPE minQuantity = 124.9 title = Have a ComSatPayload of at least 125 units on the craft disableOnStateChange = false + hideChildren = true } PARAMETER @@ -257,6 +259,7 @@ CONTRACT_TYPE minQuantity = 124.9 title = Have a ComSatPayload of at least 125 units on the craft disableOnStateChange = false + hideChildren = true } PARAMETER @@ -327,6 +330,7 @@ CONTRACT_TYPE minQuantity = 124.9 title = Have a ComSatPayload of at least 125 units on the craft disableOnStateChange = false + hideChildren = true } PARAMETER diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg index d6ed85fdc8c..38fb210e7b1 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/MolniyaNetwork3.cfg @@ -121,8 +121,9 @@ CONTRACT_TYPE resource = ComSatPayload minQuantity = 300.0 maxQuantity = 599.9 - title = Have a ComSatPayload of at least 300 units on the craft + title = Have a ComSatPayload of 300 units on the craft disableOnStateChange = false + hideChildren = true } PARAMETER { @@ -208,8 +209,9 @@ CONTRACT_TYPE resource = ComSatPayload minQuantity = 300.0 maxQuantity = 599.9 - title = Have a ComSatPayload of at least 300 units on the craft + title = Have a ComSatPayload of 300 units on the craft disableOnStateChange = false + hideChildren = true } PARAMETER { @@ -295,8 +297,9 @@ CONTRACT_TYPE resource = ComSatPayload minQuantity = 300.0 maxQuantity = 599.9 - title = Have a ComSatPayload of at least 300 units on the craft + title = Have a ComSatPayload of 300 units on the craft disableOnStateChange = false + hideChildren = true } PARAMETER { diff --git a/GameData/RP-1/Programs/Programs.cfg b/GameData/RP-1/Programs/Programs.cfg index 95cf8ec5ac9..874bb5e92c5 100644 --- a/GameData/RP-1/Programs/Programs.cfg +++ b/GameData/RP-1/Programs/Programs.cfg @@ -535,8 +535,8 @@ RP0_PROGRAM CONFIDENCECOSTS { - Normal = 450 - Fast = 900 + Normal = 550 + Fast = 1100 } } From bb0449d006cb3b2c727a740bb6eda09ee9fd7ada Mon Sep 17 00:00:00 2001 From: Ballatik <67292986+Ballatik@users.noreply.github.com> Date: Wed, 27 Mar 2024 16:56:55 -0400 Subject: [PATCH 27/27] Prevent double dips --- .../Commercial Applications 2/FirstGEOSat.cfg | 21 +++++++++++++ .../FirstGeosync.cfg | 21 +++++++++++++ .../FirstTargetedMolniya.cfg | 30 ++++++++++++++++++- .../FirstTargetedTundra.cfg | 21 +++++++++++++ .../FirstTundraSat.cfg | 21 +++++++++++++ 5 files changed, 113 insertions(+), 1 deletion(-) diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstGEOSat.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstGEOSat.cfg index dfa8bc6dbc5..88973f80177 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstGEOSat.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstGEOSat.cfg @@ -60,6 +60,27 @@ CONTRACT_TYPE contractType = FirstGeosync invertRequirement = true } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = FirstTargetedMolniya + invertRequirement = true + } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = FirstTundraSat + invertRequirement = true + } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = FirstTargetedTundra + invertRequirement = true + } PARAMETER { diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstGeosync.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstGeosync.cfg index 515c6af9106..63b1415154c 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstGeosync.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstGeosync.cfg @@ -56,6 +56,27 @@ CONTRACT_TYPE contractType = FirstGEOSat invertRequirement = true } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = FirstTargetedMolniya + invertRequirement = true + } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = FirstTundraSat + invertRequirement = true + } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = FirstTargetedTundra + invertRequirement = true + } PARAMETER { diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg index afb7266a822..8f3ac449677 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedMolniya.cfg @@ -1,7 +1,7 @@ CONTRACT_TYPE { name = FirstTargetedMolniya - title = First Targeted Molniya Orbit Satellite + title = Targeted Molniya Orbit Satellite group = CommApp2 agent = Federation Aeronautique Internationale @@ -44,6 +44,34 @@ CONTRACT_TYPE type = ProgramActive program = CommercialApplications2 } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = FirstTundraSat + invertRequirement = true + } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = FirstGeosync + invertRequirement = true + } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = FirstGEOSat + invertRequirement = true + } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = FirstTargetedTundra + invertRequirement = true + } BEHAVIOUR { diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg index e47a368b20e..0e7cb60e630 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTargetedTundra.cfg @@ -52,6 +52,27 @@ CONTRACT_TYPE contractType = FirstTundraSat invertRequirement = true } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = FirstGEOSat + invertRequirement = true + } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = FirstTargetedMolniya + invertRequirement = true + } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = FirstGeosync + invertRequirement = true + } BEHAVIOUR { diff --git a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTundraSat.cfg b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTundraSat.cfg index 848747d46ef..68c6279f5a9 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 2/FirstTundraSat.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 2/FirstTundraSat.cfg @@ -55,6 +55,27 @@ CONTRACT_TYPE contractType = FirstTargetedTundra invertRequirement = true } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = FirstTargetedMolniya + invertRequirement = true + } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = FirstGeosync + invertRequirement = true + } + REQUIREMENT + { + name = AcceptContract + type = AcceptContract + contractType = FirstGEOSat + invertRequirement = true + } PARAMETER {