├── .gitattributes ├── .github └── workflows │ ├── attachReleaseArtifacts.yml │ └── build.yml ├── .gitignore ├── ForumPost.bb ├── GameData └── ProceduralParts │ ├── ChangeLog.txt │ ├── KSPCommunityFixes.cfg │ ├── Licence.txt │ ├── ModuleManager │ ├── DRE.cfg │ ├── FilterExt_proc.cfg │ ├── KSPCF.cfg │ ├── ModularFuelTanks.cfg │ └── RealFuels.cfg │ ├── Parts │ ├── Electrical │ │ └── Battery.cfg │ ├── HighRatio.mu │ ├── LowRatio.mu │ ├── SRBBell.mu │ ├── StretchySRBBell.dds │ ├── StretchySRBBell_EM.dds │ ├── StretchySRBBell_NRM.dds │ ├── Structural │ │ ├── Heatshield.cfg │ │ ├── NoseCone.cfg │ │ ├── StackDecoupler.cfg │ │ └── Structural.cfg │ ├── Tanks │ │ ├── 1TankLiquid.cfg │ │ ├── 2TankRCS.cfg │ │ ├── 3TankXenon.cfg │ │ ├── 4SRB.cfg │ │ └── TankOre.cfg │ ├── TechTree │ │ └── Upgrades.cfg │ ├── ZOtherMods │ │ ├── TankExtraplanetary.cfg │ │ ├── TankKethane.cfg │ │ ├── TankLifeSupport.cfg │ │ └── USI-LS compatibility.cfg │ ├── ablative.dds │ ├── atlas.dds │ ├── atlas_NRM.dds │ ├── blueside.dds │ ├── copernicus.dds │ ├── copernicus_NRM.dds │ ├── cylinderTank.mu │ ├── ends.dds │ ├── foilthin.dds │ ├── foilthin_NRM.dds │ ├── gersides.dds │ ├── greyside.dds │ ├── heatshield.mu │ ├── mu.dds │ ├── orangesides.dds │ ├── plainwhite.dds │ ├── sides.dds │ ├── sides_NRM.dds │ ├── soyuzgreen.dds │ ├── srbsides.dds │ ├── srbsides_NRM.dds │ ├── stockend.dds │ ├── stocksides.dds │ ├── stocksides_NRM.dds │ ├── stripes1.dds │ ├── stripes2.dds │ ├── tiles.dds │ ├── tiles_NRM.dds │ ├── ussides.dds │ └── whiteside.dds │ ├── ProceduralParts.cfg │ ├── ProceduralParts.version │ ├── ProceduralsUnlimited.cfg │ ├── ProceduralsUnlimitedFoil.cfg │ ├── ProceduralsUnlimitedMetal.cfg │ ├── README.md │ ├── STTextures.cfg │ └── Textures │ ├── Mains │ ├── Foil-DIFF.dds │ ├── Metal-DIFF.png │ └── Stringer-TopBottom-Smooth-DIFF.dds │ ├── Masks │ ├── Able-MASK.dds │ ├── Able-USAF-MASK.dds │ ├── Agena-MASK.dds │ ├── BlackArrow-MASK.dds │ ├── BlackArrow2-MASK.dds │ ├── Bumper-MASK.dds │ ├── Checkers-Double-MASK.dds │ ├── Checkers-MASK.dds │ ├── Checkers2-MASK.dds │ ├── Corestar-MASK.dds │ ├── Default-MASK.dds │ ├── DeltaIV-MASK.dds │ ├── Europa-MASK.dds │ ├── Fancy1-MASK.dds │ ├── Fancy2-MASK.dds │ ├── Fancy3-MASK.dds │ ├── Fancy4-MASK.dds │ ├── Fancy5-MASK.dds │ ├── Fancy6-MASK.dds │ ├── Fancy7-MASK.dds │ ├── Fancy8-MASK.dds │ ├── Fancy9-MASK.dds │ ├── Hermes-MASK.dds │ ├── Juno-L-MASK.dds │ ├── Juno-MASK.dds │ ├── LongMarch-MASK.dds │ ├── LongMarch2-MASK.dds │ ├── Mu-MASK.dds │ ├── Narrow-MASK.dds │ ├── Redstone-L-MASK.dds │ ├── Redstone-MASK.dds │ ├── Redstone-USA-MASK.dds │ ├── SLV-MASK.dds │ ├── Skylab-MASK.dds │ ├── Slats-MASK.dds │ ├── Solid-MASK.dds │ ├── Stripes-Half-MASK.dds │ ├── Stripes-Long-MASK.dds │ ├── Stripes-MASK.dds │ ├── Stripes-Twisted-MASK.dds │ ├── ThorAble-MASK.dds │ ├── Titan-MASK.dds │ ├── Titan2-MASK.dds │ ├── Tricolor-MASK.dds │ └── Vanguard-MASK.dds │ ├── Metallic │ └── Smooth-METAL.dds │ └── Normals │ ├── Foil-NRM.dds │ ├── Smooth-NRM.dds │ └── Stringer-TopBottom-M-Smooth-NRM.dds ├── README.md ├── Source ├── CalcsAndModels │ ├── Bezier.xlsx │ ├── Circle.xlsx │ ├── Heatshields.xlsx │ ├── ModTanks.xlsx │ ├── Models.unitypackage │ └── StockParts.xlsx ├── DecouplerTweaker.cs ├── EngineWrapper.cs ├── ICostModifier.cs ├── KSPUtils.cs ├── LegacyTextureHandler.cs ├── Makefile ├── MathUtils.cs ├── ProceduralAbstractShape.cs ├── ProceduralAbstractSoRShape.cs ├── ProceduralHeatshield.cs ├── ProceduralPart.cs ├── ProceduralParts.csproj ├── ProceduralParts.sln ├── ProceduralParts.sln.DotSettings ├── ProceduralParts.userprefs ├── ProceduralSRB.cs ├── ProceduralShapeBezierCone.cs ├── ProceduralShapeCone.cs ├── ProceduralShapeCylinder.cs ├── ProceduralShapeHollowCone.cs ├── ProceduralShapeHollowCylinder.cs ├── ProceduralShapeHollowPill.cs ├── ProceduralShapeHollowTruss.cs ├── ProceduralShapePill.cs ├── ProceduralShapePolygon.cs ├── ProceduralTools │ ├── DragCubeTool.cs │ └── KSPFieldTool.cs ├── Properties │ ├── AssemblyInfo.cs │ └── AssemblyInfo.in ├── TUTexturePickerGUI.cs ├── TankContentSwitcher.cs ├── TextureSet.cs ├── TransformFollower.cs ├── UnityUtils.cs ├── UpgradePipeline.cs └── VectorUtils.cs ├── convertBB.sh └── version-gen /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | 24 | version-gen text eol=lf 25 | *.sh text eol=lf -------------------------------------------------------------------------------- /.github/workflows/attachReleaseArtifacts.yml: -------------------------------------------------------------------------------- 1 | name: "Attach Release Artifacts" 2 | 3 | # Controls when the action will run. 4 | on: 5 | release: 6 | types: [published] 7 | 8 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 9 | jobs: 10 | attach-release-artifacts: 11 | # The type of runner that the job will run on 12 | runs-on: ubuntu-22.04 13 | 14 | # Steps represent a sequence of tasks that will be executed as part of the job 15 | steps: 16 | - name: Get Branch 17 | shell: bash 18 | run: | 19 | releaseBranch=${{ github.event.release.target_commitish }} 20 | echo "Found branch ${releaseBranch}" 21 | echo "tagged_branch=${releaseBranch}" >> $GITHUB_ENV 22 | 23 | - name: Checkout 24 | uses: actions/checkout@v2 25 | with: 26 | fetch-depth: 0 27 | ref: ${{ env.tagged_branch }} 28 | 29 | - name: Download required assemblies 30 | id: download-assemblies 31 | uses: KSP-RO/BuildTools/download-assemblies@master 32 | with: 33 | KSP_ZIP_PASSWORD: ${{ secrets.KSP_ZIP_PASSWORD }} 34 | 35 | - name: Update AssemblyInfo 36 | uses: KSP-RO/BuildTools/update-assembly-info@master 37 | with: 38 | path: ${GITHUB_WORKSPACE}/Source/Properties/AssemblyInfo.cs 39 | tag: ${{ github.event.release.tag_name }} 40 | 41 | - name: Build mod solution 42 | run: msbuild /p:Configuration=Release /p:ReferencePath="${{ steps.download-assemblies.outputs.ksp-dll-path }}" ${GITHUB_WORKSPACE}/Source/ProceduralParts.sln 43 | 44 | - name: Remove excess DLLs 45 | uses: KSP-RO/BuildTools/remove-excess-dlls@master 46 | with: 47 | path: ${GITHUB_WORKSPACE}/GameData/ 48 | 49 | - name: Update version file 50 | uses: KSP-RO/BuildTools/update-version-file@master 51 | with: 52 | tag: ${{ github.event.release.tag_name }} 53 | path: ${GITHUB_WORKSPACE}/GameData/ProceduralParts/ProceduralParts.version 54 | 55 | - name: Assemble release 56 | id: assemble-release 57 | run: | 58 | RELEASE_DIR="${RUNNER_TEMP}/release" 59 | echo "Release dir: ${RELEASE_DIR}" 60 | echo "Release zip: ${RELEASE_DIR}/ProceduralParts-${{ github.event.release.tag_name }}.zip" 61 | mkdir -v "${RELEASE_DIR}" 62 | echo "::set-output name=release-dir::${RELEASE_DIR}" 63 | cp -v -R "${GITHUB_WORKSPACE}/GameData" "${RELEASE_DIR}" 64 | cd ${RELEASE_DIR} 65 | zip -r ProceduralParts-${{ github.event.release.tag_name }}.zip GameData 66 | 67 | - name: Upload package to release 68 | uses: actions/upload-release-asset@v1 69 | env: 70 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 71 | with: 72 | upload_url: ${{ github.event.release.upload_url }} 73 | asset_path: ${{ steps.assemble-release.outputs.release-dir }}/ProceduralParts-${{ github.event.release.tag_name }}.zip 74 | asset_name: ProceduralParts-${{ github.event.release.tag_name }}.zip 75 | asset_content_type: application/zip 76 | 77 | - name: Setup git config 78 | run: | 79 | git config user.name "GitHub Actions Bot" 80 | git config user.email "<>" 81 | 82 | - name: Commit changes 83 | shell: bash 84 | env: 85 | TAG_STRING: ${{ github.event.release.tag_name }} 86 | run: | 87 | RELEASEBRANCH=${{ env.tagged_branch }} 88 | git add "${GITHUB_WORKSPACE}/GameData/ProceduralParts/ProceduralParts.version" 89 | git commit -m "Update version to $TAG_STRING" 90 | git push origin $RELEASEBRANCH 91 | git tag $TAG_STRING $RELEASEBRANCH --force 92 | git push origin $TAG_STRING --force 93 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: build 4 | 5 | # Controls when the action will run. 6 | on: 7 | # Triggers the workflow on push or pull request events but only for the master branch 8 | push: 9 | branches: [ master ] 10 | pull_request: 11 | branches: [ master ] 12 | 13 | # Allows you to run this workflow manually from the Actions tab 14 | workflow_dispatch: 15 | 16 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 17 | jobs: 18 | check-secret: 19 | uses: KSP-RO/BuildTools/.github/workflows/check-secret.yml@master 20 | secrets: 21 | KSP_ZIP_PASSWORD: ${{ secrets.KSP_ZIP_PASSWORD }} 22 | 23 | validate-cfg-files: 24 | uses: KSP-RO/BuildTools/.github/workflows/validate-cfg-files.yml@master 25 | 26 | build: 27 | # The type of runner that the job will run on 28 | runs-on: ubuntu-22.04 29 | needs: [check-secret] 30 | if: needs.check-secret.outputs.has-password == 'true' 31 | # Steps represent a sequence of tasks that will be executed as part of the job 32 | steps: 33 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 34 | - name: Checkout 35 | uses: actions/checkout@v2 36 | with: 37 | fetch-depth: 100 38 | 39 | - name: Download required assemblies 40 | id: download-assemblies 41 | uses: KSP-RO/BuildTools/download-assemblies@master 42 | with: 43 | KSP_ZIP_PASSWORD: ${{ secrets.KSP_ZIP_PASSWORD }} 44 | 45 | - name: Build mod solution 46 | run: msbuild /p:Configuration=Release /p:ReferencePath="${{ steps.download-assemblies.outputs.ksp-dll-path }}" ${GITHUB_WORKSPACE}/Source/ProceduralParts.sln 47 | 48 | - name: Remove excess DLLs 49 | uses: KSP-RO/BuildTools/remove-excess-dlls@master 50 | with: 51 | path: ${GITHUB_WORKSPACE}/GameData/ 52 | 53 | - name: Build metadata 54 | uses: KSP-RO/BuildTools/update-version-file@master 55 | with: 56 | path: ${GITHUB_WORKSPACE}/GameData/ProceduralParts/ProceduralParts.version 57 | tag: "v3.0.0.0" 58 | 59 | - name: Assemble release 60 | id: assemble-release 61 | run: | 62 | RELEASE_DIR="${RUNNER_TEMP}/release" 63 | echo "Release dir: ${RELEASE_DIR}" 64 | mkdir -v "${RELEASE_DIR}" 65 | echo "::set-output name=release-dir::${RELEASE_DIR}" 66 | cp -v -R "${GITHUB_WORKSPACE}/GameData" "${RELEASE_DIR}" 67 | 68 | - name: Upload artifacts 69 | uses: actions/upload-artifact@v4 70 | with: 71 | name: ProceduralParts 72 | path: ${{ steps.assemble-release.outputs.release-dir }} 73 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Aa][Rr][Mm]/ 27 | [Aa][Rr][Mm]64/ 28 | bld/ 29 | [Bb]in/ 30 | [Oo]bj/ 31 | [Ll]og/ 32 | *.dll 33 | 34 | # Visual Studio 2015/2017 cache/options directory 35 | .vs/ 36 | # Uncomment if you have tasks that create the project's static files in wwwroot 37 | #wwwroot/ 38 | 39 | # Visual Studio 2017 auto generated files 40 | Generated\ Files/ 41 | 42 | # MSTest test Results 43 | [Tt]est[Rr]esult*/ 44 | [Bb]uild[Ll]og.* 45 | 46 | # NUNIT 47 | *.VisualState.xml 48 | TestResult.xml 49 | 50 | # Build Results of an ATL Project 51 | [Dd]ebugPS/ 52 | [Rr]eleasePS/ 53 | dlldata.c 54 | 55 | # Benchmark Results 56 | BenchmarkDotNet.Artifacts/ 57 | 58 | # .NET Core 59 | project.lock.json 60 | project.fragment.lock.json 61 | artifacts/ 62 | 63 | # StyleCop 64 | StyleCopReport.xml 65 | 66 | # Files built by Visual Studio 67 | *_i.c 68 | *_p.c 69 | *_h.h 70 | *.ilk 71 | *.meta 72 | *.obj 73 | *.iobj 74 | *.pch 75 | *.pdb 76 | *.ipdb 77 | *.pgc 78 | *.pgd 79 | *.rsp 80 | *.sbr 81 | *.tlb 82 | *.tli 83 | *.tlh 84 | *.tmp 85 | *.tmp_proj 86 | *_wpftmp.csproj 87 | *.log 88 | *.vspscc 89 | *.vssscc 90 | .builds 91 | *.pidb 92 | *.svclog 93 | *.scc 94 | 95 | # Chutzpah Test files 96 | _Chutzpah* 97 | 98 | # Visual C++ cache files 99 | ipch/ 100 | *.aps 101 | *.ncb 102 | *.opendb 103 | *.opensdf 104 | *.sdf 105 | *.cachefile 106 | *.VC.db 107 | *.VC.VC.opendb 108 | 109 | # Visual Studio profiler 110 | *.psess 111 | *.vsp 112 | *.vspx 113 | *.sap 114 | 115 | # Visual Studio Trace Files 116 | *.e2e 117 | 118 | # TFS 2012 Local Workspace 119 | $tf/ 120 | 121 | # Guidance Automation Toolkit 122 | *.gpState 123 | 124 | # ReSharper is a .NET coding add-in 125 | _ReSharper*/ 126 | *.[Rr]e[Ss]harper 127 | *.DotSettings.user 128 | 129 | # JustCode is a .NET coding add-in 130 | .JustCode 131 | 132 | # TeamCity is a build add-in 133 | _TeamCity* 134 | 135 | # DotCover is a Code Coverage Tool 136 | *.dotCover 137 | 138 | # AxoCover is a Code Coverage Tool 139 | .axoCover/* 140 | !.axoCover/settings.json 141 | 142 | # Visual Studio code coverage results 143 | *.coverage 144 | *.coveragexml 145 | 146 | # NCrunch 147 | _NCrunch_* 148 | .*crunch*.local.xml 149 | nCrunchTemp_* 150 | 151 | # MightyMoose 152 | *.mm.* 153 | AutoTest.Net/ 154 | 155 | # Web workbench (sass) 156 | .sass-cache/ 157 | 158 | # Installshield output folder 159 | [Ee]xpress/ 160 | 161 | # DocProject is a documentation generator add-in 162 | DocProject/buildhelp/ 163 | DocProject/Help/*.HxT 164 | DocProject/Help/*.HxC 165 | DocProject/Help/*.hhc 166 | DocProject/Help/*.hhk 167 | DocProject/Help/*.hhp 168 | DocProject/Help/Html2 169 | DocProject/Help/html 170 | 171 | # Click-Once directory 172 | publish/ 173 | 174 | # Publish Web Output 175 | *.[Pp]ublish.xml 176 | *.azurePubxml 177 | # Note: Comment the next line if you want to checkin your web deploy settings, 178 | # but database connection strings (with potential passwords) will be unencrypted 179 | *.pubxml 180 | *.publishproj 181 | 182 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 183 | # checkin your Azure Web App publish settings, but sensitive information contained 184 | # in these scripts will be unencrypted 185 | PublishScripts/ 186 | 187 | # NuGet Packages 188 | *.nupkg 189 | # NuGet Symbol Packages 190 | *.snupkg 191 | # The packages folder can be ignored because of Package Restore 192 | **/[Pp]ackages/* 193 | # except build/, which is used as an MSBuild target. 194 | !**/[Pp]ackages/build/ 195 | # Uncomment if necessary however generally it will be regenerated when needed 196 | #!**/[Pp]ackages/repositories.config 197 | # NuGet v3's project.json files produces more ignorable files 198 | *.nuget.props 199 | *.nuget.targets 200 | 201 | # Microsoft Azure Build Output 202 | csx/ 203 | *.build.csdef 204 | 205 | # Microsoft Azure Emulator 206 | ecf/ 207 | rcf/ 208 | 209 | # Windows Store app package directories and files 210 | AppPackages/ 211 | BundleArtifacts/ 212 | Package.StoreAssociation.xml 213 | _pkginfo.txt 214 | *.appx 215 | *.appxbundle 216 | *.appxupload 217 | 218 | # Visual Studio cache files 219 | # files ending in .cache can be ignored 220 | *.[Cc]ache 221 | # but keep track of directories ending in .cache 222 | !?*.[Cc]ache/ 223 | 224 | # Others 225 | ClientBin/ 226 | ~$* 227 | *~ 228 | *.dbmdl 229 | *.dbproj.schemaview 230 | *.jfm 231 | *.pfx 232 | *.publishsettings 233 | orleans.codegen.cs 234 | 235 | # Including strong name files can present a security risk 236 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 237 | #*.snk 238 | 239 | # Since there are multiple workflows, uncomment next line to ignore bower_components 240 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 241 | #bower_components/ 242 | 243 | # RIA/Silverlight projects 244 | Generated_Code/ 245 | 246 | # Backup & report files from converting an old project file 247 | # to a newer Visual Studio version. Backup files are not needed, 248 | # because we have git ;-) 249 | _UpgradeReport_Files/ 250 | Backup*/ 251 | UpgradeLog*.XML 252 | UpgradeLog*.htm 253 | ServiceFabricBackup/ 254 | *.rptproj.bak 255 | 256 | # SQL Server files 257 | *.mdf 258 | *.ldf 259 | *.ndf 260 | 261 | # Business Intelligence projects 262 | *.rdl.data 263 | *.bim.layout 264 | *.bim_*.settings 265 | *.rptproj.rsuser 266 | *- Backup*.rdl 267 | 268 | # Microsoft Fakes 269 | FakesAssemblies/ 270 | 271 | # GhostDoc plugin setting file 272 | *.GhostDoc.xml 273 | 274 | # Node.js Tools for Visual Studio 275 | .ntvs_analysis.dat 276 | node_modules/ 277 | 278 | # Visual Studio 6 build log 279 | *.plg 280 | 281 | # Visual Studio 6 workspace options file 282 | *.opt 283 | 284 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 285 | *.vbw 286 | 287 | # Visual Studio LightSwitch build output 288 | **/*.HTMLClient/GeneratedArtifacts 289 | **/*.DesktopClient/GeneratedArtifacts 290 | **/*.DesktopClient/ModelManifest.xml 291 | **/*.Server/GeneratedArtifacts 292 | **/*.Server/ModelManifest.xml 293 | _Pvt_Extensions 294 | 295 | # Paket dependency manager 296 | .paket/paket.exe 297 | paket-files/ 298 | 299 | # FAKE - F# Make 300 | .fake/ 301 | 302 | # CodeRush personal settings 303 | .cr/personal 304 | 305 | # Python Tools for Visual Studio (PTVS) 306 | __pycache__/ 307 | *.pyc 308 | 309 | # Cake - Uncomment if you are using it 310 | # tools/** 311 | # !tools/packages.config 312 | 313 | # Tabs Studio 314 | *.tss 315 | 316 | # Telerik's JustMock configuration file 317 | *.jmconfig 318 | 319 | # BizTalk build output 320 | *.btp.cs 321 | *.btm.cs 322 | *.odx.cs 323 | *.xsd.cs 324 | 325 | # OpenCover UI analysis results 326 | OpenCover/ 327 | 328 | # Azure Stream Analytics local run output 329 | ASALocalRun/ 330 | 331 | # MSBuild Binary and Structured Log 332 | *.binlog 333 | 334 | # NVidia Nsight GPU debugger configuration file 335 | *.nvuser 336 | 337 | # MFractors (Xamarin productivity tool) working folder 338 | .mfractor/ 339 | 340 | # Local History for Visual Studio 341 | .localhistory/ 342 | 343 | # BeatPulse healthcheck temp database 344 | healthchecksdb 345 | 346 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 347 | MigrationBackup/ 348 | 349 | # macOS 350 | .DS_Store 351 | -------------------------------------------------------------------------------- /GameData/ProceduralParts/KSPCommunityFixes.cfg: -------------------------------------------------------------------------------- 1 | @KSP_COMMUNITY_FIXES:FOR[ProceduralParts] 2 | { 3 | @ModUpgradePipeline = true 4 | } 5 | -------------------------------------------------------------------------------- /GameData/ProceduralParts/ModuleManager/DRE.cfg: -------------------------------------------------------------------------------- 1 | @PART[proceduralTankSRB]:AFTER[DeadlyReentry] 2 | { 3 | @maxTemp = 1250 4 | @MODULE[ModuleEngines] { @heatProduction = 55 } 5 | @MODULE[ProceduralSRB] { @heatPerThrust = 14 } 6 | } 7 | -------------------------------------------------------------------------------- /GameData/ProceduralParts/ModuleManager/FilterExt_proc.cfg: -------------------------------------------------------------------------------- 1 | @PART[*]:HAS[@MODULE[ProceduralPart*]]:NEEDS[FilterExtension] 2 | { 3 | @bulkheadProfiles ^= :$:,proc: 4 | } 5 | 6 | @PART[proceduralBattery]:NEEDS[FilterExtension] 7 | { 8 | @bulkheadProfiles ^= :size0:size00: 9 | } -------------------------------------------------------------------------------- /GameData/ProceduralParts/ModuleManager/KSPCF.cfg: -------------------------------------------------------------------------------- 1 | @KSP_COMMUNITY_FIXES:AFTER[KSPCommunityFixes] 2 | { 3 | @PersistentIConfigNode = true 4 | } 5 | -------------------------------------------------------------------------------- /GameData/ProceduralParts/ModuleManager/ModularFuelTanks.cfg: -------------------------------------------------------------------------------- 1 | @PART[proceduralTankLiquid]:AFTER[ModularFuelTanks] 2 | { 3 | !MODULE[TankContentSwitcher] {} 4 | %MODULE[ModuleFuelTanks] 5 | { 6 | type = Default 7 | volume = 211 8 | tankVolumeConversion = 200 9 | } 10 | } 11 | 12 | @PART[proceduralTankRCS]:AFTER[ModularFuelTanks] 13 | { 14 | !MODULE[TankContentSwitcher] {} 15 | %MODULE[ModuleFuelTanks] 16 | { 17 | type = RCS 18 | volume = 106 19 | tankVolumeConversion = 200 20 | } 21 | } 22 | 23 | @PART[proceduralTankXenon]:AFTER[ModularFuelTanks] 24 | { 25 | !MODULE[TankContentSwitcher] {} 26 | %MODULE[ModuleFuelTanks] 27 | { 28 | type = Xenon 29 | volume = 792 30 | tankVolumeConversion = 10000 31 | } 32 | } 33 | @PART[proceduralConeLiquid]:AFTER[ModularFuelTanks] 34 | { 35 | !MODULE[TankContentSwitcher] {} 36 | %MODULE[ModuleFuelTanks] 37 | { 38 | type = Default 39 | volume = 77 40 | tankVolumeConversion = 200 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /GameData/ProceduralParts/ModuleManager/RealFuels.cfg: -------------------------------------------------------------------------------- 1 | // Delete all the normal fuel tanks. 2 | 3 | @PART[proceduralTankSRB]:NEEDS[RealFuels] { @name = proceduralSRBRealFuels } 4 | !PART[proceduralTankRCS]:NEEDS[RealFuels] {} 5 | !PART[proceduralTankXenon]:NEEDS[RealFuels] {} 6 | !PART[proceduralConeLiquid]:NEEDS[RealFuels] {} 7 | 8 | @PARTUPGRADE:HAS[#partIcon[proceduralTankLiquid]]:NEEDS[RealFuels] 9 | { 10 | @partIcon = proceduralTankRealFuels 11 | } 12 | 13 | @PARTUPGRADE:HAS[#partIcon[proceduralTankSRB]]:NEEDS[RealFuels] 14 | { 15 | @partIcon = proceduralSRBRealFuels 16 | } 17 | 18 | @PART[proceduralTankLiquid]:NEEDS[RealFuels] 19 | { 20 | @name = proceduralTankRealFuels 21 | @title = Procedural Real Fuels Tank 22 | @description ^= :^:Baseline tank type. Accepts most fuels. Can be switched between unpressurised, balloon, cryogenic, ballooon cryo, and service module types. : 23 | 24 | @MODULE[ProceduralPart] { %costPerkL = 0.00957 } 25 | 26 | !MODULE[TankContentSwitcher] {} 27 | MODULE 28 | { 29 | name = ModuleFuelTanks 30 | 31 | volume = 1060 32 | utilizationTweakable = true 33 | type = Default 34 | typeAvailable = Default 35 | typeAvailable = Cryogenic 36 | typeAvailable = ServiceModule 37 | typeAvailable = Fuselage 38 | typeAvailable = Balloon 39 | typeAvailable = BalloonCryo 40 | typeAvailable = Structural 41 | typeAvailable = ElectricPropulsion 42 | } 43 | } 44 | 45 | @TANK_DEFINITION[Solid]:FOR[ProceduralParts]:NEEDS[RealFuels] 46 | { 47 | !TANK,* {} 48 | // tank with same fuel as default CONFIG should start out full, so a default-placed part will show some burn time & dv 49 | // Default the current legacy fuel 50 | TANK 51 | { 52 | name = SolidFuel // Retain old default for generic "SolidFuel" so long as that exists in RF 53 | amount = full 54 | maxAmount = 100% 55 | cost = 0 // FIXME: we'd normally expect resource cost to handle this, but all solid fuels get zeros as resurce costs because it's all figured into the part costs. So would have to assign something here. cost is per-litre 56 | mass = 0 // *dry* mass in tons per liter of fuel. We don't need per-fuel-type variations here, so basemass is all we need to set. Might make sense to use this for a fuel that needs an unusually strong casing? 57 | } 58 | 59 | // Build tanks defined in RealFuels proper 60 | +TANK[SolidFuel] { 61 | @name = PSPC // sep motors, baby sergeant, altair I, castor, gcrc 62 | // the other fuels should default empty, since they all share the same volume 63 | @amount = 0 64 | @maxAmount = 0 65 | } 66 | 67 | +TANK[PSPC] { @name = HTPB } // star37e, antares iii 68 | +TANK[PSPC] { @name = PBAN } // altair iii, ua120x, rsrm 69 | +TANK[PSPC] { @name = NGNC } // tiny tim, Nike, etc. a reasonable default/starting fuel? 70 | +TANK[PSPC] { @name = HNIW } // waxwing, star17 71 | 72 | // Some RO fuels? 73 | //+TANK[PSPC]:NEEDS[RealismOverhaul] { @name = PBAA } // altair II, antares, castor 2 74 | //+TANK[PSPC]:NEEDS[RealismOverhaul] { @name = PUPE } // algol 75 | //+TANK[PSPC]:NEEDS[RealismOverhaul] { @name = CTPB } // waxwing, star17 76 | } 77 | -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/Electrical/Battery.cfg: -------------------------------------------------------------------------------- 1 | PART 2 | { 3 | // --- general parameters --- 4 | name = proceduralBattery 5 | module = Part 6 | author = Swamp Ig 7 | 8 | // --- asset parameters --- 9 | MODEL 10 | { 11 | model = ProceduralParts/Parts/cylinderTank 12 | scale = 1,1,1 13 | } 14 | scale = 1 15 | rescaleFactor = 1 16 | 17 | // --- node definitions --- 18 | node_stack_top=0,0.5,0,0,1,0,1 19 | node_stack_bottom=0,-0.5,0,0,-1,0,1 20 | node_attach=0,0,0.5,0,0,-1,1 21 | 22 | // --- editor parameters --- 23 | TechRequired = basicScience 24 | entryCost = 8200 25 | cost = 0 // 880 26 | category = Electrical 27 | subcategory = 0 28 | title = Procedural Battery 29 | manufacturer = Kerbchem Industries 30 | description = With further refinements to procedural tech, we were able to fill a viscoelastic nanopolymer shell with electroactive particles. This gives you a battery able to be adapted to many shapes. 31 | 32 | // attachment rules: stack, srfAttach, allowStack, allowSrfAttach, allowCollision 33 | attachRules = 1,1,1,1,0 34 | 35 | // --- standard part parameters --- 36 | mass = 1 37 | dragModelType = default 38 | maximum_drag = 0.2 39 | minimum_drag = 0.2 40 | angularDrag = 1 41 | crashTolerance = 8 42 | maxTemp = 2000 43 | bulkheadProfiles = size0, srf 44 | 45 | MODULE 46 | { 47 | name = ProceduralPart 48 | textureSet = BlueSide 49 | shapeName = Cylinder 50 | 51 | diameterMin = 0.01 52 | lengthMin = 0.01 53 | volumeMin = 0 54 | diameterMax = 0.5 55 | lengthMax = 1.0 56 | volumeMax = 0.04 // 0.04 supports 150 57 | updateDragCubesInEditor:NEEDS[FerramAerospaceResearch] = true 58 | 59 | UPGRADES 60 | { 61 | UPGRADE 62 | { 63 | name__ = ProceduralPartsBattery300 64 | diameterMax = 1.0 65 | lengthMax = 1.0 66 | volumeMax = 0.08 67 | } 68 | UPGRADE 69 | { 70 | name__ = ProceduralPartsBattery600 71 | diameterMax = 1.75 72 | lengthMax = 0.75 73 | volumeMax = 0.16 74 | } 75 | UPGRADE 76 | { 77 | name__ = ProceduralPartsBattery2400 78 | volumeMax = 0.64 79 | } 80 | UPGRADE 81 | { 82 | name__ = ProceduralPartsBattery4800 83 | diameterMax = 3.0 84 | lengthMax = 1.5 85 | volumeMax = 1.28 86 | } 87 | UPGRADE 88 | { 89 | name__ = ProceduralPartsBatteryUnlimited 90 | diameterMax = Infinity 91 | lengthMax = Infinity 92 | volumeMax = Infinity 93 | } 94 | } 95 | } 96 | MODULE 97 | { 98 | name = ProceduralShapeCylinder 99 | displayName = Cylinder 100 | 101 | length = 0.375 102 | diameter = 0.375 103 | } 104 | MODULE 105 | { 106 | name = ProceduralShapeCone 107 | displayName = Cone 108 | techRequired = electrics 109 | 110 | length = 0.375 111 | topDiameter = 0.375 112 | bottomDiameter = 0.625 113 | } 114 | MODULE 115 | { 116 | name = ProceduralShapePill 117 | displayName = Fillet Cylinder 118 | techRequired = advElectrics 119 | 120 | diameter = 0.5 121 | length = 0.875 122 | fillet = 0.375 123 | } 124 | MODULE 125 | { 126 | name = ProceduralShapeBezierCone 127 | displayName = Smooth Cone 128 | techRequired = largeElectrics 129 | 130 | selectedShape = Round1 131 | length = 0.625 132 | topDiameter = 0.25 133 | bottomDiameter = 0.5 134 | } 135 | MODULE 136 | { 137 | name = ProceduralShapePolygon 138 | displayName = Polygon 139 | techRequired = start 140 | 141 | length = 0.5 142 | diameter = 0.5 143 | } 144 | MODULE 145 | { 146 | name = TankContentSwitcher 147 | useVolume = true 148 | 149 | TANK_TYPE_OPTION 150 | { 151 | name = Electric 152 | // Dry density for the battery banks for Z-200 and Z-4k is 0.163, 153 | // and the Z-1k is 0.184. We want to keep this to some 'roundish' 154 | // number so the max volumes don't end up as weird fractions of 155 | // pi, so will round it a bit. 156 | dryDensity = 0.1875 157 | RESOURCE 158 | { 159 | name = ElectricCharge 160 | // All stock parts are the same. This translates to 3500 U / kL 161 | unitsPerT = 20000 162 | } 163 | } 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/HighRatio.mu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/HighRatio.mu -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/LowRatio.mu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/LowRatio.mu -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/SRBBell.mu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/SRBBell.mu -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/StretchySRBBell.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/StretchySRBBell.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/StretchySRBBell_EM.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/StretchySRBBell_EM.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/StretchySRBBell_NRM.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/StretchySRBBell_NRM.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/Structural/Heatshield.cfg: -------------------------------------------------------------------------------- 1 | PART 2 | { 3 | // --- general parameters --- 4 | name = proceduralHeatshield 5 | module = Part 6 | author = AncientGammoner, NathanKell, Swamp Ig, OtherBarry 7 | 8 | // --- asset parameters --- 9 | MODEL 10 | { 11 | model = ProceduralParts/Parts/heatshield 12 | scale = 1,1,1 13 | } 14 | scale = 1 15 | rescaleFactor = 1 16 | 17 | // --- node definitions --- 18 | node_stack_top=0,0.5,0,0,1,0,1 19 | node_stack_bottom=0,-0.5,0,0,-1,0,1 20 | node_attach=0,0,0.5,0,0,-1,1 21 | 22 | // --- editor parameters --- 23 | cost = 0 24 | TechRequired = survivability 25 | entryCost = 4200 26 | category = Thermal 27 | subcategory = 0 28 | title = Procedural Heatshield 29 | manufacturer = Kerbchem Industries 30 | description = Made from viscoelastic nanopolymers (which were discovered by accident... growing in the back of the office mini-fridge) this ablative heat shield can be stretched to a range of sizes. Hardens to a rigid, heat resistant structure before launch! 31 | 32 | // attachment rules: stack, srfAttach, allowStack, allowSrfAttach, allowCollision 33 | attachRules = 1,0,1,1,0 34 | 35 | // --- standard part parameters --- 36 | mass = 1 37 | dragModelType = default 38 | maximum_drag = 0.2 39 | minimum_drag = 0.2 40 | angularDrag = 2 41 | crashTolerance = 9 42 | breakingForce = 200 43 | breakingTorque = 200 44 | fuelCrossFeed = False 45 | PhysicsSignificance = 0 46 | maxTemp = 3000 47 | stageOffset = 1 48 | childStageOffset = 1 49 | bulkheadProfiles = size1 50 | thermalMassModifier = 1 51 | 52 | MODULE 53 | { 54 | name = ProceduralPart 55 | textureSet = Ablative 56 | shapeName = Smooth Cone 57 | capTextureIndex = 1 58 | diameterMin = 1.0 59 | lengthMin = 0.1 60 | volumeMin = 0 61 | diameterMax = 1.5 62 | lengthMax = 0.5 63 | volumeMax = Infinity 64 | allowCurveTweaking = False 65 | updateDragCubesInEditor:NEEDS[FerramAerospaceResearch] = true 66 | 67 | costsIncludeResources = false 68 | baseCost=1 69 | costPerkL=0 70 | 71 | UPGRADES 72 | { 73 | UPGRADE 74 | { 75 | name__ = ProceduralPartsHeatshield3m 76 | diameterMax = 3.0 77 | } 78 | UPGRADE 79 | { 80 | name__ = ProceduralPartsHeatshield5m 81 | diameterMax = 5.0 82 | } 83 | UPGRADE 84 | { 85 | name__ = ProceduralPartsHeatshield0.125m 86 | diameterMin = 0.125 87 | } 88 | UPGRADE 89 | { 90 | name__ = ProceduralPartsHeatshieldUnlimited 91 | diameterMin = 0.01 92 | diameterMax = Infinity 93 | lengthMin = 0.1 94 | lengthMax = Infinity 95 | } 96 | } 97 | } 98 | MODULE 99 | { 100 | name = ProceduralShapeBezierCone 101 | displayName = Smooth Cone 102 | 103 | selectedShape = Round3 104 | 105 | length = 0.2 106 | topDiameter =1.25 107 | bottomDiameter = 0 108 | coneBottomMode = Constant 109 | } 110 | 111 | MODULE 112 | { 113 | name = ModuleAblator 114 | ablativeResource = Ablator 115 | lossExp = -7500 116 | lossConst = 0.1 117 | pyrolysisLossFactor = 6000 118 | reentryConductivity = 0.01 119 | ablationTempThresh = 500 120 | } 121 | 122 | MODULE 123 | { 124 | name=ProceduralHeatshield 125 | textureSet=Stockalike 126 | ablatorPerArea=162.9746 127 | multiplyCostByDiameter=240 128 | //massPerDiameter=0.2 129 | 130 | massFromDiameterCurve 131 | { 132 | key = 0 0 133 | key = 1.25 0.1 134 | key = 2.5 0.5 135 | key = 3.75 1 136 | key = 50 50 137 | } 138 | 139 | CoPoffset 140 | { 141 | key = 0 0.8 142 | key = 1.25 1 143 | key = 2.5 1.1 144 | key = 3.75 1.4 145 | key = 50 10 146 | } 147 | } 148 | 149 | MODULE 150 | { 151 | name = ModuleJettison 152 | jettisonName = fairing 153 | bottomNodeName = bottom 154 | isFairing = True 155 | jettisonedObjectMass = 0.5 156 | jettisonForce = 15 157 | jettisonDirection = 0 0 1 158 | } 159 | 160 | RESOURCE 161 | { 162 | name = Ablator 163 | amount = 0 164 | maxAmount = 0 165 | flowMode = Out 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/Structural/NoseCone.cfg: -------------------------------------------------------------------------------- 1 | +PART[proceduralTankLiquid]:FIRST 2 | { 3 | @name = proceduralNoseCone 4 | @title = Procedural Nose Cone 5 | @author = AncientGammoner, NathanKell, Swamp Ig, OtherBarry 6 | 7 | @TechRequired = stability 8 | @category = Aero 9 | @entryCost = 6800 10 | 11 | @maximum_drag = 0.1 12 | @minimum_drag = 0.1 13 | @angularDrag = 0.25 14 | @maxTemp = 2400 15 | 16 | @MODULE[ProceduralPart] 17 | { 18 | @textureSet = WhiteSide 19 | @shapeName = Smooth Cone 20 | @costPerkL=200 21 | 22 | //aspectMin = 1.0 23 | //aspectMax = 8.0 24 | @diameterMin = 0.55 25 | @diameterMax = 1.5 26 | @lengthMin = 0.625 27 | @lengthMax = 0.625 28 | @volumeMin = 0 29 | @volumeMax = Infinity 30 | 31 | !UPGRADES,* {} 32 | UPGRADES 33 | { 34 | UPGRADE 35 | { 36 | name__ = ProceduralPartsNoseCone1.5M 37 | lengthMax = 1.5 38 | } 39 | UPGRADE 40 | { 41 | name__ = ProceduralPartsNoseCone2.5M 42 | diameterMax = 2.5 43 | } 44 | UPGRADE 45 | { 46 | name__ = ProceduralPartsNoseConeUnlimited 47 | diameterMin = 0.01 48 | diameterMax = Infinity 49 | } 50 | } 51 | } 52 | !MODULE[ProceduralShape*],* {} 53 | MODULE 54 | { 55 | name = ProceduralShapeBezierCone 56 | displayName = Smooth Cone 57 | 58 | selectedShape = Round1 59 | length = 0.625 60 | topDiameter = 0 61 | bottomDiameter = 1.25 62 | 63 | coneTopMode = Constant 64 | } 65 | !MODULE[TankContentSwitcher] {} 66 | MODULE 67 | { 68 | name = TankContentSwitcher 69 | useVolume = true 70 | 71 | TANK_TYPE_OPTION 72 | { 73 | name = Structural 74 | dryDensity = 0.068 75 | isStructural = true 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/Structural/StackDecoupler.cfg: -------------------------------------------------------------------------------- 1 | PART 2 | { 3 | // --- general parameters --- 4 | name = proceduralStackDecoupler 5 | module = Part 6 | author = AncientGammoner, NK, Tiberion, NathanKell, Swamp Ig, jsimmonds 7 | 8 | // --- asset parameters --- 9 | MODEL 10 | { 11 | model = ProceduralParts/Parts/cylinderTank 12 | scale = 1,1,1 13 | } 14 | scale = 1 15 | rescaleFactor = 1 16 | 17 | // --- node definitions --- 18 | node_stack_top=0,0.5,0,0,1,0,1 19 | node_stack_bottom=0,-0.5,0,0,-1,0,1 20 | 21 | // --- FX definitions --- 22 | fx_gasBurst_white = 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, decouple 23 | sound_decoupler_fire = decouple 24 | 25 | // --- editor parameters --- 26 | cost = 0 // 200 27 | TechRequired = engineering101 28 | category = Coupling 29 | subcategory = 0 30 | title = Procedural Stack Decoupler 31 | manufacturer = Kerbchem Industries 32 | description = Made from viscoelastic nanopolymers (which were discovered by accident... growing in the back of the office mini-fridge) this decoupler can be stretched to accommodate a range of sizes. 33 | 34 | // attachment rules: stack, srfAttach, allowStack, allowSrfAttach, allowCollision 35 | attachRules = 1,0,1,1,0 36 | 37 | // --- standard part parameters --- 38 | mass = 1 39 | dragModelType = default 40 | maximum_drag = 0.2 41 | minimum_drag = 0.2 42 | angularDrag = 2 43 | crashTolerance = 9 44 | maxTemp = 2000 45 | fuelCrossFeed = False 46 | bulkheadProfiles = size1 47 | 48 | stageOffset = 1 49 | childStageOffset = 1 50 | 51 | MODULE 52 | { 53 | name = ProceduralPart 54 | textureSet = PlainWhite 55 | shapeName = Fillet Cylinder 56 | 57 | // Only the diameter is tweakable, not the length or the curve 58 | diameterMin = 1 59 | lengthMin = 0.2 60 | volumeMin = 0 61 | diameterMax = 1.75 62 | lengthMax = 0.2 63 | volumeMax = Infinity 64 | updateDragCubesInEditor:NEEDS[FerramAerospaceResearch] = true 65 | 66 | // If you want to be able to tweak the fillet curve, comment this line 67 | allowCurveTweaking = false 68 | 69 | UPGRADES 70 | { 71 | UPGRADE 72 | { 73 | name__ = ProceduralPartsDecoupler3m 74 | diameterMax = 3.0 75 | } 76 | UPGRADE 77 | { 78 | name__ = ProceduralPartsDecoupler4.5m 79 | diameterMax = 4.5 80 | } 81 | UPGRADE 82 | { 83 | name__ = ProceduralPartsDecoupler0.125m 84 | diameterMin = 0.125 85 | } 86 | UPGRADE 87 | { 88 | name__ = ProceduralPartsDecouplerUnlimited 89 | diameterMin = 0.01 90 | diameterMax = Infinity 91 | } 92 | } 93 | } 94 | 95 | MODULE 96 | { 97 | name = ProceduralShapePill 98 | displayName = Fillet Cylinder 99 | length = 0.2 100 | diameter = 1.25 101 | fillet = 0.05 102 | } 103 | 104 | MODULE 105 | { 106 | name = ProceduralShapeHollowPill 107 | displayName = Hollow Fillet Cylinder 108 | length = 0.2 109 | outerDiameter = 1.25 110 | innerDiameter = 0.625 111 | fillet = 0.05 112 | } 113 | 114 | MODULE 115 | { 116 | name = ModuleDecouple 117 | ejectionForce = 250 118 | explosiveNodeID = top 119 | } 120 | 121 | MODULE 122 | { 123 | name = DecouplerTweaker 124 | 125 | // Separator mode is available only with this tech 126 | separatorTechRequired = advMetalworks 127 | 128 | // Node to listen on. This should be the same as explosiveNodeID above. 129 | textureMessageName = top 130 | 131 | // Stock-alike density. This seems pretty extreme compared to everything else really 132 | // They're small parts anyhow so it doesn't matter too much. 133 | density = 0.33 134 | 135 | // A 1m diameter decoupler could be brought up to a 8 kNs impulse 136 | // ie: If the bottom and top payload mass were 1 ton each, at max 137 | // after firing the parts would be moving away from each other at 8m/s 138 | maxImpulseMassRatio = 8 139 | } 140 | 141 | MODULE 142 | { 143 | name = ModuleToggleCrossfeed 144 | crossfeedStatus = false 145 | toggleEditor = true 146 | toggleFlight = true 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/Structural/Structural.cfg: -------------------------------------------------------------------------------- 1 | +PART[proceduralTankLiquid]:FIRST 2 | { 3 | @name = proceduralStructural 4 | 5 | @TechRequired = advConstruction 6 | @category = Structural 7 | @title = Procedural Structural Element 8 | 9 | // Inherit upgrades, dimensions, etc 10 | @MODULE[ProceduralPart] { @textureSet = WhiteSide } 11 | 12 | @MODULE[TankContentSwitcher] 13 | { 14 | // Using stock structural fuselage you actually pay a mass penalty over the equivalent 15 | // empty tank, which makes no sense to me. Will give it about half the dry density. 16 | !TANK_TYPE_OPTION,* {} 17 | %TANK_TYPE_OPTION[Structural] 18 | { 19 | dryDensity = 0.05 20 | isStructural = true 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/Tanks/1TankLiquid.cfg: -------------------------------------------------------------------------------- 1 | PART 2 | { 3 | // --- general parameters --- 4 | name = proceduralTankLiquid 5 | module = Part 6 | author = AncientGammoner, NathanKell, Swamp Ig 7 | 8 | // --- asset parameters --- 9 | MODEL 10 | { 11 | model = ProceduralParts/Parts/cylinderTank 12 | scale = 1,1,1 13 | } 14 | scale = 1 15 | rescaleFactor = 1 16 | 17 | // --- node definitions --- 18 | node_stack_top=0,0.5,0,0,1,0,1 19 | node_stack_bottom=0,-0.5,0,0,-1,0,1 20 | node_attach=0,0,0.5,0,0,-1,1 21 | 22 | // --- editor parameters --- 23 | cost = 0 // 4000 24 | TechRequired = basicRocketry 25 | entryCost = 4000 26 | category = FuelTank 27 | subcategory = 0 28 | title = Procedural Liquid Tank 29 | manufacturer = Kerbchem Industries 30 | description = Made from viscoelastic nanopolymers (which were discovered by accident... growing in the back of the office mini-fridge) this fuel tank can be stretched to accommodate fuel loads of a range of sizes and shapes. Hardens to a rigid structure before launch! 31 | 32 | // attachment rules: stack, srfAttach, allowStack, allowSrfAttach, allowCollision 33 | attachRules = 1,1,1,1,0 34 | 35 | // --- standard part parameters --- 36 | mass = 1 37 | dragModelType = default 38 | maximum_drag = 0.2 39 | minimum_drag = 0.2 40 | angularDrag = 2 41 | crashTolerance = 7 42 | breakingForce = 200 43 | breakingTorque = 200 44 | maxTemp = 2000 45 | bulkheadProfiles = size1, srf 46 | 47 | MODULE 48 | { 49 | name = ProceduralPart 50 | shapeName = Cylinder // Setting the default shapeName to a hollow shape breaks surface attaching for a new part. Placing it and picking it up again fixes the issue. 51 | 52 | // FL-T100 (basicRocketry) - 1.25 x 0.78125 m = 0.959 kL 53 | diameterMin = 1.0 54 | diameterMax = 1.5 55 | lengthMin = 0.5 56 | lengthMax = 0.75 57 | volumeMin = 0.6 58 | volumeMax = 0.8 59 | updateDragCubesInEditor:NEEDS[FerramAerospaceResearch] = true 60 | 61 | UPGRADES 62 | { 63 | UPGRADE 64 | { 65 | // FL-T200 - 1.25 x 1.1105 m = 1.363 kL 66 | name__ = ProceduralPartsTank1500L 67 | lengthMax = 1.5 68 | volumeMax = 1.5 69 | } 70 | UPGRADE 71 | { 72 | // FL-T400 - 1.25 x 1.87819 m = 2.305 kL 73 | name__ = ProceduralPartsTank2500L 74 | lengthMax = 2.0 75 | volumeMax = 2.5 76 | } 77 | UPGRADE 78 | { 79 | // Mk0 80 | name__ = ProceduralPartsTankAviation 81 | diameterMin = 0.625 82 | volumeMin = 0.3 83 | } 84 | UPGRADE 85 | { 86 | // FL-T800 - 1.25 x 3.75 m = 4.602 kL 87 | // X200-32 - 2.5 x 3.75 m = 18.408 kL 88 | name__ = ProceduralPartsTank20000L 89 | lengthMax = 4.0 90 | diameterMax = 3.0 91 | volumeMax = 20 92 | } 93 | UPGRADE 94 | { 95 | // Jumbo-64 - 2.5 x 7.5 m = 36.816 kL 96 | name__ = ProceduralPartsTank37000L 97 | lengthMax = 8.0 98 | volumeMax = 37.0 99 | } 100 | UPGRADE 101 | { 102 | // Kerbodyne S3-7200 - 3.75 x 4.0 103 | name__ = ProceduralPartsTank45000L 104 | diameterMax = 5.0 105 | volumeMax = 45.0 106 | } 107 | UPGRADE 108 | { 109 | // Kerbodyne S3-14400 - 3.75 x 7.5 = 82.614kl 110 | name__ = ProceduralPartsTank85000L 111 | // diameterMax = 5.0 112 | volumeMax = 85.0 113 | } 114 | UPGRADE 115 | { 116 | // Oscar-B - 0.625 x 0.3485474 m = 0.107 kL. Not in main sequence. Depends indirectly off basicRocketry 117 | name__ = ProceduralPartsTankMiniaturization 118 | diameterMin = 0.125 119 | lengthMin = 0.125 120 | volumeMin = 0.0625 121 | } 122 | UPGRADE 123 | { 124 | name__ = ProceduralPartsTankUnlimited 125 | diameterMin = 0.01 126 | diameterMax = Infinity 127 | lengthMin = 0.01 128 | lengthMax = Infinity 129 | volumeMin = 0 130 | volumeMax = Infinity 131 | } 132 | } 133 | } 134 | MODULE 135 | { 136 | name = ProceduralShapeCylinder 137 | displayName = Cylinder 138 | techRequired = start 139 | 140 | length = 0.75 141 | diameter = 1 142 | } 143 | MODULE 144 | { 145 | name = ProceduralShapeCone 146 | displayName = Cone 147 | techRequired = generalConstruction 148 | 149 | length = 0.5 150 | topDiameter = 1 151 | bottomDiameter = 1.25 152 | } 153 | MODULE 154 | { 155 | name = ProceduralShapePill 156 | displayName = Fillet Cylinder 157 | techRequired = advConstruction 158 | 159 | length = 0.75 160 | diameter = 1 161 | fillet = 0.25 162 | } 163 | MODULE 164 | { 165 | name = ProceduralShapeBezierCone 166 | displayName = Smooth Cone 167 | techRequired = advConstruction 168 | 169 | selectedShape = Round1 170 | 171 | length = 0.5 172 | topDiameter = 1.0 173 | bottomDiameter = 1.25 174 | } 175 | MODULE 176 | { 177 | name = ProceduralShapePolygon 178 | displayName = Polygon 179 | techRequired = start 180 | 181 | length = 0.75 182 | diameter = 1.0 183 | } 184 | MODULE 185 | { 186 | name = ProceduralShapeHollowCylinder 187 | displayName = Hollow Cylinder 188 | techRequired = start 189 | length = 0.75 190 | innerDiameter = 0.5 191 | outerDiameter = 1 192 | } 193 | MODULE 194 | { 195 | name = ProceduralShapeHollowCone 196 | displayName = Hollow Cone 197 | techRequired = start 198 | length = 0.5 199 | topInnerDiameter = 0.5 200 | topOuterDiameter = 1 201 | bottomInnerDiameter = 0.5 202 | bottomOuterDiameter = 1.25 203 | } 204 | MODULE 205 | { 206 | name = ProceduralShapeHollowPill 207 | displayName = Hollow Fillet Cylinder 208 | techRequired = start 209 | 210 | length = 0.75 211 | innerDiameter = 0.5 212 | outerDiameter = 1 213 | fillet = 0.25 214 | } 215 | MODULE 216 | { 217 | name = ProceduralShapeHollowTruss 218 | displayName = Truss 219 | techRequired = start 220 | 221 | length = 0.5 222 | topDiameter = 1 223 | bottomDiameter = 1.25 224 | rodDiameter = 0.125 225 | } 226 | MODULE 227 | { 228 | name = TankContentSwitcher 229 | useVolume = true 230 | 231 | // All mixed fuel tanks with the exception of the micro ones have the same resource per ton 232 | // All the X200 series, plus the FL-T800 have the same dry density and resource units per kL volume 233 | TANK_TYPE_OPTION 234 | { 235 | name = Mixed 236 | // This is the dry mass of the tank per kL of volume. 237 | dryDensity = 0.1089 238 | costMultiplier = 1.0 239 | RESOURCE 240 | { 241 | name = LiquidFuel 242 | //unitsPerKL = 78.22784 243 | unitsPerT = 720 244 | } 245 | RESOURCE 246 | { 247 | name = Oxidizer 248 | //unitsPerKL = 95.6118 249 | unitsPerT = 880 250 | } 251 | } 252 | 253 | // Stock tanks for liquid fuels are pretty un-physical in terms of their mass ratios 254 | // The only one where it is relatively easy to calculate the volume for is Mk1 fuselage 255 | // which gives a higher dry density than the mixed tanks. I have used a different dry 256 | // density (lower than the stock, but higher than stretchy SRB was using) 257 | 258 | // The other tanks with the exception of the Mk1 have 800 units per T dry mass of fuel 259 | // This gives you a slight advantage to using the liquid fuel tanks ahead of the mixed tank 260 | TANK_TYPE_OPTION 261 | { 262 | name = LiquidFuel 263 | dryDensity = 0.1089 // StretchySRB: 0.0450, Mk1: 0.15211 264 | costMultiplier = 0.65 265 | RESOURCE 266 | { 267 | name = LiquidFuel 268 | unitsPerT = 1600 // StretchySRB unitsPerKL: 49.9789, Mk: 65.19 269 | } 270 | } 271 | 272 | // Nothing much to go on for oxidizer tanks, will keep the same dry density and ratio. 273 | TANK_TYPE_OPTION 274 | { 275 | name = Oxidizer 276 | dryDensity = 0.1089 // 0.0815 in StretchySRB 277 | costMultiplier = 0.75 278 | RESOURCE 279 | { 280 | name = Oxidizer 281 | unitsPerT = 1600 // unitsPerKL 81.4873 in StetchySRB 282 | } 283 | } 284 | } 285 | } 286 | -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/Tanks/2TankRCS.cfg: -------------------------------------------------------------------------------- 1 | +PART[proceduralTankLiquid]:FIRST 2 | { 3 | @name = proceduralTankRCS 4 | @TechRequired = advFuelSystems 5 | @title = Procedural RCS Tank 6 | 7 | @cost = 165 8 | @breakingForce = 50 9 | @breakingTorque = 50 10 | 11 | %RESOURCE[MonoPropellant] 12 | { 13 | amount = 135 14 | maxAmount = 135 15 | } 16 | 17 | @MODULE[ProceduralPart] 18 | { 19 | %textureSet = Stockalike 20 | // FL-R1 - 2.5 x 1 m = 4.91 kL 21 | @diameterMin = 0.5 22 | @diameterMax = 3.0 23 | @lengthMin = 0.3 24 | @lengthMax = 2.0 25 | @volumeMin = 0.11 26 | @volumeMax = 5 27 | 28 | @UPGRADES 29 | { 30 | !UPGRADE:HAS[~name__[ProceduralPartsTankUnlimited]] {} 31 | } 32 | } 33 | @MODULE[ProceduralShapeCylinder] 34 | { 35 | @length = 0.5 36 | @diameter = 1.25 37 | } 38 | @MODULE[ProceduralShapeCone] 39 | { 40 | @length = 0.750 41 | @topDiameter = 0.625 42 | @bottomDiameter = 1.25 43 | } 44 | @MODULE[ProceduralShapePill] 45 | { 46 | @length = 0.625 47 | @diameter = 1.25 48 | @fillet = 0.25 49 | } 50 | @MODULE[ProceduralShapeBezierCone] 51 | { 52 | @length = 0.750 53 | @topDiameter = 0.625 54 | @bottomDiameter = 1.25 55 | } 56 | @MODULE[ProceduralShapePolygon] 57 | { 58 | @length = 1.0 59 | @diameter = 1.25 60 | } 61 | @MODULE[TankContentSwitcher] 62 | { 63 | !TANK_TYPE_OPTION,* {} 64 | // Dry density and fuel units per kL are all over the shop for RCS. Basing on FL-R25 65 | %TANK_TYPE_OPTION[RCS] 66 | { 67 | dryDensity = 0.22 68 | %RESOURCE[MonoPropellant] { unitsPerT = 1000 } // FL-R10 and Stratus-V Cyl. 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/Tanks/3TankXenon.cfg: -------------------------------------------------------------------------------- 1 | +PART[proceduralTankLiquid]:FIRST 2 | { 3 | @name = proceduralTankXenon 4 | @title = Procedural Xenon Tank 5 | @author ^= :$: Eggman360: 6 | @TechRequired = ionPropulsion 7 | 8 | @cost = 3000 9 | @breakingForce = 50 10 | @breakingTorque = 50 11 | @bulkheadProfiles = size0, srf 12 | 13 | %RESOURCE[XenonGas] 14 | { 15 | amount = 747.5 16 | maxAmount = 747.5 17 | } 18 | 19 | @MODULE[ProceduralPart] 20 | { 21 | %textureSet = Copernicus 22 | 23 | // FL-R25 - 1.25 x 0.5706054 m = 0.700238177 kL 24 | %diameterMin = 0.125 25 | %diameterMax = 0.75 26 | %lengthMin = 0.1 27 | %lengthMax = 0.75 28 | %volumeMin = 0.02 29 | %volumeMax = 0.2 30 | 31 | @UPGRADES 32 | { 33 | !UPGRADE,* {} 34 | UPGRADE 35 | { 36 | name__ = ProceduralPartsTankUnlimited 37 | diameterMin = 0.01 38 | diameterMax = Infinity 39 | lengthMin = 0.01 40 | lengthMax = Infinity 41 | volumeMin = 0 42 | volumeMax = Infinity 43 | } 44 | } 45 | } 46 | 47 | @MODULE[ProceduralShapeCylinder] 48 | { 49 | @length = 0.3 50 | @diameter = 0.625 51 | } 52 | @MODULE[ProceduralShapeCone] 53 | { 54 | @length = 0.3 55 | @topDiameter = 0.162 56 | @bottomDiameter = 0.625 57 | } 58 | @MODULE[ProceduralShapePill] 59 | { 60 | @length = 0.3 61 | @diameter = 0.625 62 | @fillet = 0.25 63 | } 64 | @MODULE[ProceduralShapeBezierCone] 65 | { 66 | @length = 0.3 67 | @topDiameter = 0.162 68 | @bottomDiameter = 0.625 69 | } 70 | @MODULE[ProceduralShapePolygon] 71 | { 72 | @length = 1.0 73 | @diameter = 1.25 74 | } 75 | @MODULE[TankContentSwitcher] 76 | { 77 | !TANK_TYPE_OPTION,* {} 78 | %TANK_TYPE_OPTION[XenonGas] 79 | { 80 | 81 | dryDensity = 0.5801 // PB-X150 (modelled as a simple cylinder, not with the detail) 82 | %RESOURCE[XenonGas] { unitsPerT = 14000 } 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/Tanks/4SRB.cfg: -------------------------------------------------------------------------------- 1 | PART 2 | { 3 | // --- general parameters --- 4 | name = proceduralTankSRB 5 | module = Part 6 | author = AncientGammoner, NK, Tiberion, NathanKell, Swamp Ig 7 | 8 | // --- asset parameters --- 9 | MODEL 10 | { 11 | model = ProceduralParts/Parts/cylinderTank 12 | scale = 1,1,1 13 | } 14 | // The model is positioned so it looks right in the icon for the VAB 15 | // If you alter the default params, then change the position 16 | MODEL 17 | { 18 | model = ProceduralParts/Parts/SRBBell 19 | position = 0.0, -1.25, 0.0 20 | scale = 1,1,1 21 | } 22 | // If you want to make another SRB bell, you'll need to have a good look at 23 | // the structure of these ones and keep it the same. You can add an extra 24 | // SRB_BELL node to the ProceduralSRB module below. 25 | MODEL 26 | { 27 | model = ProceduralParts/Parts/HighRatio 28 | position = 0.0, -1.25, 0.0 29 | scale = 1,1,1 30 | } 31 | MODEL 32 | { 33 | model = ProceduralParts/Parts/LowRatio 34 | position = 0.0, -1.25, 0.0 35 | scale = 1,1,1 36 | } 37 | scale = 1 38 | rescaleFactor = 1 39 | 40 | // --- node definitions --- 41 | node_stack_top = 0.0, 0.5, 0.0, 0.0, 1.0, 0.0, 1 42 | node_stack_bottom = 0.0, -0.5, 0.0, 0.0, -1.0, 0.0, 1 43 | node_attach = 0.5, 0.0, 0.0, 1.0, 0.0, 0.0, 1 44 | 45 | fx_exhaustFlame_yellow = 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, running 46 | fx_exhaustSparks_yellow = 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, running 47 | // fx_exhaustLight_yellow = 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, running 48 | fx_smokeTrail_medium = -5.0, 0.0, 0.0, 0.0, 1.0, 0.0, running 49 | 50 | sound_vent_medium = engage 51 | sound_rocket_hard = running 52 | sound_vent_soft = disengage 53 | sound_explosion_low = flameout 54 | 55 | // --- editor parameters --- 56 | cost = 260 // 4000 57 | category = Propulsion 58 | TechRequired = start 59 | entryCost = 15000 60 | subcategory = 0 61 | title = Procedural SRB 62 | manufacturer = Kerbchem Industries 63 | description = Made from viscoelastic nanopolymers (which were discovered by accident... growing in the back of the office mini-fridge) this solid rocket can be stretched to accommodate fuel loads of a range of sizes and shapes. Hardens to a rigid structure before launch! 64 | 65 | // attachment rules: stack, srfAttach, allowStack, allowSrfAttach, allowCollision 66 | attachRules = 1,1,1,1,0 67 | 68 | // --- standard part parameters --- 69 | mass = 1 70 | dragModelType = default 71 | maximum_drag = 0.3 72 | minimum_drag = 0.3 73 | angularDrag = 2 74 | crashTolerance = 7 75 | breakingForce = 200 76 | breakingTorque = 200 77 | maxTemp = 3600 78 | bulkheadProfiles = size1, srf 79 | 80 | stagingIcon = SOLID_BOOSTER 81 | 82 | RESOURCE 83 | { 84 | name = SolidFuel 85 | amount = 427.1 86 | maxAmount = 427.1 87 | } 88 | 89 | MODULE 90 | { 91 | name = ProceduralPart 92 | textureSet = SegmentedSRB 93 | shapeName = Cylinder 94 | 95 | // Lengths for the stock tanks are approximate as one needs to account for the bell. 96 | // RT-5 - 1.25 x 1.2 m = 1.45 kL 97 | diameterMin = 1.0 98 | diameterMax = 1.75 99 | lengthMin = 1.0 100 | lengthMax = 1.25 101 | volumeMin = 1.0 102 | volumeMax = 2.0 103 | updateDragCubesInEditor:NEEDS[FerramAerospaceResearch] = true 104 | 105 | UPGRADES 106 | { 107 | UPGRADE 108 | { 109 | // RT-10 - 1.25 x 2.4 m = 2.95 kL 110 | name__ = ProceduralPartsSRB3m 111 | lengthMax = 3.0 112 | volumeMax = 4.0 113 | } 114 | UPGRADE 115 | { 116 | // BACC - 1.25 x 7.1 m = 8.71 kL 117 | // Sepatron - 0.15 x 0.5 = 0.009 kl 118 | name__ = ProceduralPartsSRB10kL 119 | lengthMin = 0.125 120 | lengthMax = 10.0 121 | volumeMin = 0.001 122 | volumeMax = 10.0 123 | } 124 | UPGRADE 125 | { 126 | name__ = ProceduralPartsSRBDiam3m 127 | diameterMax = 3.0 128 | volumeMax = 15.0 129 | } 130 | UPGRADE 131 | { 132 | name__ = ProceduralPartsSRB40kL 133 | volumeMax = 40.0 134 | } 135 | UPGRADE 136 | { 137 | name__ = ProceduralPartsSRB50kL 138 | lengthMax = 15.0 139 | volumeMax = 50.0 140 | } 141 | UPGRADE 142 | { 143 | name__ = ProceduralPartsSRBUnlimited 144 | diameterMin = 0.01 145 | diameterMax = Infinity 146 | lengthMin = 0.01 147 | lengthMax = Infinity 148 | volumeMin = 0.01 149 | volumeMax = Infinity 150 | } 151 | } 152 | } 153 | // Don't change the default length without also altering the default position above. 154 | MODULE 155 | { 156 | name = ProceduralShapeCylinder 157 | displayName = Cylinder 158 | techRequired = start 159 | 160 | length = 2.5 161 | diameter = 1.25 162 | } 163 | MODULE 164 | { 165 | name = ProceduralShapeCone 166 | displayName = Cone 167 | techRequired = generalConstruction 168 | 169 | // We need the bottom mode to be limit min so that it doesn't 170 | // get to small to allow the bell to be attached nicely 171 | coneBottomMode = LimitMin 172 | 173 | length = 2.5 174 | topDiameter = 0.625 175 | bottomDiameter = 1.25 176 | } 177 | MODULE 178 | { 179 | name = ProceduralShapePill 180 | displayName = Fillet Cylinder 181 | techRequired = advConstruction 182 | 183 | length = 2.5 184 | diameter = 1.25 185 | fillet = 0.25 186 | } 187 | MODULE 188 | { 189 | name = ProceduralShapeBezierCone 190 | displayName = Smooth Cone 191 | techRequired = advConstruction 192 | 193 | // We need the bottom mode to be limit min so that it doesn't 194 | // get to small to allow the bell to be attached nicely 195 | coneBottomMode = LimitMin 196 | 197 | selectedShape = Round1 198 | 199 | length = 2.5 200 | topDiameter = 0.625 201 | bottomDiameter = 1.25 202 | } 203 | MODULE 204 | { 205 | name = TankContentSwitcher 206 | useVolume = true 207 | 208 | TANK_TYPE_OPTION 209 | { 210 | name = SolidFuel 211 | dryDensity = 0.174 212 | // Again no real consistency in stock KSP. Have gone with a bit lower than RT-10 dry/wet 213 | RESOURCE 214 | { 215 | name = SolidFuel 216 | unitsPerT = 800 217 | } 218 | } 219 | } 220 | 221 | MODULE 222 | { 223 | name = ModuleEngines 224 | thrustVectorTransformName = thrustTransform 225 | throttleLocked = True 226 | exhaustDamage = True 227 | ignitionThreshold = 0.1 228 | minThrust = 0 229 | maxThrust = 52 230 | heatProduction = 157 231 | useEngineResponseTime = True 232 | engineAccelerationSpeed = 10.0 233 | allowShutdown = False 234 | fxOffset = 0, 0, 0 235 | PROPELLANT 236 | { 237 | name = SolidFuel 238 | ratio = 1.0 239 | DrawGauge = True 240 | } 241 | atmosphereCurve 242 | { 243 | key = 0 10 244 | key = 1 20 245 | } 246 | } 247 | MODULE 248 | { 249 | name = ProceduralSRB 250 | 251 | srbBellName = SRBBell 252 | thrustVectorTransformName = thrustTransform 253 | bottomAttachNodeName = bottom 254 | 255 | selectedBellName = Surface 256 | 257 | // Thrust for the SRB on part place (default thrust). 258 | thrust = 500 259 | 260 | // The thrust that an SRB with a 1m base could put out. 261 | // Make this higher to allow for more powerful SRBs at the same diameter. 262 | // If you don't want tiny bells, use a smaller number. If you want a higher thrust limit, use a bigger number. 263 | // Note that this goes up on the square of diameter, so a 2m diameter part will give you 2^2 * thrust1m = 2000kN max thrust. 264 | // Does not affect ships in flight (as in their bells will not rescale) 265 | thrust1m = 500 266 | 267 | // To replicate Advanced Booster SRB 268 | // See thread here: http://forum.kerbalspaceprogram.com/threads/70676-WIP-Procedural-Parts-The-next-phase-of-Stretchy-SRBs?p=1116650&viewfull=1#post1116650 269 | // Changing this will not affect ships in flight (but will affect anything loaded into the VAB) 270 | //thrust1m = 1500 271 | 272 | // Heat Produced = heatPerThrust * sqrt(thrust) / (1+total mass). 273 | // All stock parts are around 50 274 | // I realize this model is not very physical, but the way heat is handled in the game is pretty daft 275 | // Note anything with heat production much above 700 tends to explode. 276 | // Does not affect ships in flight (as in their heat production will not rescale) 277 | heatPerThrust = 40 278 | 279 | SRB_BELL 280 | { 281 | name = Surface 282 | 283 | // ISP in vacuum and kerbin surface 284 | atmosphereCurve 285 | { 286 | key = 0 250 287 | key = 1 230 288 | } 289 | // Degrees of gimble 290 | gimbalRange = 5.25 291 | 292 | // Config intrinsic to the model, don't change unless you know what you're doing 293 | modelName = LowRatioBell 294 | // Diameter of the bell's choke (in the unscaled model) 295 | bellChokeDiameter = 0.55 296 | // Ratio between the bell choke and the bottom of the SRB 297 | // Should never be > 1.0. Ideal depends on the model somewhat, but big numbers look funny. 298 | chokeEndRatio = 0.55 299 | } 300 | SRB_BELL 301 | { 302 | name = Vacuum 303 | 304 | atmosphereCurve 305 | { 306 | key = 0 264 307 | key = 1 215 308 | } 309 | gimbalRange = 5.1 310 | 311 | modelName = HighRatioBell 312 | bellChokeDiameter = 0.32 313 | chokeEndRatio = 0.32 314 | } 315 | } 316 | MODULE 317 | { 318 | name = ModuleGimbal 319 | gimbalTransformName = thrustTransform 320 | gimbalResponseSpeed = 10 321 | useGimbalResponseSpeed = true 322 | } 323 | } 324 | 325 | @PART[proceduralTankSRB]:FIRST:NEEDS[RealFuels] 326 | { 327 | @mass = 3.737 328 | 329 | @MODULE[ProceduralSRB] 330 | { 331 | %costMultiplier = 0.5 332 | %burnTimeME = 15 333 | !thrust = DEL 334 | @SRB_BELL[Surface] 335 | { 336 | realFuelsEngineType = S 337 | @gimbalRange = 0.25 338 | } 339 | @SRB_BELL[Vacuum] 340 | { 341 | realFuelsEngineType = S+ 342 | @gimbalRange = 0.1 343 | } 344 | @SRB_BELL,* { !atmosphereCurve {} } 345 | } 346 | @MODULE[ModuleGimbal] { %gimbalRange = 0.25 } 347 | 348 | !MODULE[TankContentSwitcher] {} 349 | %MODULE[ModuleFuelTanks] 350 | { 351 | volume = 1060 352 | type = Solid 353 | typeAvailable = Solid 354 | } 355 | %MODULE[ModuleEngineConfigs] 356 | { 357 | type = ModuleEngines 358 | techLevel = 0 359 | origTechLevel = 0 360 | engineType = S 361 | gimbalTransform = SRBBell 362 | configuration = Normal 363 | modded = false 364 | %CONFIG[Normal] 365 | { 366 | heatProduction = 157 367 | 368 | PROPELLANT 369 | { 370 | name = SolidFuel 371 | ratio = 1.0 372 | DrawGauge = True 373 | } 374 | IspSL = 1 375 | IspV = 1 376 | } 377 | +CONFIG[Normal] 378 | { 379 | @name = PSPC 380 | @PROPELLANT { @name = PSPC } 381 | } 382 | +CONFIG[Normal] 383 | { 384 | @name = HTPB 385 | @PROPELLANT { @name = HTPB } 386 | } 387 | +CONFIG[Normal] 388 | { 389 | @name = PBAN 390 | @PROPELLANT { @name = PBAN } 391 | } 392 | +CONFIG[Normal] 393 | { 394 | @name = NGNC 395 | @PROPELLANT { @name = NGNC } 396 | } 397 | +CONFIG[Normal] 398 | { 399 | @name = HNIW 400 | @PROPELLANT { @name = HNIW } 401 | } 402 | } 403 | } 404 | -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/Tanks/TankOre.cfg: -------------------------------------------------------------------------------- 1 | +PART[proceduralTankLiquid]:FIRST 2 | { 3 | @name = proceduralTankOre 4 | @author = Ckfinite, AncientGammoner, NathanKell, Swamp Ig, OtherBarry 5 | @TechRequired = advScienceTech 6 | 7 | @title = Procedural Ore Tank 8 | @cost = 4 9 | @crashTolerance = 12 10 | @breakingForce = 500 11 | @breakingTorque = 500 12 | 13 | %RESOURCE[Ore] 14 | { 15 | amount = 171.4 16 | maxAmount = 171.4 17 | } 18 | 19 | @MODULE[ProceduralPart] 20 | { 21 | %textureSet = GreySide 22 | %costPerkL=424 23 | 24 | @diameterMin = 0.1 25 | @diameterMax = 1.5 26 | @lengthMin = 0.1 27 | @lengthMax = 1.75 28 | @volumeMin = 0.1 29 | @volumeMax = 2.5 30 | 31 | @UPGRADES 32 | { 33 | !UPGRADE,* {} 34 | UPGRADE 35 | { 36 | // FL-T200 - 1.25 x 1.1105 m = 1.363 kL 37 | name__ = ProceduralPartsTankOre1 38 | diameterMax = 3.0 39 | volumeMax = 15.0 40 | lengthMax = 5.0 41 | } 42 | UPGRADE 43 | { 44 | name__ = ProceduralPartsTankUnlimited 45 | diameterMin = 0.01 46 | diameterMax = Infinity 47 | lengthMin = 0.01 48 | lengthMax = Infinity 49 | volumeMin = 0 50 | volumeMax = Infinity 51 | } 52 | } 53 | } 54 | @MODULE[ProceduralShapeCylinder] 55 | { 56 | @length = 1.0 57 | @diameter = 1.25 58 | } 59 | @MODULE[ProceduralShapeCone] 60 | { 61 | @length = 1.0 62 | @topDiameter = 0.625 63 | @bottomDiameter = 1.25 64 | } 65 | @MODULE[ProceduralShapePill] 66 | { 67 | @length = 1.0 68 | @diameter = 1.25 69 | @fillet = 0.25 70 | } 71 | @MODULE[ProceduralShapeBezierCone] 72 | { 73 | @length = 1.0 74 | @topDiameter = 0.625 75 | @bottomDiameter = 1.25 76 | } 77 | @MODULE[ProceduralShapePolygon] 78 | { 79 | @length = 1.0 80 | @diameter = 1.25 81 | } 82 | @MODULE[TankContentSwitcher] 83 | { 84 | !TANK_TYPE_OPTION,* {} 85 | %TANK_TYPE_OPTION[Ore] 86 | { 87 | dryDensity = 0.17 88 | %RESOURCE[Ore] { unitsPerKL = 139.664 } 89 | } 90 | } 91 | 92 | %MODULE[ModuleFuelJettison] {} 93 | } 94 | -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/TechTree/Upgrades.cfg: -------------------------------------------------------------------------------- 1 | PARTUPGRADE 2 | { 3 | name = ProceduralPartsTank1500L 4 | partIcon = proceduralTankLiquid 5 | techRequired = generalRocketry 6 | title = Procedural Tank (1.5 kL) 7 | description = Procedural Tank max volume is 1.5 kL 8 | } 9 | 10 | PARTUPGRADE 11 | { 12 | name = ProceduralPartsTank2500L 13 | partIcon = proceduralTankLiquid 14 | techRequired = advRocketry 15 | title = Procedural Tank (2.5 kL) 16 | description = Procedural Tank max volume is 2.5 kL 17 | } 18 | 19 | PARTUPGRADE 20 | { 21 | name = ProceduralPartsTankAviation 22 | partIcon = proceduralTankLiquid 23 | techRequired = aviation 24 | title = Procedural Tank (Aviation) 25 | description = Procedural Tank min diameter is 0.625m (Mk0) 26 | } 27 | 28 | PARTUPGRADE 29 | { 30 | name = ProceduralPartsTank20000L 31 | partIcon = proceduralTankLiquid 32 | techRequired = fuelSystems 33 | title = Procedural Tank (20 kL) 34 | description = Procedural Tank max volume is 20 kL 35 | } 36 | 37 | PARTUPGRADE 38 | { 39 | name = ProceduralPartsTank37000L 40 | partIcon = proceduralTankLiquid 41 | techRequired = advFuelSystems 42 | title = Procedural Tank (37 kL) 43 | description = Procedural Tank max volume is 37 kL 44 | } 45 | 46 | PARTUPGRADE 47 | { 48 | name = ProceduralPartsTank45000L 49 | partIcon = proceduralTankLiquid 50 | techRequired = largeVolumeContainment 51 | title = Procedural Tank (45 kL) 52 | description = Procedural Tank max volume is 45 kL 53 | } 54 | 55 | PARTUPGRADE 56 | { 57 | name = ProceduralPartsTank85000L 58 | partIcon = proceduralTankLiquid 59 | techRequired = highPerformanceFuelSystems 60 | title = Procedural Tank (85 kL) 61 | description = Procedural Tank max volume is 85 kL 62 | } 63 | 64 | PARTUPGRADE 65 | { 66 | name = ProceduralPartsTankMiniaturization 67 | partIcon = proceduralTankLiquid 68 | techRequired = propulsionSystems 69 | title = Procedural Tank (Miniaturization) 70 | description = Procedural Tank min dimensions are reduced 71 | } 72 | 73 | PARTUPGRADE 74 | { 75 | name = ProceduralPartsTankUnlimited 76 | partIcon = proceduralTankLiquid 77 | techRequired = metaMaterials 78 | title = Procedural Tank (Unlimited) 79 | description = Procedural Tank size is unrestricted 80 | } 81 | 82 | PARTUPGRADE 83 | { 84 | name = ProceduralPartsTankOre1 85 | partIcon = proceduralTankOre 86 | techRequired = experimentalScience 87 | title = Procedural Ore Tank (Expanded) 88 | description = Procedural Ore Tank dimensions are increased 89 | } 90 | 91 | PARTUPGRADE 92 | { 93 | name = ProceduralPartsNoseCone1.5M 94 | partIcon = proceduralNoseCone 95 | techRequired = aerodynamicSystems 96 | title = Procedural NoseCone (1.5m) 97 | description = Procedural NoseCone max length 1.5m 98 | } 99 | 100 | PARTUPGRADE 101 | { 102 | name = ProceduralPartsNoseCone2.5M 103 | partIcon = proceduralNoseCone 104 | techRequired = advConstruction 105 | title = Procedural NoseCone (2.5m) 106 | description = Procedural NoseCone max diameter 2.5m 107 | } 108 | 109 | PARTUPGRADE 110 | { 111 | name = ProceduralPartsNoseConeUnlimited 112 | partIcon = proceduralNoseCone 113 | techRequired = aerospaceTech 114 | title = Procedural NoseCone (Unlimited) 115 | description = Procedural NoseCone max diameter unrestricted 116 | } 117 | 118 | PARTUPGRADE 119 | { 120 | name = ProceduralPartsBattery300 121 | partIcon = proceduralBattery 122 | techRequired = electrics 123 | title = Procedural Battery (300 EC) 124 | description = Procedural Batteries can contain 300 EC 125 | } 126 | 127 | PARTUPGRADE 128 | { 129 | name = ProceduralPartsBattery600 130 | partIcon = proceduralBattery 131 | techRequired = advElectrics 132 | title = Procedural Battery (600 EC) 133 | description = Procedural Batteries can contain 600 EC 134 | } 135 | 136 | PARTUPGRADE 137 | { 138 | name = ProceduralPartsBattery2400 139 | partIcon = proceduralBattery 140 | techRequired = largeElectrics 141 | title = Procedural Battery (2400 EC) 142 | description = Procedural Batteries can contain 2400 EC 143 | } 144 | 145 | PARTUPGRADE 146 | { 147 | name = ProceduralPartsBattery4800 148 | partIcon = proceduralBattery 149 | techRequired = specializedElectrics 150 | title = Procedural Battery (4800 EC) 151 | description = Procedural Batteries can contain 4800 EC 152 | } 153 | 154 | PARTUPGRADE 155 | { 156 | name = ProceduralPartsBatteryUnlimited 157 | partIcon = proceduralBattery 158 | techRequired = experimentalElectrics 159 | title = Procedural Battery (Unlimited EC) 160 | description = Procedural Batteries can contain any amount of EC 161 | } 162 | 163 | PARTUPGRADE 164 | { 165 | name = ProceduralPartsDecoupler3m 166 | partIcon = proceduralStackDecoupler 167 | techRequired = generalConstruction 168 | title = Procedural Decoupler (3m) 169 | description = Procedural Decoupler maximum diameter is 3m 170 | } 171 | 172 | PARTUPGRADE 173 | { 174 | name = ProceduralPartsDecoupler4.5m 175 | partIcon = proceduralStackDecoupler 176 | techRequired = specializedConstruction 177 | title = Procedural Decoupler (4.5m) 178 | description = Procedural Decoupler maximum diameter is 4.5m 179 | } 180 | 181 | PARTUPGRADE 182 | { 183 | name = ProceduralPartsDecoupler0.125m 184 | partIcon = proceduralStackDecoupler 185 | techRequired = precisionEngineering 186 | title = Procedural Decoupler (0.125m) 187 | description = Procedural Decoupler minimum diameter is 0.125m 188 | } 189 | 190 | PARTUPGRADE 191 | { 192 | name = ProceduralPartsDecouplerUnlimited 193 | partIcon = proceduralStackDecoupler 194 | techRequired = metaMaterials 195 | title = Procedural Decoupler (Unlimited) 196 | description = Procedural Decoupler diameter is unrestricted 197 | } 198 | 199 | PARTUPGRADE 200 | { 201 | name = ProceduralPartsHeatshield3m 202 | partIcon = proceduralHeatshield 203 | techRequired = landing 204 | title = Procedural Heatshield (3m) 205 | description = Procedural Heatshield maximum diameter is 3m 206 | } 207 | 208 | PARTUPGRADE 209 | { 210 | name = ProceduralPartsHeatshield5m 211 | partIcon = proceduralHeatshield 212 | techRequired = advLanding 213 | title = Procedural Heatshield (5m) 214 | description = Procedural Heatshield maximum diameter is 5m 215 | } 216 | 217 | PARTUPGRADE 218 | { 219 | name = ProceduralPartsHeatshield0.125m 220 | partIcon = proceduralHeatshield 221 | techRequired = precisionEngineering 222 | title = Procedural Heatshield (0.125m) 223 | description = Procedural Heatshield minimum diameter is 0.125m 224 | } 225 | 226 | PARTUPGRADE 227 | { 228 | name = ProceduralPartsHeatshieldUnlimited 229 | partIcon = proceduralHeatshield 230 | techRequired = metaMaterials 231 | title = Procedural Heatshield (Unlimited) 232 | description = Procedural Heatshield diameter is unrestricted 233 | } 234 | 235 | PARTUPGRADE 236 | { 237 | name = ProceduralPartsSRB3m 238 | partIcon = proceduralTankSRB 239 | techRequired = basicRocketry 240 | title = Procedural SRB (3m) 241 | description = Procedural SRB maximum length is 3m 242 | } 243 | 244 | PARTUPGRADE 245 | { 246 | name = ProceduralPartsSRB10kL 247 | partIcon = proceduralTankSRB 248 | techRequired = generalRocketry 249 | title = Procedural SRB (10 kL) 250 | description = Procedural SRB dimensions expanded, maximum volume is 10kL 251 | } 252 | 253 | PARTUPGRADE 254 | { 255 | name = ProceduralPartsSRBDiam3m 256 | partIcon = proceduralTankSRB 257 | techRequired = heavyRocketry 258 | title = Procedural SRB (3m diameter) 259 | description = Procedural SRB maximum diameter is 3m 260 | } 261 | 262 | PARTUPGRADE 263 | { 264 | name = ProceduralPartsSRB40kL 265 | partIcon = proceduralTankSRB 266 | techRequired = heavierRocketry 267 | title = Procedural SRB (40 kL) 268 | description = Procedural SRB maximum volume is 40kL 269 | } 270 | 271 | PARTUPGRADE 272 | { 273 | name = ProceduralPartsSRB50kL 274 | partIcon = proceduralTankSRB 275 | techRequired = veryHeavyRocketry 276 | title = Procedural SRB (50 kL) 277 | description = Procedural SRB dimensions expanded, maximum volume is 50kL 278 | } 279 | 280 | PARTUPGRADE 281 | { 282 | name = ProceduralPartsSRBUnlimited 283 | partIcon = proceduralTankSRB 284 | techRequired = metaMaterials 285 | title = Procedural SRB (Unlimited) 286 | description = Procedural SRB dimensions are unrestricted 287 | } 288 | -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/ZOtherMods/TankExtraplanetary.cfg: -------------------------------------------------------------------------------- 1 | +PART[proceduralTankLiquid]:FIRST:NEEDS[Launchpad] 2 | { 3 | // --- general parameters --- 4 | @name = proceduralTankExtraplanetary 5 | @author = AncientGammoner, NathanKell, Swamp Ig, OtherBarry 6 | 7 | @TechRequired = advRocketry 8 | @category = Utility 9 | @title = Procedural Launchpad Tank 10 | 11 | !MODULE[ProceduralPart] {} 12 | MODULE,0 13 | { 14 | name = ProceduralPart 15 | costPerkL=424 16 | diameterMin = 0.1 17 | diameterMax = 3.0 18 | lengthMin = 0.1 19 | lengthMax = 5.0 20 | volumeMin = 0.1 21 | volumeMax = 15.0 22 | updateDragCubesInEditor:NEEDS[FerramAerospaceResearch] = true 23 | 24 | UPGRADES 25 | { 26 | UPGRADE 27 | { 28 | name__ = ProceduralPartsTankUnlimited 29 | diameterMin = 0.01 30 | diameterMax = Infinity 31 | lengthMin = 0.01 32 | lengthMax = Infinity 33 | volumeMin = 0 34 | volumeMax = Infinity 35 | } 36 | } 37 | } 38 | 39 | @MODULE[TankContentSwitcher] 40 | { 41 | !TANK_TYPE_OPTION,* {} 42 | %TANK_TYPE_OPTION[Ore] 43 | { 44 | dryDensity = 0.17 45 | %RESOURCE[Ore] { unitsPerKL = 114 } 46 | } 47 | 48 | %TANK_TYPE_OPTION[Metal] 49 | { 50 | dryDensity = 0.17 51 | %RESOURCE[Metal] { unitsPerKL = 114 } 52 | } 53 | 54 | TANK_TYPE_OPTION 55 | { 56 | name = Rocket Parts 57 | dryDensity = 0.17 58 | %RESOURCE[RocketParts] { unitsPerKL = 114 } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/ZOtherMods/TankKethane.cfg: -------------------------------------------------------------------------------- 1 | PARTUPGRADE:NEEDS[Kethane] 2 | { 3 | name = ProceduralPartsKethaneTank 4 | partIcon = proceduralTankKethane 5 | techRequired = heavyRocketry 6 | title = Procedural Kethane Tank (Expanded) 7 | description = Procedural Kethane Tank dimensions are increased 8 | } 9 | 10 | +PART[proceduralTankLiquid]:FIRST:NEEDS[Kethane] 11 | { 12 | @name = proceduralTankKethane 13 | @author = AncientGammoner, NathanKell, Swamp Ig, OtherBarry 14 | 15 | @TechRequired = start 16 | @category = Propulsion 17 | @title = Procedural Kethane Tank 18 | 19 | %MODULE[KethaneWetMassIndicator] {} 20 | @MODULE[ProceduralPart] 21 | { 22 | @textureSet = SoyuzGreen 23 | @diameterMin = 1.0 24 | @diameterMax = 1.5 25 | @lengthMin = 1.0 26 | @lengthMax = 2.0 27 | @volumeMin = 1.5 28 | @volumeMax = 3.0 29 | 30 | !UPGRADES {} 31 | UPGRADES 32 | { 33 | UPGRADE 34 | { 35 | name__ = ProceduralPartsKethaneTank 36 | diameterMax = 3.0 37 | volumeMax = 35.0 38 | lengthMax = 7.5 39 | } 40 | UPGRADE 41 | { 42 | name__ = ProceduralPartsTankUnlimited 43 | diameterMin = 0.01 44 | diameterMax = Infinity 45 | lengthMin = 0.01 46 | lengthMax = Infinity 47 | volumeMin = 0 48 | volumeMax = Infinity 49 | } 50 | } 51 | } 52 | 53 | @MODULE[TankContentSwitcher] 54 | { 55 | !TANK_TYPE_OPTION,* {} 56 | %TANK_TYPE_OPTION[LifeSupport] 57 | { 58 | dryDensity = 0.12 59 | %RESOURCE[Kethane] 60 | { 61 | unitsPerT = 4000 62 | forceEmpty = true 63 | } 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/ZOtherMods/TankLifeSupport.cfg: -------------------------------------------------------------------------------- 1 | PARTUPGRADE:NEEDS[TacLifeSupport] 2 | { 3 | name = ProceduralPartsTACLSTank 4 | partIcon = proceduralTankTAC 5 | techRequired = heavyRocketry 6 | title = Procedural Life Support Tank (Expanded) 7 | description = Procedural Life Support Tank dimensions are increased 8 | } 9 | 10 | +PART[proceduralTankLiquid]:FIRST:NEEDS[TacLifeSupport] 11 | { 12 | @name = proceduralTankTAC 13 | @author = AncientGammoner, NathanKell, Swamp Ig, OtherBarry 14 | 15 | @TechRequired = survivability 16 | @category = Utility 17 | @title = Procedural Life Support Tank 18 | 19 | %MODULE[LifeSupportModule] {} 20 | @MODULE[ProceduralPart] 21 | { 22 | @textureSet = PlainWhite 23 | %costPerkL=980 24 | @diameterMin = 0.1 25 | @diameterMax = 1.5 26 | @lengthMin = 0.1 27 | @lengthMax = 0.5 28 | @volumeMin = 0.1 29 | @volumeMax = 1.0 30 | 31 | !UPGRADES {} 32 | UPGRADES 33 | { 34 | UPGRADE 35 | { 36 | name__ = ProceduralPartsTACLSTank 37 | diameterMax = 3.0 38 | volumeMax = 3.0 39 | lengthMax = 1.0 40 | } 41 | UPGRADE 42 | { 43 | name__ = ProceduralPartsTankUnlimited 44 | diameterMin = 0.01 45 | diameterMax = Infinity 46 | lengthMin = 0.01 47 | lengthMax = Infinity 48 | volumeMin = 0 49 | volumeMax = Infinity 50 | } 51 | } 52 | } 53 | 54 | @MODULE[TankContentSwitcher] 55 | { 56 | !TANK_TYPE_OPTION,* {} 57 | %TANK_TYPE_OPTION[LifeSupport] 58 | { 59 | dryDensity = 0.65 60 | %RESOURCE[Food] { unitsPerKL = 369 } 61 | %RESOURCE[Water] { unitsPerKL = 244 } 62 | %RESOURCE[Oxygen] { unitsPerKL = 37483 } 63 | } 64 | 65 | %TANK_TYPE_OPTION[LifeSupportWaste] 66 | { 67 | dryDensity = 0.65 68 | %RESOURCE[Waste] { unitsPerKL = 63 } 69 | %RESOURCE[WasteWater] { unitsPerKL = 588 } 70 | %RESOURCE[CarbonDioxide] { unitsPerKL = 61437 } 71 | @RESOURCE,* { forceEmpty = true } 72 | } 73 | 74 | %TANK_TYPE_OPTION[Food] 75 | { 76 | dryDensity = 0.65 77 | %RESOURCE[Food] { unitsPerKL = 784 } 78 | } 79 | 80 | %TANK_TYPE_OPTION[Waste] 81 | { 82 | dryDensity = 0.65 83 | %RESOURCE[Waste] 84 | { 85 | unitsPerKL = 189 86 | forceEmpty = true 87 | } 88 | } 89 | 90 | %TANK_TYPE_OPTION[Water] 91 | { 92 | dryDensity = 0.65 93 | %RESOURCE[Water] { unitsPerKL = 784 } 94 | } 95 | 96 | %TANK_TYPE_OPTION[WasteWater] 97 | { 98 | dryDensity = 0.65 99 | %RESOURCE[WasteWater] 100 | { 101 | unitsPerKL = 1764 102 | forceEmpty = true 103 | } 104 | } 105 | 106 | %TANK_TYPE_OPTION[Oxygen] 107 | { 108 | dryDensity = 0.65 109 | %RESOURCE[Oxygen] { unitsPerKL = 174411 } 110 | } 111 | 112 | %TANK_TYPE_OPTION[CarbonDioxide] 113 | { 114 | dryDensity = 0.65 115 | %RESOURCE[CarbonDioxide] 116 | { 117 | unitsPerKL = 184311 118 | forceEmpty = true 119 | } 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/ZOtherMods/USI-LS compatibility.cfg: -------------------------------------------------------------------------------- 1 | PARTUPGRADE:NEEDS[USILifeSupport] 2 | { 3 | name = ProceduralPartsUSILSTank 4 | partIcon = proceduralTankUSI-LS 5 | techRequired = heavyRocketry 6 | title = Procedural Life Support Tank (Expanded) 7 | description = Procedural Life Support Tank dimensions are increased 8 | } 9 | 10 | +PART[proceduralTankLiquid]:FIRST:NEEDS[USILifeSupport] 11 | { 12 | // --- general parameters --- 13 | @name = proceduralTankUSI-LS 14 | @author = AncientGammoner, NathanKell, Swamp Ig, OtherBarry, RoverDude, Rafael acevedo 15 | 16 | @TechRequired = survivability 17 | @category = Utility 18 | @title = Procedural Life Support Tank 19 | @tags = cck-lifesupport life support usi mulch supplies fertilizer 20 | 21 | !MODULE[ProceduralPart] {} 22 | MODULE,0 23 | { 24 | name = ProceduralPart 25 | textureSet = Mu 26 | costPerkL=980 27 | diameterMin = 0.1 28 | diameterMax = 1.5 29 | lengthMin = 0.1 30 | lengthMax = 0.5 31 | volumeMin = 0.1 32 | volumeMax = 1.0 33 | updateDragCubesInEditor:NEEDS[FerramAerospaceResearch] = true 34 | 35 | UPGRADES 36 | { 37 | UPGRADE 38 | { 39 | name__ = ProceduralPartsUSILSTank 40 | diameterMax = 3.0 41 | volumeMax = 3.0 42 | lengthMax = 1.0 43 | } 44 | UPGRADE 45 | { 46 | name__ = ProceduralPartsTankUnlimited 47 | diameterMin = 0.01 48 | diameterMax = Infinity 49 | lengthMin = 0.01 50 | lengthMax = Infinity 51 | volumeMin = 0 52 | volumeMax = Infinity 53 | } 54 | } 55 | } 56 | 57 | @MODULE[TankContentSwitcher] 58 | { 59 | !TANK_TYPE_OPTION,* {} 60 | %TANK_TYPE_OPTION[LifeSupport] 61 | { 62 | dryDensity = 0.18 63 | %RESOURCE[Supplies] { unitsPerKL = 849 } 64 | %RESOURCE[Mulch] 65 | { 66 | unitsPerKL = 16.8 67 | forceEmpty = true 68 | } 69 | %RESOURCE[Fertilizer] { unitsPerKL = 16.8 } 70 | } 71 | 72 | %TANK_TYPE_OPTION[Mulch] 73 | { 74 | dryDensity = 0.18 75 | %RESOURCE[Mulch] 76 | { 77 | unitsPerKL = 849 78 | forceEmpty = true 79 | } 80 | } 81 | 82 | %TANK_TYPE_OPTION[Supplies] 83 | { 84 | dryDensity = 0.18 85 | %RESOURCE[Supplies] { unitsPerKL = 849 } 86 | } 87 | 88 | %TANK_TYPE_OPTION[Fertilizer] 89 | { 90 | dryDensity = 0.18 91 | %RESOURCE[Fertilizer] { unitsPerKL = 849 } 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/ablative.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/ablative.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/atlas.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/atlas.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/atlas_NRM.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/atlas_NRM.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/blueside.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/blueside.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/copernicus.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/copernicus.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/copernicus_NRM.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/copernicus_NRM.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/cylinderTank.mu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/cylinderTank.mu -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/ends.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/ends.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/foilthin.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/foilthin.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/foilthin_NRM.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/foilthin_NRM.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/gersides.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/gersides.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/greyside.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/greyside.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/heatshield.mu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/heatshield.mu -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/mu.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/mu.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/orangesides.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/orangesides.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/plainwhite.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/plainwhite.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/sides.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/sides.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/sides_NRM.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/sides_NRM.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/soyuzgreen.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/soyuzgreen.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/srbsides.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/srbsides.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/srbsides_NRM.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/srbsides_NRM.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/stockend.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/stockend.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/stocksides.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/stocksides.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/stocksides_NRM.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/stocksides_NRM.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/stripes1.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/stripes1.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/stripes2.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/stripes2.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/tiles.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/tiles.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/tiles_NRM.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/tiles_NRM.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/ussides.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/ussides.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Parts/whiteside.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Parts/whiteside.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/ProceduralParts.cfg: -------------------------------------------------------------------------------- 1 | ProceduralPartsSettings 2 | { 3 | Shape 4 | { 5 | name = Straight 6 | displayName = Straight 7 | points = 0.3, 0.3, 0.7, 0.7 8 | } 9 | Shape 10 | { 11 | name = Round1 12 | displayName = Round #1 13 | points = 0.4, 0.001, 1, 0.6 14 | } 15 | Shape 16 | { 17 | name = Round2 18 | displayName = Round #2 19 | points = 0.5, 0.001, 0.8, 0.7 20 | } 21 | Shape 22 | { 23 | name = Round3 24 | displayName = Round #3 25 | points = 1, 0, 1, 0.5 26 | } 27 | Shape 28 | { 29 | name = Peaked1 30 | displayName = Peaked #1 31 | points = 0.4, 0.2, 0.8, 0.6 32 | } 33 | Shape 34 | { 35 | name = Peaked2 36 | displayName = Peaked #2 37 | points = 0.3, 0.2, 1, 0.5 38 | } 39 | Shape 40 | { 41 | name = Sharp1 42 | displayName = Sharp #1 43 | points = 0.1, 0.001, 0.7, 0.6667 44 | } 45 | Shape 46 | { 47 | name = Sharp2 48 | displayName = Sharp #2 49 | points = 0.3333, 0.3, 1, 0.9 50 | } 51 | Shape 52 | { 53 | name = Waisted 54 | displayName = Waisted 55 | points = 0, 0.5, 1, 0.5 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /GameData/ProceduralParts/ProceduralParts.version: -------------------------------------------------------------------------------- 1 | { 2 | "NAME": "Procedural Parts", 3 | "URL": "https://raw.githubusercontent.com/KSP-RO/ProceduralParts/master/GameData/ProceduralParts/ProceduralParts.version", 4 | "DOWNLOAD": "https://github.com/KSP-RO/ProceduralParts/releases", 5 | "GITHUB": { 6 | "USERNAME": "KSP-RO", 7 | "REPOSITORY": "ProceduralParts", 8 | "ALLOW_PRE_RELEASE": false 9 | }, 10 | "VERSION": { 11 | "MAJOR": 2, 12 | "MINOR": 7, 13 | "PATCH": 2, 14 | "BUILD": 0 15 | }, 16 | "KSP_VERSION": { 17 | "MAJOR": 1, 18 | "MINOR": 8, 19 | "PATCH": 1 20 | }, 21 | "KSP_VERSION_MIN": { 22 | "MAJOR": 1, 23 | "MINOR": 8, 24 | "PATCH": 1 25 | }, 26 | "KSP_VERSION_MAX": { 27 | "MAJOR": 1, 28 | "MINOR": 12, 29 | "PATCH": 99 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /GameData/ProceduralParts/ProceduralsUnlimited.cfg: -------------------------------------------------------------------------------- 1 | KSP_COLOR_PRESET:NEEDS[TexturesUnlimited] 2 | { 3 | name = white-metallic 4 | title = White Paint (Metallic) 5 | color = 236, 236, 236 6 | specular = 176 7 | metallic = 255 8 | } 9 | 10 | KSP_COLOR_PRESET:NEEDS[TexturesUnlimited] 11 | { 12 | name = black-metallic 13 | title = Black Paint (Metallic) 14 | color = 46, 46, 46 15 | specular = 176 16 | metallic = 255 17 | } 18 | 19 | @PRESET_COLOR_GROUP[Metallics]:NEEDS[TexturesUnlimited] 20 | { 21 | color = white-metallic 22 | color = black-metallic 23 | } 24 | 25 | KSP_TEXTURE_SET:NEEDS[TexturesUnlimited] 26 | { 27 | name = CustomEnds 28 | title = PP-CustomEnds 29 | recolorable = true 30 | MATERIAL 31 | { 32 | shader = TU/Metallic 33 | texture = _MainTex, ProceduralParts/Parts/ends 34 | texture = _BumpMap, ProceduralParts/Textures/Normals/Smooth-NRM 35 | texture = _MetallicGlossMap,ProceduralParts/Textures/Metallic/Smooth-METAL 36 | texture = _MaskTex, ProceduralParts/Textures/Masks/Solid-MASK 37 | keyword = TU_RECOLOR 38 | vector = _DiffuseNorm, 0.5,0.5,0.5 39 | vector = _MetalNorm, 0.5,0.5,0.5 40 | vector = _SmoothnessNorm, 0.5,0.5,0.5 41 | float = _Metal, 0.2 42 | float = _Smoothness, 0.2 43 | mesh = ends 44 | } 45 | COLORS 46 | { 47 | mainColor = stockWhite 48 | secondColor = white 49 | detailColor = white 50 | } 51 | } 52 | 53 | @PART[procedural*]:HAS[@MODULE[ProceduralPart]]:FOR[ProceduralParts]:NEEDS[TexturesUnlimited] 54 | { 55 | MODULE 56 | { 57 | name = SSTURecolorGUI 58 | } 59 | 60 | MODULE 61 | { 62 | name = KSPTextureSwitch 63 | transformName = sides 64 | sectionName = Sides 65 | 66 | currentTextureSet = Metal 67 | 68 | textureSet = Metal 69 | textureSet = Foil-Default 70 | textureSet = Metal-Default 71 | textureSet = Metal-Tricolor 72 | textureSet = Metal-Stripes 73 | textureSet = Metal-Stripes-Long 74 | textureSet = Metal-Stripes-Half 75 | textureSet = Metal-Stripes-Twisted 76 | textureSet = Metal-Checkers 77 | textureSet = Metal-Checkers2 78 | textureSet = Metal-Checkers-Double 79 | textureSet = Metal-Slats 80 | textureSet = Metal-Narrow 81 | 82 | textureSet = Metal-Fancy 83 | textureSet = Metal-Fancy2 84 | textureSet = Metal-Fancy3 85 | textureSet = Metal-Fancy4 86 | textureSet = Metal-Fancy5 87 | textureSet = Metal-Fancy6 88 | textureSet = Metal-Fancy7 89 | textureSet = Metal-Fancy8 90 | textureSet = Metal-Fancy9 91 | 92 | textureSet = Metal-Able 93 | textureSet = Metal-Able-USAF 94 | textureSet = Metal-Agena 95 | textureSet = Metal-BlackArrow 96 | textureSet = Metal-BlackArrow2 97 | textureSet = Metal-Bumper 98 | textureSet = Metal-Corestar 99 | textureSet = Metal-DeltaIV 100 | textureSet = Metal-Europa 101 | textureSet = Metal-Hermes 102 | textureSet = Metal-Juno 103 | textureSet = Metal-Juno-L 104 | textureSet = Metal-LongMarch 105 | textureSet = Metal-LongMarch2 106 | textureSet = Metal-Mu 107 | textureSet = Metal-Redstone 108 | textureSet = Metal-Redstone-L 109 | textureSet = Metal-Redstone-USA 110 | textureSet = Metal-SLV 111 | textureSet = Metal-Skylab 112 | textureSet = Metal-ThorAble 113 | textureSet = Metal-Titan 114 | textureSet = Metal-Titan2 115 | textureSet = Metal-Vanguard 116 | } 117 | 118 | MODULE 119 | { 120 | name = KSPTextureSwitch 121 | transformName = ends 122 | sectionName = Ends 123 | 124 | currentTextureSet = CustomEnds 125 | 126 | textureSet = CustomEnds 127 | textureSet = Metal 128 | textureSet = Foil-Default 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /GameData/ProceduralParts/ProceduralsUnlimitedFoil.cfg: -------------------------------------------------------------------------------- 1 | KSP_TEXTURE_SET:NEEDS[TexturesUnlimited] 2 | { 3 | name = Foil-Default 4 | title = Foil 5 | recolorable = true 6 | MATERIAL 7 | { 8 | shader = TU/Metallic 9 | texture = _MainTex, ProceduralParts/Textures/Mains/Foil-DIFF 10 | texture = _BumpMap, ProceduralParts/Textures/Normals/Foil-NRM 11 | texture = _MetallicGlossMap,ProceduralParts/Textures/Metallic/Smooth-METAL 12 | texture = _MaskTex, ProceduralParts/Textures/Masks/Solid-MASK 13 | keyword = TU_RECOLOR 14 | channelMask = 1 15 | vector = _DiffuseNorm, 0.5,0.5,0.5 16 | vector = _MetalNorm, 0.5,0.5,0.5 17 | vector = _SmoothnessNorm, 0.5,0.5,0.5 18 | mode = create 19 | } 20 | COLORS 21 | { 22 | mainColor = gold 23 | secondColor = gold 24 | detailColor = gold 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /GameData/ProceduralParts/README.md: -------------------------------------------------------------------------------- 1 | ProceduralParts allows you to procedurally generate a number of different parts in a range of sizes and shapes. The parts are fully tweakable with multiple options for customization of the shape, surface texture, and other parameters. 2 | 3 | ## Features 4 | 5 | #### The features include 6 | * Everything accessible by tweaking 7 | * A broad range of shapes including cylinders, truncated cones, filleted cylinders, bezier cones. 8 | * New part shapes are easy to develop and plug in, so cuboid / pill shaped / whatever else you want shaped will be able to be created. 9 | * Most stuff configurable in the config file, including resources and fill ratios, tech levels, available shapes 10 | * Diverse support for career mode - tank shapes, dimensions, and contents all limited by researched tech 11 | * All supplied parts are carefully designed to be as 'stock alike' as possible in their tech level requirements - You can't create a monster tank before you've discovered basic rocketry for example. 12 | * Other mod support - tanks for RealFuels, Kethane, Extraplanetary Launchpads, and TAC. Heat shields for Deadly Reentry. (thanks to OtherBarry) 13 | * Plays nicely with Ferram Aerospace Research 14 | * Multiple textures available for part surfaces. These are fully compatible with StretchySRB textures. 15 | * Deprecation support for StretchySRB - see below for details. 16 | * A Module - TankContentSwitcher that can be applied to existing tanks (with say module manager) and allow their contents to be tweaked. Tweak any tank in the VAB into a Liquid fuel only or oxidizer tank. 17 | 18 | #### Parts available 19 | * **Tanks** Different parts supplied for different 'groups' of fuels (Liquid fuels, SRBs, Monoprop, Xenon). The multiple part approach is to allow for tech limiting of sizes and volumes. 20 | * **SRBs** Tweakable thrust (or burn time for real fuels). Tweak between a choice of two bells that are designed for surface or vacuum, with varying ISPs. 21 | * **Decoupler** Tweakable diameters (with tech defined limits), ejection impulse, and can be in either decoupler or separator mode (again tech dependent). 22 | * **Structural Part** Good for fuselage, adapters, whatever. Half as light as the equivalent tank. 23 | * **Batteries** It's a bit rough and ready, but it works well enough. 24 | * **Nose Cone** Specialized structural part for nose cones. The shape is limited to a smooth cone with a bounded ratio of diameter to length. 25 | * **Heat Shield** Built to the same specs as Deadly Reentry. Will shield any sized object from heat. (requires deadly reentry) 26 | 27 | ## Installation 28 | Place the ProceduralParts folder found inside the zip file into GameData. 29 | 30 | Dependencies: 31 | * ModuleManager 32 | * KSPCommunityFixes 33 | 34 | ## Upgrades 35 | * Make sure you delete any old versions of ProceduralParts. 36 | * There's a handful of deprecated parts as was previously used for real fuels. If you didn't use these parts, then you can safely delete the PartsDeprecated folder in the main install directory. 37 | 38 | ## Known Issues 39 | * Known limitation: Setting the default shapeName in a part cfg to a hollow shape breaks surface attaching for a new part. Placing it and picking it up again fixes the issue. 40 | * An SRB attached to a parent through the nozzle gets incorrect position when changing the nozzle angle. Reattaching the part fixes the issue. 41 | 42 | ## Custom Textures and Texture Packs 43 | Procedural Parts is compatible with all texture packs for StretchySRBs. It's easy to [roll your own texture packs](https://github.com/Swamp-Ig/ProceduralParts/blob/master/Parts/STTextures.cfg) too. 44 | 45 | Here's some texture packs that other people have compiled: 46 | 47 | #### Planeguy868 48 | [Download](http://www.mediafire.com/download/gz8f35398bs7a14/planeguy868.zip). 49 | Installation instructions: download and extract it to KSP's GameData folder. 50 | 51 | ![image](http://i.imgur.com/Zsq4zeYm.png) 52 | ![image](http://i.imgur.com/6uSoyXCm.png) 53 | 54 | #### Ferram4's Saturn and Nova Textures 55 | [Download](http://www.mediafire.com/download/9mi9tjb5akaiaaz/SaturnNovaTexturePack.zip). 56 | Installation instructions in zip. 57 | 58 | ![image](http://i.imgur.com/YZyRRBN.jpg) 59 | 60 | #### blackheart612 61 | [Full thread!](http://forum.kerbalspaceprogram.com/threads/68892) 62 | Install instructions and sample images in link. 63 | 64 | ## Compatibility with StretchyTanks / StretchySRBs 65 | This is essentially a completely new mod and can run alongside either of the previous mods. This is useful if you have pre-existing ships in your save file still using those parts. If you don't have any ships using those parts, then you can delete the old mod. 66 | 67 | There's a module manager patch file present that will hide all the StretchySRB tanks in the VAB so they don't clutter it up. If for whatever reason you want to continue using StretchySRBs, then delete ProceduralParts\ModuleManager\StretchyTanks_Hide.cfg and this won't happen. 68 | 69 | ## Integration with Real Fuels and Modular Fuel Tanks 70 | Integration with Real Fuels and Modular Fuels Tanks is complete. Ensure you have Real Fuels version 6.1 or newer, and Modular Fuel Tanks 5.0.1 or newer. There's one or two bugs still to get through, stay tuned for updates on those two. 71 | 72 | For MFT, the existing tank types are turned into the corresponding MFT type. 73 | 74 | For real fuels, there's an SRB which can be switched between low altitude and high altitude versions, plus a tank which can be switched between the various RF tank types. 75 | 76 | The old real fuels system with multiple parts for different tank types is preserved as a deprecated option (hidden in the VAB). If you don't have any old tanks on ships or craft you can delete the PartsDeprecated from the root of the install. 77 | 78 | ## Integration with other mods 79 | Thanks to OtherBarry, there are now tanks for RealFuels, Kethane, Extraplanetary Launchpads, and TAC. 80 | There's also a procedural heat-shield for Deadly Reentry. 81 | All part's drag models will automatically update if using Ferram Aerospace Research. 82 | The tank types will automatically appear if the mods are installed. They should be 'fair' compared to their unmodded versions. 83 | 84 | ## How to ~~cheat in career mode~~ have lower tech restrictions 85 | The current tech restrictions have been tailored to closely mimic stock, with a bit of room to alter the original specs. Note that **this will not be changed** with the out of the box config. 86 | 87 | If you'd like more generous limits, you can create a MM patch (ie: cut and paste this into a file called mycheats.cfg in your GameData dir) and tweak to your liking: 88 | 89 | ~~~~ 90 | @PART[proceduralTank*] 91 | { 92 | @MODULE[ProceduralPart] 93 | { 94 | @TECHLIMIT,* 95 | { 96 | // Increase the max length for all tech levels by 3* 97 | @lengthMax *= 3 98 | // Corresponding volume increase 99 | @volumeMax *= 3 100 | 101 | // Increase the max diameter by double 102 | @diameterMax *= 2 103 | // Since volume goes up on diameter^2, need to use increase^2 104 | @volumeMax *= 4 105 | } 106 | } 107 | } 108 | ~~~~ 109 | This will affect all procedural tanks and the SRB. The name of the Real Fuels SRB is "proceduralSRBRealFuels" so you'll need to make another similar patch for that one if you want to mess with that too. 110 | 111 | If you'd like to be able to use all the shapes from the early game then use the following MM patch: 112 | ~~~~ 113 | @PART[*] 114 | { 115 | @MODULE[ProceduralShape*] 116 | { 117 | -techRequired = dummy 118 | } 119 | } 120 | ~~~~ 121 | This will affect all parts. 122 | 123 | ## Future plans 124 | * Cuboid parts, with customizable side lengths 125 | * Extruded parts, such as hexagonal and octagonal pieces 126 | * Add optional mounting pod for surface mounts to pod tank. 127 | * Procedural command module, possibly with rescaling / tweakable IVA. 128 | 129 | ## Features That Are Not Planned 130 | * Procedural wings, procedural fairings - there's good mods for these already. 131 | * Procedural engines - May happen one day, but not a priority. 132 | 133 | ## Acknowledgements 134 | #### ProceduralParts has an extended family tree 135 | * StretchyTanks is the original module by the great Ancient Gammoner. 136 | * StretchySRBs was created and updated by NathanKell and e-dog. 137 | * ProceduralParts is a near complete re-write by Swamp Ig. 138 | 139 | #### Also featuring 140 | * Extensive work on config and mod integration by OtherBarry 141 | * Models by Tiberion 142 | * Further textures by Chestburster and Dante80. 143 | * Config code by jsimmonds 144 | -------------------------------------------------------------------------------- /GameData/ProceduralParts/STTextures.cfg: -------------------------------------------------------------------------------- 1 | STRETCHYTANKTEXTURES 2 | { 3 | name = Default 4 | 5 | // DOCS 6 | // If you're adding a new texture, create a new node. 7 | // The name of the node is the name that will be stored in your craft file. 8 | // Inside that node, you need two subnodes: sides and ends 9 | // sides can have the following keys: 10 | // texture = the path to the texture used for the sides 11 | // bump = the bump map, if any (shader will be non-bumped if this is left out) 12 | // uScale = how many times the texture is tiled horizontally around the tank 13 | // vScale = how many times the texture is tiled vertically on the tank sides 14 | // autoScale = if present and true, the uScale and vScale will be multiplied by 15 | // tank radial and vertical stretch factors respectively. Note that the 16 | // scales will round to the nearest (total scale factor / original scale) 17 | // so that textures don't have seams. The default sides texture 18 | // has uScale 4, so it starts tiled 4x horizontally and when stretched will 19 | // be more or less (but always in steps of 0.25) 20 | // autoScaleU = like autoScale, but only for uScale. 21 | // autoScaleV = like autoScale, but only for vScale. 22 | // autoWidthDivide = if present and true, and autoScale or autoScaleV is true, divide height 23 | // scaling by width stretch factor. In other words, a 2x10m SRB and 1x5m SRB 24 | // will have the same vertical scaling. (SegmentedSRB uses this) 25 | // autoHeightSteps = if present, use steps of (this) instead of (1/vScale) for 26 | // vertical tiling of the texture (only use when autoScale or autoScaleV is true) 27 | // ends can have just the texture key (see above) 28 | 29 | Original 30 | { 31 | //by Ancient Gammoner 32 | sides 33 | { 34 | texture = ProceduralParts/Parts/sides 35 | bump = ProceduralParts/Parts/sides_NRM 36 | uScale = 4 37 | vScale = 1 38 | autoScale = true 39 | shininess = 0.1 40 | specular = 0.2, 0.2, 0.2 41 | } 42 | ends 43 | { 44 | texture = ProceduralParts/Parts/ends 45 | } 46 | } 47 | Tiles 48 | { 49 | //by Swamp Ig 50 | sides 51 | { 52 | texture = ProceduralParts/Parts/tiles 53 | bump = ProceduralParts/Parts/tiles_NRM 54 | uScale = 6 55 | vScale = 1.5 56 | autoScale = true 57 | shininess = 0.6 58 | specular = 0.4, 0.4, 0.4 59 | } 60 | ends 61 | { 62 | texture = ProceduralParts/Parts/ends 63 | } 64 | } 65 | Stockalike 66 | { 67 | //by Ancient Gammoner 68 | sides 69 | { 70 | texture = ProceduralParts/Parts/stocksides 71 | bump = ProceduralParts/Parts/stocksides_NRM 72 | uScale = 2 73 | vScale = 1 74 | autoScale = true 75 | } 76 | ends 77 | { 78 | texture = ProceduralParts/Parts/stockend 79 | } 80 | } 81 | German 82 | { 83 | // by NathanKell 84 | sides 85 | { 86 | texture = ProceduralParts/Parts/gersides 87 | uScale = 2 88 | vScale = 1 89 | } 90 | ends 91 | { 92 | texture = ProceduralParts/Parts/ends 93 | } 94 | } 95 | Saturn 96 | { 97 | // by NathanKell 98 | sides 99 | { 100 | texture = ProceduralParts/Parts/ussides 101 | bump = ProceduralParts/Parts/stocksides_NRM 102 | uScale = 2 103 | vScale = 1 104 | } 105 | ends 106 | { 107 | texture = ProceduralParts/Parts/ends 108 | } 109 | } 110 | SegmentedSRB 111 | { 112 | // by e-dog 113 | sides 114 | { 115 | texture = ProceduralParts/Parts/srbsides 116 | bump = ProceduralParts/Parts/srbsides_NRM 117 | uScale = 2 118 | vScale = 1 119 | autoScale = true 120 | autoHeightSteps = 0.5 121 | shininess = 0.5 122 | specular = 1.0, 1.0, 1.0 123 | } 124 | ends 125 | { 126 | texture = ProceduralParts/Parts/ends 127 | } 128 | } 129 | CryogenicOrange 130 | { 131 | // by Chestburster 132 | sides 133 | { 134 | texture = ProceduralParts/Parts/orangesides 135 | uScale = 1.0 136 | vScale = 0.5 137 | autoScale = true 138 | shininess = 0.5 139 | specular = 0.5, 0.4, 0.3 140 | } 141 | ends 142 | { 143 | texture = ProceduralParts/Parts/ends 144 | } 145 | } 146 | RedstoneStripes 147 | { 148 | // by Chestburster 149 | sides 150 | { 151 | texture = ProceduralParts/Parts/stripes1 152 | uScale = 2 153 | vScale = 1 154 | } 155 | ends 156 | { 157 | texture = ProceduralParts/Parts/ends 158 | } 159 | } 160 | TitanStripes 161 | { 162 | // by Chestburster 163 | sides 164 | { 165 | texture = ProceduralParts/Parts/stripes2 166 | uScale = 2 167 | vScale = 1 168 | } 169 | ends 170 | { 171 | texture = ProceduralParts/Parts/ends 172 | } 173 | } 174 | WhiteSide 175 | { 176 | // by Chestburster 177 | sides 178 | { 179 | texture = ProceduralParts/Parts/whiteside 180 | uScale = 2 181 | vScale = 1 182 | autoScale = true 183 | autoHeightSteps = 0.5 184 | shininess = 0.6 185 | specular = 0.4, 0.4, 0.4 186 | } 187 | ends 188 | { 189 | texture = ProceduralParts/Parts/ends 190 | } 191 | } 192 | BlueSide 193 | { 194 | // by Chestburster 195 | sides 196 | { 197 | texture = ProceduralParts/Parts/blueside 198 | uScale = 2 199 | vScale = 2 200 | } 201 | ends 202 | { 203 | texture = ProceduralParts/Parts/ends 204 | } 205 | } 206 | GreySide 207 | { 208 | // by Chestburster 209 | sides 210 | { 211 | texture = ProceduralParts/Parts/greyside 212 | uScale = 2 213 | vScale = 1 214 | autoScale = true 215 | } 216 | ends 217 | { 218 | texture = ProceduralParts/Parts/ends 219 | } 220 | } 221 | Ablative 222 | { 223 | // by e-dog 224 | sides 225 | { 226 | texture = ProceduralParts/Parts/ablative 227 | uScale = 2 228 | vScale = 1 229 | autoScale = true 230 | autoHeightSteps = 1 231 | shininess = 0.2 232 | specular = 0.2, 0.2, 0.2 233 | } 234 | ends 235 | { 236 | texture = ProceduralParts/Parts/stockend 237 | } 238 | } 239 | PlainWhite 240 | { 241 | // by Chestburster 242 | sides 243 | { 244 | texture = ProceduralParts/Parts/plainwhite 245 | uScale = 2 246 | vScale = 1 247 | autoScale = true 248 | shininess = 0.6 249 | specular = 0.4, 0.4, 0.4 250 | } 251 | ends 252 | { 253 | texture = ProceduralParts/Parts/ends 254 | } 255 | } 256 | SoyuzGreen 257 | { 258 | // by Chestburster 259 | sides 260 | { 261 | texture = ProceduralParts/Parts/soyuzgreen 262 | uScale = 2 263 | vScale = 1 264 | autoScale = true 265 | } 266 | ends 267 | { 268 | texture = ProceduralParts/Parts/ends 269 | } 270 | } 271 | Atlas 272 | { 273 | // by Dante80 274 | sides 275 | { 276 | texture = ProceduralParts/Parts/atlas 277 | bump = ProceduralParts/Parts/atlas_NRM 278 | uScale = 1.0 279 | vScale = 0.5 280 | autoScale = true 281 | shininess = 0.05 282 | specular = 0.6, 0.6, 0.6 283 | } 284 | ends 285 | { 286 | texture = ProceduralParts/Parts/ends 287 | } 288 | } 289 | Copernicus 290 | { 291 | // by e-dog 292 | sides 293 | { 294 | texture = ProceduralParts/Parts/copernicus 295 | bump = ProceduralParts/Parts/copernicus_NRM 296 | uScale = 1.0 297 | vScale = 0.5 298 | autoScale = true 299 | shininess = 0.05 300 | specular = 1.0, 0.75, 0.25 301 | } 302 | ends 303 | { 304 | texture = ProceduralParts/Parts/ends 305 | } 306 | } 307 | Mu 308 | { 309 | // by Dante80 310 | sides 311 | { 312 | texture = ProceduralParts/Parts/mu 313 | uScale = 2.0 314 | vScale = 1.0 315 | shininess = 0.6 316 | specular = 0.4, 0.4, 0.4 317 | } 318 | ends 319 | { 320 | texture = ProceduralParts/Parts/ends 321 | } 322 | } 323 | GoldFoil 324 | { 325 | // by e-dog 326 | sides 327 | { 328 | texture = ProceduralParts/Parts/foilthin 329 | bump = ProceduralParts/Parts/foilthin_NRM 330 | uScale = 2.5 331 | vScale = 1.25 332 | autoScale = true 333 | shininess = 0.05 334 | specular = 1.0, 0.75, 0.25 335 | } 336 | ends 337 | { 338 | texture = ProceduralParts/Parts/ends 339 | } 340 | } 341 | } -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Mains/Foil-DIFF.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Mains/Foil-DIFF.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Mains/Metal-DIFF.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Mains/Metal-DIFF.png -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Mains/Stringer-TopBottom-Smooth-DIFF.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Mains/Stringer-TopBottom-Smooth-DIFF.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Able-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Able-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Able-USAF-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Able-USAF-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Agena-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Agena-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/BlackArrow-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/BlackArrow-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/BlackArrow2-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/BlackArrow2-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Bumper-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Bumper-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Checkers-Double-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Checkers-Double-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Checkers-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Checkers-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Checkers2-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Checkers2-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Corestar-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Corestar-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Default-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Default-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/DeltaIV-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/DeltaIV-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Europa-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Europa-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Fancy1-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Fancy1-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Fancy2-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Fancy2-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Fancy3-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Fancy3-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Fancy4-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Fancy4-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Fancy5-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Fancy5-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Fancy6-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Fancy6-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Fancy7-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Fancy7-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Fancy8-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Fancy8-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Fancy9-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Fancy9-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Hermes-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Hermes-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Juno-L-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Juno-L-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Juno-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Juno-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/LongMarch-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/LongMarch-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/LongMarch2-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/LongMarch2-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Mu-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Mu-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Narrow-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Narrow-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Redstone-L-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Redstone-L-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Redstone-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Redstone-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Redstone-USA-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Redstone-USA-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/SLV-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/SLV-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Skylab-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Skylab-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Slats-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Slats-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Solid-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Solid-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Stripes-Half-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Stripes-Half-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Stripes-Long-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Stripes-Long-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Stripes-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Stripes-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Stripes-Twisted-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Stripes-Twisted-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/ThorAble-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/ThorAble-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Titan-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Titan-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Titan2-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Titan2-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Tricolor-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Tricolor-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Masks/Vanguard-MASK.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Masks/Vanguard-MASK.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Metallic/Smooth-METAL.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Metallic/Smooth-METAL.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Normals/Foil-NRM.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Normals/Foil-NRM.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Normals/Smooth-NRM.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Normals/Smooth-NRM.dds -------------------------------------------------------------------------------- /GameData/ProceduralParts/Textures/Normals/Stringer-TopBottom-M-Smooth-NRM.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/GameData/ProceduralParts/Textures/Normals/Stringer-TopBottom-M-Smooth-NRM.dds -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ProceduralParts allows you to procedurally generate a number of different parts in a range of sizes and shapes. The parts are fully tweakable with multiple options for customization of the shape, surface texture, and other parameters. 2 | 3 | ## Features 4 | 5 | #### The features include 6 | * Everything accessible by tweaking 7 | * A broad range of shapes including cylinders, truncated cones, filleted cylinders, bezier cones. 8 | * New part shapes are easy to develop and plug in, so cuboid / pill shaped / whatever else you want shaped will be able to be created. 9 | * Most stuff configurable in the config file, including resources and fill ratios, tech levels, available shapes 10 | * Diverse support for career mode - tank shapes, dimensions, and contents all limited by researched tech 11 | * All supplied parts are carefully designed to be as 'stock alike' as possible in their tech level requirements - You can't create a monster tank before you've discovered basic rocketry for example. 12 | * Other mod support - tanks for RealFuels, Kethane, Extraplanetary Launchpads, and TAC. Heat shields for Deadly Reentry. (thanks to OtherBarry) 13 | * Plays nicely with Ferram Aerospace Research 14 | * Multiple textures available for part surfaces. These are fully compatible with StretchySRB textures. 15 | * Deprecation support for StretchySRB - see below for details. 16 | * A Module - TankContentSwitcher that can be applied to existing tanks (with say module manager) and allow their contents to be tweaked. Tweak any tank in the VAB into a Liquid fuel only or oxidizer tank. 17 | 18 | #### Parts available 19 | * **Tanks** Different parts supplied for different 'groups' of fuels (Liquid fuels, SRBs, Monoprop, Xenon). The multiple part approach is to allow for tech limiting of sizes and volumes. 20 | * **SRBs** Tweakable thrust (or burn time for real fuels). Tweak between a choice of two bells that are designed for surface or vacuum, with varying ISPs. 21 | * **Decoupler** Tweakable diameters (with tech defined limits), ejection impulse, and can be in either decoupler or separator mode (again tech dependent). 22 | * **Structural Part** Good for fuselage, adapters, whatever. Half as light as the equivalent tank. 23 | * **Batteries** It's a bit rough and ready, but it works well enough. 24 | * **Nose Cone** Specialized structural part for nose cones. The shape is limited to a smooth cone with a bounded ratio of diameter to length. 25 | * **Heat Shield** Built to the same specs as Deadly Reentry. Will shield any sized object from heat. (requires deadly reentry) 26 | 27 | ## Installation 28 | Place the ProceduralParts folder found inside the zip file into GameData. 29 | 30 | Dependencies: 31 | * ModuleManager 32 | * KSPCommunityFixes 33 | 34 | ## Upgrades 35 | * Make sure you delete any old versions of ProceduralParts. 36 | * There's a handful of deprecated parts as was previously used for real fuels. If you didn't use these parts, then you can safely delete the PartsDeprecated folder in the main install directory. 37 | 38 | ## Known Issues 39 | * Known limitation: Setting the default shapeName in a part cfg to a hollow shape breaks surface attaching for a new part. Placing it and picking it up again fixes the issue. 40 | * An SRB attached to a parent through the nozzle gets incorrect position when changing the nozzle angle. Reattaching the part fixes the issue. 41 | 42 | ## Custom Textures and Texture Packs 43 | Procedural Parts is compatible with all texture packs for StretchySRBs. It's easy to [roll your own texture packs](https://github.com/Swamp-Ig/ProceduralParts/blob/master/Parts/STTextures.cfg) too. 44 | 45 | Here's some texture packs that other people have compiled: 46 | 47 | #### Planeguy868 48 | [Download](http://www.mediafire.com/download/gz8f35398bs7a14/planeguy868.zip). 49 | Installation instructions: download and extract it to KSP's GameData folder. 50 | 51 | ![image](http://i.imgur.com/Zsq4zeYm.png) 52 | ![image](http://i.imgur.com/6uSoyXCm.png) 53 | 54 | #### Ferram4's Saturn and Nova Textures 55 | [Download](http://www.mediafire.com/download/9mi9tjb5akaiaaz/SaturnNovaTexturePack.zip). 56 | Installation instructions in zip. 57 | 58 | ![image](http://i.imgur.com/YZyRRBN.jpg) 59 | 60 | #### blackheart612 61 | [Full thread!](http://forum.kerbalspaceprogram.com/threads/68892) 62 | Install instructions and sample images in link. 63 | 64 | ## Compatibility with StretchyTanks / StretchySRBs 65 | This is essentially a completely new mod and can run alongside either of the previous mods. This is useful if you have pre-existing ships in your save file still using those parts. If you don't have any ships using those parts, then you can delete the old mod. 66 | 67 | There's a module manager patch file present that will hide all the StretchySRB tanks in the VAB so they don't clutter it up. If for whatever reason you want to continue using StretchySRBs, then delete ProceduralParts\ModuleManager\StretchyTanks_Hide.cfg and this won't happen. 68 | 69 | ## Integration with Real Fuels and Modular Fuel Tanks 70 | Integration with Real Fuels and Modular Fuels Tanks is complete. Ensure you have Real Fuels version 6.1 or newer, and Modular Fuel Tanks 5.0.1 or newer. There's one or two bugs still to get through, stay tuned for updates on those two. 71 | 72 | For MFT, the existing tank types are turned into the corresponding MFT type. 73 | 74 | For real fuels, there's an SRB which can be switched between low altitude and high altitude versions, plus a tank which can be switched between the various RF tank types. 75 | 76 | The old real fuels system with multiple parts for different tank types is preserved as a deprecated option (hidden in the VAB). If you don't have any old tanks on ships or craft you can delete the PartsDeprecated from the root of the install. 77 | 78 | ## Integration with other mods 79 | Thanks to OtherBarry, there are now tanks for RealFuels, Kethane, Extraplanetary Launchpads, and TAC. 80 | There's also a procedural heat-shield for Deadly Reentry. 81 | All part's drag models will automatically update if using Ferram Aerospace Research. 82 | The tank types will automatically appear if the mods are installed. They should be 'fair' compared to their unmodded versions. 83 | 84 | ## How to ~~cheat in career mode~~ have lower tech restrictions 85 | The current tech restrictions have been tailored to closely mimic stock, with a bit of room to alter the original specs. Note that **this will not be changed** with the out of the box config. 86 | 87 | If you'd like more generous limits, you can create a MM patch (ie: cut and paste this into a file called mycheats.cfg in your GameData dir) and tweak to your liking: 88 | 89 | ~~~~ 90 | @PART[proceduralTank*] 91 | { 92 | @MODULE[ProceduralPart] 93 | { 94 | @TECHLIMIT,* 95 | { 96 | // Increase the max length for all tech levels by 3* 97 | @lengthMax *= 3 98 | // Corresponding volume increase 99 | @volumeMax *= 3 100 | 101 | // Increase the max diameter by double 102 | @diameterMax *= 2 103 | // Since volume goes up on diameter^2, need to use increase^2 104 | @volumeMax *= 4 105 | } 106 | } 107 | } 108 | ~~~~ 109 | This will affect all procedural tanks and the SRB. The name of the Real Fuels SRB is "proceduralSRBRealFuels" so you'll need to make another similar patch for that one if you want to mess with that too. 110 | 111 | If you'd like to be able to use all the shapes from the early game then use the following MM patch: 112 | ~~~~ 113 | @PART[*] 114 | { 115 | @MODULE[ProceduralShape*] 116 | { 117 | -techRequired = dummy 118 | } 119 | } 120 | ~~~~ 121 | This will affect all parts. 122 | 123 | ## Future plans 124 | * Cuboid parts, with customizable side lengths 125 | * Extruded parts, such as hexagonal and octagonal pieces 126 | * Add optional mounting pod for surface mounts to pod tank. 127 | * Procedural command module, possibly with rescaling / tweakable IVA. 128 | 129 | ## Features That Are Not Planned 130 | * Procedural wings, procedural fairings - there's good mods for these already. 131 | * Procedural engines - May happen one day, but not a priority. 132 | 133 | ## Acknowledgements 134 | #### ProceduralParts has an extended family tree 135 | * StretchyTanks is the original module by the great Ancient Gammoner. 136 | * StretchySRBs was created and updated by NathanKell and e-dog. 137 | * ProceduralParts is a near complete re-write by Swamp Ig. 138 | 139 | #### Also featuring 140 | * Extensive work on config and mod integration by OtherBarry 141 | * Models by Tiberion 142 | * Further textures by Chestburster and Dante80. 143 | * Config code by jsimmonds 144 | -------------------------------------------------------------------------------- /Source/CalcsAndModels/Bezier.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/Source/CalcsAndModels/Bezier.xlsx -------------------------------------------------------------------------------- /Source/CalcsAndModels/Circle.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/Source/CalcsAndModels/Circle.xlsx -------------------------------------------------------------------------------- /Source/CalcsAndModels/Heatshields.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/Source/CalcsAndModels/Heatshields.xlsx -------------------------------------------------------------------------------- /Source/CalcsAndModels/ModTanks.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/Source/CalcsAndModels/ModTanks.xlsx -------------------------------------------------------------------------------- /Source/CalcsAndModels/Models.unitypackage: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/Source/CalcsAndModels/Models.unitypackage -------------------------------------------------------------------------------- /Source/CalcsAndModels/StockParts.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KSP-RO/ProceduralParts/784be24bc0feca698694a71786f120c288bf5ac6/Source/CalcsAndModels/StockParts.xlsx -------------------------------------------------------------------------------- /Source/DecouplerTweaker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace ProceduralParts 5 | { 6 | 7 | /// 8 | /// Module to allow tweaking of decouplers in the VAB. 9 | /// 10 | /// This fairly flexible module allows tech dependent tweaking of the type and size of modules. 11 | /// There are options for it to target just one specific module, or all the modules on a part. 12 | /// 13 | public class DecouplerTweaker : PartModule, IPartMassModifier 14 | { 15 | #region IPartMassModifier implementation 16 | 17 | public float GetModuleMass(float defaultMass, ModifierStagingSituation sit) => density > 0 ? mass - defaultMass : 0; 18 | public ModifierChangeWhen GetModuleMassChangeWhen() => ModifierChangeWhen.FIXED; 19 | 20 | #endregion 21 | 22 | /// 23 | /// In career mode, if this tech is not available then the option to have separators is not present 24 | /// 25 | [KSPField] 26 | public string separatorTechRequired; 27 | 28 | /// 29 | /// Maximum ejection impulse available. 30 | /// 31 | [KSPField(isPersistant = true)] 32 | public float maxImpulse = float.PositiveInfinity; 33 | 34 | /// 35 | /// Listen for a specific texture message, again for use with proceedural parts. If set, then listens for ChangeAttachNodeSize message. 36 | /// 37 | [KSPField] 38 | public string textureMessageName; 39 | 40 | /// 41 | /// Density of the decoupler. This is for use with Procedural Parts. Listens for ChangeVolume message 42 | /// 43 | [KSPField] 44 | public float density = 0; 45 | 46 | /// 47 | /// If specified, this will set a maximum impulse based on the mass of the node. 48 | /// 49 | [KSPField] 50 | public float maxImpulseMassRatio = 125; 51 | 52 | [KSPField(isPersistant = true, guiActiveEditor = true, guiName = "Style:", groupName = ProceduralPart.PAWGroupName), 53 | UI_Toggle(disabledText = "Decoupler", enabledText = "Separator")] 54 | public bool isOmniDecoupler = false; 55 | 56 | [KSPField(isPersistant = true, guiActiveEditor = true, guiName = "Impulse", guiUnits = " kN*s", guiFormat = "F1", groupName = ProceduralPart.PAWGroupName), 57 | UI_FloatEdit(scene = UI_Scene.Editor, minValue = 0f, maxValue = float.PositiveInfinity, incrementLarge = 10f, incrementSmall = 1, incrementSlide = 0.1f, sigFigs = 1, unit = " kN")] 58 | public float ejectionImpulse = -1f; 59 | 60 | [KSPField(isPersistant = true, guiActiveEditor = true, guiName="Mass", guiUnits="T", guiFormat="F3", groupName = ProceduralPart.PAWGroupName)] 61 | public float mass = 0; 62 | 63 | [KSPField] 64 | public bool usePFStyleMass = false; 65 | [KSPField] 66 | public Vector4 specificMass = new Vector4(0.0002f, 0.0075f, 0.005f, 0f); 67 | [KSPField] 68 | public float decouplerMassMult = 4f; 69 | 70 | private ModuleDecouple decouple; 71 | internal const float ImpulsePerForceUnit = 0.02f; 72 | private ProceduralPart procPart; 73 | 74 | public override void OnStart(StartState state) 75 | { 76 | decouple = part.FindModuleImplementing(); 77 | procPart = part.FindModuleImplementing(); 78 | if (decouple == null) 79 | { 80 | Debug.LogError($"[ProceduralParts] No ModuleDecouple found on {part}"); 81 | isEnabled = enabled = false; 82 | return; 83 | } 84 | 85 | if (HighLogic.LoadedSceneIsEditor) 86 | { 87 | Fields[nameof(isOmniDecoupler)].guiActiveEditor = 88 | string.IsNullOrEmpty(separatorTechRequired) || ResearchAndDevelopment.GetTechnologyState(separatorTechRequired) == RDTech.State.Available; 89 | 90 | if (ejectionImpulse < 0 || float.IsNaN(ejectionImpulse)) 91 | ejectionImpulse = Math.Min(decouple.ejectionForce * ImpulsePerForceUnit, maxImpulse); 92 | 93 | (Fields[nameof(ejectionImpulse)].uiControlEditor as UI_FloatEdit).maxValue = maxImpulse; 94 | } 95 | else if (HighLogic.LoadedSceneIsFlight) 96 | { 97 | if (ejectionImpulse < 0 || float.IsNaN(ejectionImpulse)) ejectionImpulse = 0; 98 | decouple.isOmniDecoupler = isOmniDecoupler; 99 | decouple.ejectionForce = ejectionImpulse / TimeWarp.fixedDeltaTime; 100 | GameEvents.onTimeWarpRateChanged.Add(OnTimeWarpRateChanged); 101 | } 102 | } 103 | 104 | public override void OnStartFinished(StartState state) 105 | { 106 | base.OnStartFinished(state); 107 | if (HighLogic.LoadedSceneIsEditor && mass == 0f && density > 0) 108 | { 109 | if (procPart != null) 110 | UpdateMass(procPart.Volume); 111 | } 112 | } 113 | 114 | public void OnDestroy() => GameEvents.onTimeWarpRateChanged.Remove(OnTimeWarpRateChanged); 115 | 116 | private bool updatingTimeWarp = false; 117 | public void OnTimeWarpRateChanged() => StartCoroutine(TimeWarpRateChangedCR()); 118 | private System.Collections.IEnumerator TimeWarpRateChangedCR() 119 | { 120 | if (!updatingTimeWarp) 121 | { 122 | float prevWarp = 0; 123 | updatingTimeWarp = true; 124 | while (HighLogic.LoadedSceneIsFlight && TimeWarp.fixedDeltaTime != prevWarp && decouple) 125 | { 126 | decouple.ejectionForce = ejectionImpulse / TimeWarp.fixedDeltaTime; 127 | prevWarp = TimeWarp.fixedDeltaTime; 128 | yield return new WaitForFixedUpdate(); 129 | } 130 | updatingTimeWarp = false; 131 | } 132 | } 133 | 134 | // Plugs into procedural parts. 135 | //public void ChangeAttachNodeSize(AttachNode node, float minDia, float area) 136 | [KSPEvent(guiActive = false, active = true)] 137 | public void OnPartAttachNodeSizeChanged(BaseEventDetails data) 138 | { 139 | if (HighLogic.LoadedSceneIsEditor && 140 | data.Get("node") is AttachNode node && 141 | node.id == textureMessageName && 142 | maxImpulseMassRatio >= float.Epsilon && 143 | Fields[nameof(ejectionImpulse)].uiControlEditor is UI_FloatEdit ejectionImpulseEdit) 144 | { 145 | maxImpulse = CalcMaxImpulse(mass, ejectionImpulseEdit.minValue); 146 | float oldMax = float.IsPositiveInfinity(ejectionImpulseEdit.maxValue) ? maxImpulse : ejectionImpulseEdit.maxValue; 147 | float ratio = Mathf.Clamp01(ejectionImpulse / oldMax); 148 | if (ratio > 0) 149 | ejectionImpulse = maxImpulse * ratio; 150 | ejectionImpulseEdit.maxValue = maxImpulse; 151 | } 152 | } 153 | 154 | private float CalcMaxImpulse(float mass, float min) 155 | { 156 | mass = Mathf.Max(mass, 0.001f); // Disallow values too small 157 | return Mathf.Max(maxImpulseMassRatio * mass, min); 158 | } 159 | 160 | [KSPEvent(active = true)] 161 | public void OnPartVolumeChanged(BaseEventDetails data) 162 | { 163 | if (HighLogic.LoadedSceneIsEditor && density > 0 && data.Get("newTotalVolume") is double volume) 164 | { 165 | UpdateMass(volume); 166 | } 167 | } 168 | 169 | private void UpdateMass(double volume) 170 | { 171 | if (usePFStyleMass && procPart != null) 172 | { 173 | float diam = procPart.Diameter; 174 | float baseMass = (((((specificMass.x * diam) + specificMass.y) * diam) + specificMass.z) * diam) + specificMass.w; 175 | mass = baseMass * decouplerMassMult; 176 | //mass *= Mathf.Lerp(0.9f, 1.1f, Mathf.InverseLerp(0.1f, 0.3f, procPart.Length / diam)); 177 | } 178 | else 179 | { 180 | mass = Convert.ToSingle(density * volume); 181 | } 182 | GameEvents.onEditorShipModified.Fire(EditorLogic.fetch.ship); 183 | } 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /Source/ICostModifier.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace ProceduralParts 7 | { 8 | interface ICostMultiplier 9 | { 10 | float GetCurrentCostMult(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Source/KSPUtils.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable once CheckNamespace 2 | namespace KSPAPIExtensions 3 | { 4 | public static class PartUtils 5 | { 6 | /// 7 | /// If this part is a symmetry clone of another part, this method will return the original part. 8 | /// 9 | /// The part to find the original of 10 | /// The original part, or the part itself if it was the original part 11 | public static Part GetSymmetryCloneOriginal(this Part part) 12 | { 13 | if (!part.isClone || part.symmetryCounterparts == null || part.symmetryCounterparts.Count == 0) 14 | return part; 15 | 16 | foreach (Part other in part.symmetryCounterparts) 17 | { 18 | if (!other.isClone) return other; 19 | } 20 | return part; 21 | } 22 | 23 | public static bool IsSurfaceAttached(this Part part) => 24 | part.srfAttachNode != null && part.srfAttachNode.attachedPart == part.parent; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Source/LegacyTextureHandler.cs: -------------------------------------------------------------------------------- 1 | using KSPAPIExtensions; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using UnityEngine; 6 | 7 | namespace ProceduralParts 8 | { 9 | class LegacyTextureHandler 10 | { 11 | private readonly Part part; 12 | private readonly ProceduralPart PPart; 13 | private static readonly string ModTag = "[ProceduralParts.LegacyTextureHandler]"; 14 | public static readonly Dictionary textureSets = new Dictionary(); 15 | int CapTextureIndex => PPart.capTextureIndex; 16 | public enum CapTextureMode 17 | { 18 | Ends, Side, GreySide, PlainWhite 19 | } 20 | private CapTextureMode CapTexture => (CapTextureMode)CapTextureIndex; 21 | 22 | public Material SidesIconMaterial { get; private set; } 23 | public Material EndsIconMaterial { get; private set; } 24 | 25 | public Material SidesMaterial { get; private set; } 26 | public Material EndsMaterial { get; private set; } 27 | 28 | string SidesName => PPart.sidesName; 29 | string EndsName => PPart.endsName; 30 | string textureSet { get => PPart.textureSet; set => PPart.textureSet = value;} 31 | 32 | [SerializeField] 33 | private Vector2 sideTextureScale = Vector2.one; 34 | 35 | public LegacyTextureHandler(Part part, ProceduralPart ppart) 36 | { 37 | this.part = part; 38 | this.PPart = ppart; 39 | 40 | Transform sides = part.FindModelTransform(SidesName); 41 | Transform ends = part.FindModelTransform(EndsName); 42 | 43 | Transform iconModelTransform = part.partInfo.iconPrefab.transform.FindDecendant("model"); 44 | 45 | Transform iconSides = iconModelTransform.FindDecendant(SidesName); 46 | Transform iconEnds = iconModelTransform.FindDecendant(EndsName); 47 | 48 | SidesIconMaterial = (iconSides is Transform) ? iconSides.GetComponent().material : null; 49 | EndsIconMaterial = (iconEnds is Transform) ? iconEnds.GetComponent().material : null; 50 | 51 | SidesMaterial = sides.GetComponent().material; 52 | EndsMaterial = ends.GetComponent().material; 53 | } 54 | 55 | public void ValidateSelectedTexture() 56 | { 57 | if (!textureSets.ContainsKey(textureSet)) 58 | { 59 | Debug.Log($"{ModTag} Defaulting invalid TextureSet {textureSet} to {textureSets.Keys.First()}"); 60 | textureSet = textureSets.Keys.First(); 61 | } 62 | } 63 | 64 | public void UpdateTexture() 65 | { 66 | // Reset the Material, because TU may steal it. 67 | SidesMaterial = part.FindModelTransform(SidesName).GetComponent().material; 68 | EndsMaterial = part.FindModelTransform(EndsName).GetComponent().material; 69 | 70 | Material endsMaterial = (HighLogic.LoadedScene == GameScenes.LOADING) ? EndsIconMaterial : EndsMaterial; 71 | Material sidesMaterial = (HighLogic.LoadedScene == GameScenes.LOADING) ? SidesIconMaterial : SidesMaterial; 72 | 73 | if (!textureSets.ContainsKey(textureSet)) 74 | { 75 | Debug.LogError($"{ModTag} UpdateTexture() {textureSet} missing from global list!"); 76 | textureSet = textureSets.Keys.First(); 77 | } 78 | TextureSet tex = textureSets[textureSet]; 79 | 80 | if (!part.Modules.Contains("ModulePaintable")) 81 | { 82 | TextureSet.SetupShader(sidesMaterial, tex.sidesBump); 83 | } 84 | 85 | sidesMaterial.SetColor("_SpecColor", tex.sidesSpecular); 86 | sidesMaterial.SetFloat("_Shininess", tex.sidesShininess); 87 | 88 | var scaleUV = tex.GetScaleUv(sideTextureScale); 89 | 90 | sidesMaterial.mainTextureScale = scaleUV; 91 | sidesMaterial.mainTextureOffset = Vector2.zero; 92 | sidesMaterial.SetTexture("_MainTex", tex.sides); 93 | if (tex.sidesBump is Texture && sidesMaterial.HasProperty("_BumpMap")) 94 | { 95 | sidesMaterial.SetTextureScale("_BumpMap", scaleUV); 96 | sidesMaterial.SetTextureOffset("_BumpMap", Vector2.zero); 97 | sidesMaterial.SetTexture("_BumpMap", tex.sidesBump); 98 | } 99 | if (endsMaterial is Material) 100 | { 101 | SetupEndsTexture(endsMaterial, tex, scaleUV); 102 | } 103 | } 104 | 105 | public string MatToStr(Material m) => $"Material {m.name} | {m.color} | {m.mainTexture} | scale: {m.mainTextureScale} | {m.shader}: {string.Join(",", m.shaderKeywords)}"; 106 | 107 | private void SetupEndsTexture(Material endsMaterial, TextureSet tex, Vector2 scaleUV) 108 | { 109 | switch (CapTexture) 110 | { 111 | case CapTextureMode.Ends: 112 | TextureSet.SetTextureProperties(endsMaterial, tex.ends, tex.endsBump, tex.endsSpecular, tex.endsShininess, tex.endsAutoScale, scaleUV); 113 | break; 114 | case CapTextureMode.Side: 115 | TextureSet.SetTextureProperties(endsMaterial, tex.sides, tex.sidesBump, tex.sidesSpecular, tex.sidesShininess, tex.autoScale, scaleUV); 116 | break; 117 | default: 118 | if (textureSets[Enum.GetName(typeof(CapTextureMode), CapTexture)] is TextureSet texture) 119 | { 120 | var endsScaleUV = texture.GetScaleUv(sideTextureScale); 121 | TextureSet.SetTextureProperties(endsMaterial, texture.sides, texture.sidesBump, texture.sidesSpecular, texture.sidesShininess, texture.autoScale, endsScaleUV); 122 | } 123 | break; 124 | } 125 | } 126 | public void ChangeTextureScale(string meshName, Vector2 targetScale) 127 | { 128 | if (meshName == "sides" && targetScale != null) 129 | { 130 | sideTextureScale = targetScale; 131 | UpdateTexture(); 132 | } 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /Source/Makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(OS),Windows_NT) 2 | # do 'Doze stuff 3 | else 4 | UNAME_S := $(shell uname -s) 5 | ifeq ($(UNAME_S),Linux) 6 | KSPDIR := ${HOME}/.local/share/Steam/SteamApps/common/Kerbal\ Space\ Program 7 | MANAGED := ${KSPDIR}/KSP_Data/Managed/ 8 | endif 9 | ifeq ($(UNAME_S),Darwin) 10 | KSPDIR := ${HOME}/Library/Application\ Support/Steam/SteamApps/common/Kerbal\ Space\ Program/ 11 | MANAGED := ${KSPDIR}/KSP.app/Contents/Data/Managed/ 12 | endif 13 | endif 14 | 15 | GAMEDATA := ${KSPDIR}/GameData 16 | APIGAMEDATA := ${GAMEDATA}/KSPAPIExt 17 | PLUGINDIR := ${APIGAMEDATA}/Plugins 18 | KSPAPIEXT := ../../KSPAPIExtensions/Source 19 | 20 | TARGETS := ProceduralParts.dll 21 | 22 | API_FILES := \ 23 | DecouplerTweaker.cs \ 24 | ProceduralAbstractShape.cs \ 25 | ProceduralAbstractSoRShape.cs \ 26 | ProceduralHeatshield.cs \ 27 | ProceduralPart.cs \ 28 | ProceduralShapeBezierCone.cs \ 29 | ProceduralShapeCone.cs \ 30 | ProceduralShapeCylinder.cs \ 31 | ProceduralShapePill.cs \ 32 | ProceduralSRB.cs \ 33 | TankContentSwitcher.cs \ 34 | TransformFollower.cs \ 35 | ICostModifier.cs \ 36 | VectorUtils.cs \ 37 | $e 38 | 39 | RESGEN2 := resgen2 40 | GMCS := csc 41 | GIT := git 42 | TAR := tar 43 | ZIP := zip 44 | 45 | all: version ${TARGETS} 46 | 47 | .PHONY: version 48 | version: 49 | @../version-gen 50 | 51 | info: 52 | @echo "Modular Fuel Tanks Build Information" 53 | @echo " resgen2: ${RESGEN2}" 54 | @echo " gmcs: ${GMCS}" 55 | @echo " git: ${GIT}" 56 | @echo " tar: ${TAR}" 57 | @echo " zip: ${ZIP}" 58 | @echo " KSP Data: ${KSPDIR}" 59 | @echo " Plugin: ${PLUGINDIR}" 60 | 61 | ProceduralParts.dll: ${API_FILES} 62 | ${GMCS} -unsafe -t:library -lib:${APIEXTDATA},${MANAGED},${KSPAPIEXT} \ 63 | -r:Assembly-CSharp,Assembly-CSharp-firstpass,UnityEngine,KSPAPIExtensions \ 64 | -out:$@ $^ 65 | 66 | clean: 67 | rm -f ${TARGETS} AssemblyInfo.cs 68 | 69 | install: all 70 | mkdir -p ${PLUGINDIR} 71 | cp ${TARGETS} ${PLUGINDIR} 72 | 73 | .PHONY: all clean install 74 | -------------------------------------------------------------------------------- /Source/ProceduralParts.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | x86 6 | 8.0.30703 7 | 2.0 8 | {BB7C12FE-8189-4A56-B058-58C1B7366E60} 9 | Library 10 | Properties 11 | ProceduralParts 12 | ProceduralParts 13 | v4.7.2 14 | 15 | 16 | 512 17 | ..\..\Build\ProceduralParts\obj 18 | 19 | 20 | AnyCPU 21 | none 22 | false 23 | ..\..\Build\ProceduralParts\obj\ 24 | ..\Plugins\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | 1607 29 | 8.0 30 | false 31 | 32 | 33 | x86 34 | full 35 | true 36 | ..\..\..\Build\ProceduralParts\obj\ 37 | ..\Plugins\ 38 | prompt 39 | 4 40 | Auto 41 | true 42 | 8.0 43 | false 44 | 45 | 46 | bin\Debug\ 47 | TRACE;DEBUG;ENABLE_PROFILER 48 | 1607 49 | AnyCPU 50 | prompt 51 | MinimumRecommendedRules.ruleset 52 | 8.0 53 | false 54 | portable 55 | 56 | 57 | true 58 | bin\Release\ 59 | true 60 | full 61 | anycpu 62 | prompt 63 | MinimumRecommendedRules.ruleset 64 | 8.0 65 | false 66 | 67 | 68 | 69 | False 70 | 71 | 72 | False 73 | 74 | 75 | False 76 | 77 | 78 | False 79 | 80 | 81 | False 82 | 83 | 84 | False 85 | 86 | 87 | False 88 | 89 | 90 | False 91 | 92 | 93 | False 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | -------------------------------------------------------------------------------- /Source/ProceduralParts.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25123.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProceduralParts", "ProceduralParts.csproj", "{BB7C12FE-8189-4A56-B058-58C1B7366E60}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Debug|x86 = Debug|x86 12 | Release|Any CPU = Release|Any CPU 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {BB7C12FE-8189-4A56-B058-58C1B7366E60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {BB7C12FE-8189-4A56-B058-58C1B7366E60}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {BB7C12FE-8189-4A56-B058-58C1B7366E60}.Debug|x86.ActiveCfg = Debug|x86 19 | {BB7C12FE-8189-4A56-B058-58C1B7366E60}.Debug|x86.Build.0 = Debug|x86 20 | {BB7C12FE-8189-4A56-B058-58C1B7366E60}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {BB7C12FE-8189-4A56-B058-58C1B7366E60}.Release|x86.ActiveCfg = Release|x86 22 | {BB7C12FE-8189-4A56-B058-58C1B7366E60}.Release|x86.Build.0 = Release|x86 23 | {BB7C12FE-8189-4A56-B058-58C1B7366E60}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(MonoDevelopProperties) = preSolution 29 | Policies = $0 30 | $0.DotNetNamingPolicy = $1 31 | $1.DirectoryNamespaceAssociation = None 32 | $1.ResourceNamePolicy = FileFormatDefault 33 | $0.TextStylePolicy = $2 34 | $2.inheritsSet = VisualStudio 35 | $2.inheritsScope = text/plain 36 | $2.scope = text/x-csharp 37 | $0.CSharpFormattingPolicy = $3 38 | $3.IndentSwitchSection = True 39 | $3.NewLinesForBracesInProperties = True 40 | $3.NewLinesForBracesInAccessors = True 41 | $3.NewLinesForBracesInAnonymousMethods = True 42 | $3.NewLinesForBracesInControlBlocks = True 43 | $3.NewLinesForBracesInAnonymousTypes = True 44 | $3.NewLinesForBracesInObjectCollectionArrayInitializers = True 45 | $3.NewLinesForBracesInLambdaExpressionBody = True 46 | $3.NewLineForElse = True 47 | $3.NewLineForCatch = True 48 | $3.NewLineForFinally = True 49 | $3.NewLineForMembersInObjectInit = True 50 | $3.NewLineForMembersInAnonymousTypes = True 51 | $3.NewLineForClausesInQuery = True 52 | $3.SpacingAfterMethodDeclarationName = False 53 | $3.SpaceAfterMethodCallName = False 54 | $3.SpaceBeforeOpenSquareBracket = False 55 | $3.inheritsSet = Mono 56 | $3.inheritsScope = text/x-csharp 57 | $3.scope = text/x-csharp 58 | EndGlobalSection 59 | EndGlobal 60 | -------------------------------------------------------------------------------- /Source/ProceduralParts.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | True 3 | DO_NOT_SHOW 4 | DO_NOT_SHOW 5 | DO_NOT_SHOW 6 | DO_NOT_SHOW 7 | DO_NOT_SHOW 8 | DO_NOT_SHOW 9 | DO_NOT_SHOW 10 | DO_NOT_SHOW 11 | DO_NOT_SHOW 12 | FAR 13 | ISP 14 | KSP 15 | ME 16 | UI 17 | <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb"><ExtraRule Prefix="" Suffix="" Style="aaBb" /></Policy> 18 | <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb"><ExtraRule Prefix="" Suffix="" Style="aaBb" /></Policy> 19 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"><ExtraRule Prefix="" Suffix="" Style="aaBb" /></Policy> 20 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"><ExtraRule Prefix="" Suffix="" Style="aaBb" /></Policy> 21 | GUI 22 | ID 23 | UV 24 | XZU 25 | KL 26 | SRB 27 | TS 28 | SPH 29 | VAB 30 | -------------------------------------------------------------------------------- /Source/ProceduralParts.userprefs: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /Source/ProceduralShapeCylinder.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.Profiling; 3 | 4 | namespace ProceduralParts 5 | { 6 | public class ProceduralShapeCylinder : ProceduralAbstractSoRShape 7 | { 8 | private const string ModTag = "[ProceduralShapeCylinder]"; 9 | #region Config parameters 10 | 11 | [KSPField(isPersistant = true, guiActiveEditor = true, guiName = "Diameter", guiFormat = "F3", guiUnits = "m", groupName = ProceduralPart.PAWGroupName), 12 | UI_FloatEdit(scene = UI_Scene.Editor, incrementSlide = SliderPrecision, sigFigs = 5, unit="m", useSI = true)] 13 | public float diameter = 1.25f; 14 | 15 | [KSPField(isPersistant = true, guiActiveEditor = true, guiName = "Length", guiFormat = "F3", guiUnits = "m", groupName = ProceduralPart.PAWGroupName), 16 | UI_FloatEdit(scene = UI_Scene.Editor, incrementSlide = SliderPrecision, sigFigs = 5, unit="m", useSI = true)] 17 | public float length = 1f; 18 | 19 | #endregion 20 | 21 | #region Initialization 22 | 23 | public override void OnStart(StartState state) 24 | { 25 | base.OnStart(state); 26 | if (HighLogic.LoadedSceneIsEditor) 27 | { 28 | UpdateTechConstraints(); 29 | Fields[nameof(diameter)].uiControlEditor.onFieldChanged = OnShapeDimensionChanged; 30 | Fields[nameof(length)].uiControlEditor.onFieldChanged = OnShapeDimensionChanged; 31 | } 32 | } 33 | 34 | public override void UpdateTechConstraints() 35 | { 36 | Fields[nameof(length)].guiActiveEditor = PPart.lengthMin != PPart.lengthMax; 37 | UI_FloatEdit lengthEdit = Fields[nameof(length)].uiControlEditor as UI_FloatEdit; 38 | lengthEdit.incrementLarge = PPart.lengthLargeStep; 39 | lengthEdit.incrementSmall = PPart.lengthSmallStep; 40 | 41 | Fields[nameof(diameter)].guiActiveEditor = PPart.diameterMin != PPart.diameterMax; 42 | UI_FloatEdit diameterEdit = Fields[nameof(diameter)].uiControlEditor as UI_FloatEdit; 43 | diameterEdit.incrementLarge = PPart.diameterLargeStep; 44 | diameterEdit.incrementSmall = PPart.diameterSmallStep; 45 | 46 | AdjustDimensionBounds(); 47 | length = Mathf.Clamp(length, lengthEdit.minValue, lengthEdit.maxValue); 48 | diameter = Mathf.Clamp(diameter, diameterEdit.minValue, diameterEdit.maxValue); 49 | } 50 | 51 | #endregion 52 | 53 | #region Update handlers 54 | 55 | internal override void UpdateShape(bool force = true) 56 | { 57 | Profiler.BeginSample("UpdateShape Cyl"); 58 | part.CoMOffset = CoMOffset; 59 | MaxDiameter = MinDiameter = diameter; 60 | InnerMaxDiameter = InnerMinDiameter = -1f; 61 | Length = length; 62 | NominalVolume = CalculateVolume(); 63 | Volume = NominalVolume; 64 | Vector2 norm = new Vector2(1, 0); 65 | 66 | WriteMeshes( 67 | new ProfilePoint(diameter, -0.5f * length, 0f, norm), 68 | new ProfilePoint(diameter, 0.5f * length, 1f, norm) 69 | ); 70 | Profiler.EndSample(); 71 | } 72 | 73 | public override void AdjustDimensionBounds() 74 | { 75 | // V = 1/4 * pi * L * (d*d) 76 | // L = 4*V / pi * (d*d) 77 | // D = sqrt(4*V/pi / L) 78 | float t = PPart.volumeMax * 4f / Mathf.PI; 79 | float tMin = PPart.volumeMin * 4f / Mathf.PI; 80 | 81 | float maxDiameter = Mathf.Sqrt(t / length); 82 | float maxLength = t / (diameter * diameter); 83 | float minDiameter = Mathf.Sqrt(tMin / length); 84 | float minLength = tMin / (diameter * diameter); 85 | 86 | maxLength = Mathf.Clamp(maxLength, PPart.lengthMin, PPart.lengthMax); 87 | maxDiameter = Mathf.Clamp(maxDiameter, PPart.diameterMin, PPart.diameterMax); 88 | 89 | minLength = Mathf.Clamp(minLength, PPart.lengthMin, PPart.lengthMax - PPart.lengthSmallStep); 90 | minDiameter = Mathf.Clamp(minDiameter, PPart.diameterMin, PPart.diameterMax - PPart.diameterSmallStep); 91 | 92 | (Fields[nameof(diameter)].uiControlEditor as UI_FloatEdit).maxValue = maxDiameter; 93 | (Fields[nameof(length)].uiControlEditor as UI_FloatEdit).maxValue = maxLength; 94 | (Fields[nameof(diameter)].uiControlEditor as UI_FloatEdit).minValue = minDiameter; 95 | (Fields[nameof(length)].uiControlEditor as UI_FloatEdit).minValue = minLength; 96 | } 97 | 98 | public override float CalculateVolume() => CalculateVolume(length, diameter); 99 | public static float CalculateVolume(float length, float diameter) 100 | { 101 | return diameter * diameter * 0.25f * Mathf.PI * length; 102 | } 103 | 104 | public override bool SeekVolume(float targetVolume, int dir) => SeekVolume(targetVolume, Fields[nameof(length)], dir); 105 | 106 | public override void UpdateTFInterops() 107 | { 108 | ProceduralPart.tfInterface.InvokeMember("AddInteropValue", ProceduralPart.tfBindingFlags, null, null, new System.Object[] { this.part, "diam1", diameter, "ProceduralParts" }); 109 | ProceduralPart.tfInterface.InvokeMember("AddInteropValue", ProceduralPart.tfBindingFlags, null, null, new System.Object[] { this.part, "diam2", diameter, "ProceduralParts" }); 110 | ProceduralPart.tfInterface.InvokeMember("AddInteropValue", ProceduralPart.tfBindingFlags, null, null, new System.Object[] { this.part, "length", length, "ProceduralParts" }); 111 | } 112 | 113 | public override void TranslateAttachmentsAndNodes(BaseField f, object obj) 114 | { 115 | if (f.name == nameof(diameter) && obj is float oldDiameter) 116 | { 117 | HandleDiameterChange((float)f.GetValue(this), oldDiameter); 118 | } 119 | if (f.name == nameof(length) && obj is float oldLen) 120 | { 121 | HandleLengthChange((float)f.GetValue(this), oldLen); 122 | } 123 | } 124 | 125 | internal override void InitializeAttachmentNodes() => InitializeAttachmentNodes(length, diameter); 126 | 127 | public override void NormalizeCylindricCoordinates(ShapeCoordinates coords) 128 | { 129 | coords.r /= (diameter / 2); 130 | coords.y /= length; 131 | } 132 | 133 | public override void UnNormalizeCylindricCoordinates(ShapeCoordinates coords) 134 | { 135 | coords.r *= (diameter / 2); 136 | coords.y *= length; 137 | } 138 | 139 | #endregion 140 | } 141 | } -------------------------------------------------------------------------------- /Source/ProceduralTools/DragCubeTool.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using UnityEngine; 4 | using UnityEngine.Profiling; 5 | 6 | namespace ProceduralTools 7 | { 8 | public class DragCubeTool : MonoBehaviour 9 | { 10 | public Part part; 11 | 12 | public static DragCubeTool UpdateDragCubes(Part p) 13 | { 14 | var tool = p.GetComponent(); 15 | if (tool == null) 16 | { 17 | tool = p.gameObject.AddComponent(); 18 | tool.part = p; 19 | } 20 | return tool; 21 | } 22 | 23 | public static void UpdateDragCubesImmediate(Part p) 24 | { 25 | if (!Ready(p)) 26 | throw new InvalidOperationException("Not ready for drag cube rendering yet"); 27 | 28 | UpdateCubes(p); 29 | } 30 | 31 | public void FixedUpdate() 32 | { 33 | if (Ready()) 34 | UpdateCubes(); 35 | } 36 | 37 | public bool Ready() => Ready(part); 38 | 39 | private static bool Ready(Part p) 40 | { 41 | if (HighLogic.LoadedSceneIsFlight) 42 | return FlightGlobals.ready; //&& !part.packed && part.vessel.loaded; 43 | if (HighLogic.LoadedSceneIsEditor) 44 | return p.localRoot == EditorLogic.RootPart && p.gameObject.layer != LayerMask.NameToLayer("TransparentFX"); 45 | return true; 46 | } 47 | 48 | private void UpdateCubes() 49 | { 50 | UpdateCubes(part); 51 | Destroy(this); 52 | } 53 | 54 | private static void UpdateCubes(Part p) 55 | { 56 | Profiler.BeginSample("UpdateCubes"); 57 | if (FARinstalled) 58 | p.SendMessage("GeometryPartModuleRebuildMeshData"); 59 | DragCube dragCube = DragCubeSystem.Instance.RenderProceduralDragCube(p); 60 | p.DragCubes.ClearCubes(); 61 | p.DragCubes.Cubes.Add(dragCube); 62 | p.DragCubes.ResetCubeWeights(); 63 | p.DragCubes.ForceUpdate(true, true, false); 64 | p.DragCubes.SetDragWeights(); 65 | Profiler.EndSample(); 66 | } 67 | 68 | private static bool? _farInstalled; 69 | public static bool FARinstalled 70 | { 71 | get 72 | { 73 | if (!_farInstalled.HasValue) 74 | { 75 | _farInstalled = AssemblyLoader.loadedAssemblies.Any(a => a.assembly.GetName().Name == "FerramAerospaceResearch"); 76 | } 77 | return _farInstalled.Value; 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Source/ProceduralTools/KSPFieldTool.cs: -------------------------------------------------------------------------------- 1 | namespace ProceduralTools 2 | { 3 | public class KSPFieldTool 4 | { 5 | private const System.Reflection.BindingFlags SetFieldFlags = System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance; 6 | public static void SetField(PartModule instance, BaseField field, object val) 7 | { 8 | if (instance == null || field == null || val == null) 9 | return; 10 | var pai = field.uiControlEditor?.partActionItem as UIPartActionFieldItem; 11 | if (pai == null) 12 | { 13 | UIPartActionController.Instance.SpawnPartActionWindow(instance.part); 14 | pai = field.uiControlEditor?.partActionItem as UIPartActionFieldItem; 15 | } 16 | if (pai != null && 17 | pai.GetType().GetMethod("SetFieldValue", SetFieldFlags) is var _mi) 18 | { 19 | _mi.Invoke(pai, new object[] { val }); 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Source/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | #define CIBUILD_disabled 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("ProceduralParts")] 10 | [assembly: AssemblyDescription("Plugin for Kerbal Space Program")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("ProceduralParts")] 14 | [assembly: AssemblyCopyright("Copyright © 2014")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | 18 | // Setting ComVisible to false makes the types in this assembly not visible 19 | // to COM components. If you need to access a type in this assembly from 20 | // COM, set the ComVisible attribute to true on that type. 21 | [assembly: ComVisible(false)] 22 | 23 | // The following GUID is for the ID of the typelib if this project is exposed to COM 24 | [assembly: Guid("a1c9118f-14a4-4aaf-bb43-87b1c13a7d4d")] 25 | 26 | #if CIBUILD 27 | [assembly: KSPAssembly("ProceduralParts", @MAJOR@, @MINOR@)] 28 | #else 29 | [assembly: KSPAssembly("ProceduralParts", 2, 99)] 30 | #endif 31 | 32 | // Version information for an assembly consists of the following four values: 33 | // 34 | // Major Version 35 | // Minor Version 36 | // Build Number 37 | // Revision 38 | // 39 | [assembly: AssemblyVersion("2.0.0.0")] 40 | #if CIBUILD 41 | [assembly: AssemblyFileVersion("@MAJOR@.@MINOR@.@PATCH@.@BUILD@")] 42 | #else 43 | [assembly: AssemblyFileVersion("2.99.0.0")] 44 | #endif 45 | -------------------------------------------------------------------------------- /Source/Properties/AssemblyInfo.in: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ProceduralParts")] 9 | [assembly: AssemblyDescription("Plugin for Kerbal Space Program")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ProceduralParts")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("a1c9118f-14a4-4aaf-bb43-87b1c13a7d4d")] 24 | 25 | [assembly: KSPAssembly("ProceduralParts", @VERSION_MAJOR@, @VERSION_MINOR@)] 26 | 27 | // Version information for an assembly consists of the following four values: 28 | // 29 | // Major Version 30 | // Minor Version 31 | // Build Number 32 | // Revision 33 | // 34 | [assembly: AssemblyVersion("@VERSION_MAJOR_FIRST@")] 35 | [assembly: AssemblyFileVersion("@VERSION@")] 36 | -------------------------------------------------------------------------------- /Source/TextureSet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using UnityEngine; 6 | 7 | namespace ProceduralParts 8 | { 9 | public class TextureSet 10 | { 11 | public string name; 12 | 13 | public bool autoScale; 14 | public bool autoScaleU; 15 | public bool autoScaleV; 16 | public bool endsAutoScale; 17 | public bool autoWidthDivide; 18 | public float autoHeightSteps; 19 | public Vector2 scale = new Vector2(2f, 1f); 20 | 21 | public Texture sides; 22 | public Texture sidesBump = null; 23 | public Texture ends; 24 | public Texture endsBump = null; 25 | public string sidesName; 26 | public string endsName; 27 | public string sidesBumpName; 28 | public string endsBumpName; 29 | 30 | public Color sidesSpecular = new Color(0.2f, 0.2f, 0.2f); 31 | public float sidesShininess = 0.4f; 32 | 33 | public Color endsSpecular = new Color(0.2f, 0.2f, 0.2f); 34 | public float endsShininess = 0.4f; 35 | 36 | public static readonly string ModTag = "[ProceduralParts.TextureSet]"; 37 | 38 | public static TextureSet LoadTextureSet(ConfigNode node) 39 | { 40 | if (!(node.GetNode("sides") is ConfigNode sidesNode && node.GetNode("ends") is ConfigNode endsNode && 41 | sidesNode.HasValue("texture") && endsNode.HasValue("texture"))) 42 | { 43 | Debug.LogError($"{ModTag} LoadTextureSet found invalid Textureset {node.name}"); 44 | return null; 45 | } 46 | 47 | TextureSet tex = new TextureSet 48 | { 49 | name = node.name, 50 | sidesName = sidesNode.GetValue("texture"), 51 | endsName = endsNode.GetValue("texture"), 52 | sidesBumpName = sidesNode.HasValue("bump") ? sidesNode.GetValue("bump") : string.Empty, 53 | endsBumpName = endsNode.HasValue("bump") ? endsNode.GetValue("bump") : string.Empty 54 | }; 55 | 56 | if (sidesNode.HasValue("uScale")) 57 | float.TryParse(sidesNode.GetValue("uScale"), out tex.scale.x); 58 | if (sidesNode.HasValue("vScale")) 59 | float.TryParse(sidesNode.GetValue("vScale"), out tex.scale.y); 60 | 61 | if (sidesNode.HasValue("autoScale")) 62 | bool.TryParse(sidesNode.GetValue("autoScale"), out tex.autoScale); 63 | if (sidesNode.HasValue("autoScaleU")) 64 | bool.TryParse(sidesNode.GetValue("autoScaleU"), out tex.autoScaleU); 65 | if (sidesNode.HasValue("autoScaleV")) 66 | bool.TryParse(sidesNode.GetValue("autoScaleV"), out tex.autoScaleV); 67 | tex.autoScaleU |= tex.autoScale; 68 | tex.autoScaleV |= tex.autoScale; 69 | 70 | if (endsNode.HasValue("autoScale")) 71 | bool.TryParse(endsNode.GetValue("autoScale"), out tex.endsAutoScale); 72 | if (sidesNode.HasValue("autoWidthDivide")) 73 | bool.TryParse(sidesNode.GetValue("autoWidthDivide"), out tex.autoWidthDivide); 74 | if (sidesNode.HasValue("autoHeightSteps")) 75 | float.TryParse(sidesNode.GetValue("autoHeightSteps"), out tex.autoHeightSteps); 76 | 77 | if (sidesNode.HasValue("specular")) 78 | tex.sidesSpecular = ConfigNode.ParseColor(sidesNode.GetValue("specular")); 79 | if (sidesNode.HasValue("shininess")) 80 | float.TryParse(sidesNode.GetValue("shininess"), out tex.sidesShininess); 81 | if (endsNode.HasValue("specular")) 82 | tex.endsSpecular = ConfigNode.ParseColor(endsNode.GetValue("specular")); 83 | if (endsNode.HasValue("shininess")) 84 | float.TryParse(endsNode.GetValue("shininess"), out tex.endsShininess); 85 | 86 | Texture[] textures = Resources.FindObjectsOfTypeAll(typeof(Texture)) as Texture[]; 87 | 88 | if (!TryFindTexture(textures, ref tex.sidesName, out tex.sides)) 89 | { 90 | Debug.LogError($"{ModTag} LoadTextureSet Sides textures not found for {node.name}"); 91 | return null; 92 | } 93 | 94 | if (!TryFindTexture(textures, ref tex.endsName, out tex.ends)) 95 | { 96 | Debug.LogError($"{ModTag} LoadTextureSet Ends textures not found for {node.name}"); 97 | return null; 98 | } 99 | 100 | if (!string.IsNullOrEmpty(tex.sidesBumpName) && !TryFindTexture(textures, ref tex.sidesBumpName, out tex.sidesBump)) 101 | { 102 | Debug.LogError($"{ModTag} LoadTextureSet Side Bump textures not found for {node.name}"); 103 | return null; 104 | } 105 | 106 | if (!string.IsNullOrEmpty(tex.endsBumpName) && !TryFindTexture(textures, ref tex.endsBumpName, out tex.endsBump)) 107 | { 108 | Debug.LogError($"{ModTag} LoadTextureSet Cap bump textures not found for {node.name}"); 109 | return null; 110 | } 111 | 112 | return tex; 113 | } 114 | 115 | public static void LoadTextureSets(Dictionary dict) 116 | { 117 | if (dict is null) return; 118 | foreach (ConfigNode texInfo in GameDatabase.Instance.GetConfigNodes("STRETCHYTANKTEXTURES")) 119 | { 120 | foreach (ConfigNode node in texInfo.nodes) 121 | { 122 | if (LoadTextureSet(node) is TextureSet textureSet) 123 | { 124 | if (dict.ContainsKey(textureSet.name)) 125 | { 126 | Debug.LogError($"Duplicate legacy TextureSet {textureSet.name} found in {node}, skipping!"); 127 | } else 128 | { 129 | dict.Add(textureSet.name, textureSet); 130 | } 131 | } 132 | } 133 | } 134 | 135 | if (dict.Count == 0) 136 | Debug.LogError($"{ModTag} No TextureSets found!"); 137 | } 138 | 139 | private static bool TryFindTexture(Texture[] textures, ref string textureName, out Texture tex) 140 | { 141 | tex = FindTexture(textures, textureName); 142 | if (tex != null) 143 | return true; 144 | if (!textureName.StartsWith("StretchyTanks")) 145 | return false; 146 | 147 | string substName = "ProceduralParts" + textureName.Substring("StretchyTanks".Length); 148 | tex = FindTexture(textures, substName); 149 | if (tex is null) 150 | return false; 151 | 152 | textureName = substName; 153 | return true; 154 | } 155 | 156 | private static Texture FindTexture(Texture[] textures, string textureName) => 157 | textures.FirstOrDefault(t => t.name == textureName); 158 | 159 | internal Vector2 GetScaleUv(Vector2 sideTextureScale) 160 | { 161 | var scaleUV = scale; 162 | if (autoScaleU) 163 | { 164 | scaleUV.x = Math.Max(1, (float)Math.Round(scaleUV.x * sideTextureScale.x / 8f)); 165 | } 166 | if (autoScaleU && autoScaleV) 167 | { 168 | if (autoWidthDivide) 169 | { 170 | if (autoHeightSteps > 0) 171 | scaleUV.y = (float)Math.Ceiling(scaleUV.y * sideTextureScale.y / scaleUV.x * (1f / autoHeightSteps)) * autoHeightSteps; 172 | else 173 | scaleUV.y *= sideTextureScale.y / scaleUV.x; 174 | } 175 | else 176 | { 177 | if (autoHeightSteps > 0) 178 | scaleUV.y = (float)Math.Max(Math.Round(sideTextureScale.y / autoHeightSteps), 1f) * autoHeightSteps; 179 | else 180 | scaleUV.y *= sideTextureScale.y; 181 | } 182 | } else if (autoScaleV) 183 | { 184 | float scaleFactor = autoWidthDivide ? (sideTextureScale.x / 8f) : 1; 185 | if (autoHeightSteps > 0) 186 | scaleUV.y = (float)Math.Max(Math.Round(scaleUV.y * sideTextureScale.y / (autoHeightSteps * scaleFactor)), 1f) * autoHeightSteps; 187 | else 188 | scaleUV.y *= sideTextureScale.y / scaleFactor; 189 | } 190 | 191 | return scaleUV; 192 | } 193 | 194 | internal static void SetupShader(Material material, Texture bumpMap) 195 | { 196 | if (HighLogic.LoadedScene != GameScenes.LOADING) 197 | { 198 | material.shader = Shader.Find(bumpMap != null ? "KSP/Bumped Specular" : "KSP/Specular"); 199 | } 200 | else 201 | { 202 | material.shader = Shader.Find("KSP/ScreenSpaceMask"); 203 | } 204 | } 205 | 206 | internal static void SetTextureProperties(Material material, Texture texture, Texture bumpMap, Color specular, float shininess, bool autoScale, Vector2 scaleUV) 207 | { 208 | var scaleFactor = autoScale ? scaleUV.x / Mathf.PI * 2 : 0.95f; 209 | var scaleVec = new Vector2(scaleFactor, scaleFactor); 210 | var offset = 0.5f - 0.5f * scaleFactor; 211 | var offsetVec = new Vector2(offset, offset); 212 | material.mainTextureScale = scaleVec; 213 | material.mainTextureOffset = offsetVec; 214 | 215 | material.SetColor("_SpecColor", specular); 216 | material.SetFloat("_Shininess", shininess); 217 | material.SetTexture("_MainTex", texture); 218 | 219 | SetupShader(material, bumpMap); 220 | 221 | if (bumpMap != null && material.HasProperty("_BumpMap")) 222 | { 223 | material.SetTextureScale("_BumpMap", scaleVec); 224 | material.SetTextureOffset("_BumpMap", offsetVec); 225 | material.SetTexture("_BumpMap", bumpMap); 226 | } 227 | } 228 | } 229 | } 230 | -------------------------------------------------------------------------------- /Source/TransformFollower.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace ProceduralParts 4 | { 5 | public class TransformFollower : MonoBehaviour 6 | { 7 | [SerializeField] 8 | private Transformable target; 9 | [SerializeField] 10 | private bool hasParent; 11 | [SerializeField] 12 | private Vector3 oldOffset; 13 | [SerializeField] 14 | private Quaternion oldParentRotation; 15 | [SerializeField] 16 | private Quaternion oldLocalRotation; 17 | 18 | private void SetParentInternal(Transform newParent) 19 | { 20 | if (newParent == null) 21 | { 22 | hasParent = false; 23 | transform.parent = null; 24 | oldOffset = transform.position; 25 | oldParentRotation = Quaternion.identity; 26 | oldLocalRotation = transform.localRotation; 27 | } 28 | else 29 | { 30 | hasParent = true; 31 | transform.parent = newParent; 32 | oldOffset = transform.position - newParent.position; 33 | oldParentRotation = transform.parent.rotation; 34 | oldLocalRotation = transform.localRotation; 35 | } 36 | } 37 | 38 | private void Update() 39 | { 40 | if (!HighLogic.LoadedSceneIsFlight) 41 | ForceUpdate(); 42 | } 43 | 44 | public void ForceUpdate() 45 | { 46 | if (target.Destroyed) 47 | { 48 | Destroy(gameObject); 49 | print("Target destroyed: " + ((target==null)?"null":target.name)); 50 | return; 51 | } 52 | 53 | if (hasParent != (transform.parent != null)) 54 | { 55 | print("Setting parent during update: " + transform.parent); 56 | SetParentInternal(transform.parent); 57 | return; 58 | } 59 | 60 | DoTranslation(); 61 | 62 | DoRotation(); 63 | } 64 | 65 | /// 66 | /// Updates the local rotation to the orientation supplied. This will *not* pass the orientation change 67 | /// to the attached object, so is useful to set the orientation to some known 'reference' (ie the surface normal) 68 | /// 69 | public void SetLocalRotationReference(Quaternion orientation) 70 | { 71 | DoRotation(); 72 | oldLocalRotation = transform.localRotation = orientation; 73 | } 74 | 75 | private void DoTranslation() 76 | { 77 | Vector3 trans; 78 | if (hasParent) 79 | { 80 | if (oldParentRotation != transform.parent.rotation) // http://docs.unity3d.com/ScriptReference/Quaternion-operator_ne.html 81 | { 82 | oldOffset = transform.parent.rotation * (Quaternion.Inverse(oldParentRotation) * oldOffset); 83 | oldParentRotation = transform.parent.rotation; 84 | } 85 | 86 | Vector3 offset = transform.position - transform.parent.position; 87 | 88 | if (offset == oldOffset) 89 | return; 90 | 91 | trans = offset - oldOffset; 92 | oldOffset = offset; 93 | } 94 | else 95 | { 96 | if (transform.position == oldOffset) 97 | return; 98 | 99 | trans = transform.position - oldOffset; 100 | oldOffset = transform.position; 101 | } 102 | target.Translate(trans); 103 | } 104 | 105 | private void DoRotation() 106 | { 107 | if (oldLocalRotation == transform.localRotation) 108 | return; 109 | 110 | // What we want to apply is the change in rotation. This is equivalent to undoing (inverse) the old rotation, and applying the new one 111 | Quaternion rot; 112 | if (hasParent) 113 | rot = transform.parent.rotation * (Quaternion.Inverse(oldLocalRotation) * transform.localRotation) * Quaternion.Inverse(transform.parent.rotation); 114 | else 115 | rot = Quaternion.Inverse(oldLocalRotation) * transform.localRotation; 116 | 117 | target.Rotate(rot); 118 | oldLocalRotation = transform.localRotation; 119 | } 120 | 121 | public static TransformFollower CreateFollower(Transform attached) 122 | { 123 | return CreateFollower(null, attached.position, new TransformTransformable(attached)); 124 | } 125 | 126 | public static TransformFollower CreateFollower(Transform parent, Transform attached) 127 | { 128 | return CreateFollower(parent, attached.position, new TransformTransformable(attached)); 129 | } 130 | 131 | public static TransformFollower CreateFollower(Transform attached, Vector3 offset, Space offsetSpace = Space.Self) 132 | { 133 | return CreateFollower(null, attached, offset, offsetSpace); 134 | } 135 | 136 | public static TransformFollower CreateFollower(Transform parent, Transform attached, Vector3 offset, Space offsetSpace = Space.Self) 137 | { 138 | Vector3 worldOffset, localOffset; 139 | if (offsetSpace == Space.Self) 140 | { 141 | worldOffset = attached.TransformDirection(offset); 142 | localOffset = offset; 143 | } 144 | else 145 | { 146 | worldOffset = offset; 147 | localOffset = attached.InverseTransformDirection(offset); 148 | } 149 | return CreateFollower(parent, attached.position + worldOffset, new TransformTransformable(attached, localOffset)); 150 | } 151 | 152 | public static TransformFollower CreateFollower(Vector3 position, Transformable target) 153 | { 154 | return CreateFollower(null, position, target); 155 | } 156 | 157 | public static TransformFollower CreateFollower(Transform parent, Vector3 position, Transformable target) 158 | { 159 | GameObject go = new GameObject("Follower:" + target, typeof(TransformFollower)); 160 | TransformFollower loc = go.GetComponent(); 161 | 162 | loc.target = target; 163 | 164 | go.transform.position = position; 165 | loc.SetParentInternal(parent); 166 | 167 | return loc; 168 | } 169 | 170 | public abstract class Transformable : Object 171 | { 172 | public abstract bool Destroyed { get; } 173 | 174 | public abstract void Translate(Vector3 translation); 175 | 176 | public abstract void Rotate(Quaternion rotate); 177 | } 178 | 179 | public class TransformTransformable : Transformable 180 | { 181 | 182 | [SerializeField] 183 | private readonly Transform transform; 184 | [SerializeField] 185 | private Vector3? offset; 186 | 187 | // ReSharper disable once RedundantArgumentDefaultValue 188 | public TransformTransformable(Transform transform) : this(transform, null) { } 189 | 190 | public TransformTransformable(Transform transform, Vector3 offset, Space offsetSpace = Space.Self) : this(transform, (Vector3?)offset, offsetSpace) { } 191 | 192 | private TransformTransformable(Transform transform, Vector3? offset = null, Space offsetSpace = Space.Self) 193 | { 194 | this.transform = transform; 195 | if (offset == null || offset.Value == Vector3.zero) 196 | this.offset = null; 197 | else if (offsetSpace == Space.Self) 198 | this.offset = offset; 199 | else 200 | this.offset = transform.InverseTransformDirection(offset.Value); 201 | } 202 | 203 | override public bool Destroyed 204 | { 205 | get 206 | { 207 | return !transform; 208 | } 209 | } 210 | 211 | override public void Translate(Vector3 translation) 212 | { 213 | transform.Translate(translation, Space.World); 214 | } 215 | 216 | override public void Rotate(Quaternion rotate) 217 | { 218 | if (offset == null) 219 | { 220 | transform.rotation = rotate * transform.rotation; 221 | } 222 | else 223 | { 224 | transform.Translate(offset.Value); 225 | transform.rotation = rotate * transform.rotation; 226 | transform.Translate(-offset.Value); 227 | } 228 | } 229 | 230 | public override string ToString() 231 | { 232 | return transform.ToString(); 233 | } 234 | } 235 | } 236 | 237 | } -------------------------------------------------------------------------------- /Source/UnityUtils.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using UnityEngine; 3 | 4 | namespace KSPAPIExtensions 5 | { 6 | public static class UnityUtils 7 | { 8 | /// 9 | /// Formats a quarternion as an axis and rotation angle about the axis. Useful for debugging quarternions. 10 | /// 11 | /// The quarternion 12 | /// Number format for the constituent values 13 | /// The formatted string 14 | public static string ToStringAngleAxis(this Quaternion q, string format = "F3") 15 | { 16 | Vector3 axis; 17 | float angle; 18 | q.ToAngleAxis(out angle, out axis); 19 | return "(axis:" + axis.ToString(format) + " angle: " + angle.ToString(format) + ")"; 20 | } 21 | 22 | /// 23 | /// Find decendant transform / game object with the specified name. 24 | /// 25 | /// Parent transform 26 | /// Name to search for 27 | /// If true, inactive transforms are ignored 28 | /// 29 | 30 | public static Transform FindDecendant(this Transform t, string name, bool activeOnly = false) 31 | { 32 | if (t.name == name && (!activeOnly || t.gameObject.activeSelf)) 33 | return t; 34 | 35 | if (activeOnly && !t.gameObject.activeInHierarchy) 36 | return null; 37 | 38 | for (int i = 0; i < t.childCount; ++i) 39 | { 40 | if (FindDecendant(t.GetChild(i), name, activeOnly) is Transform ret) 41 | return ret; 42 | } 43 | 44 | return null; 45 | } 46 | } 47 | /// 48 | /// Holds all the bits and pieces for a mesh without the checking code. 49 | /// Useful when in the process of creating dynamic meshes. 50 | /// 51 | public class UncheckedMesh 52 | { 53 | public readonly int nVrt; 54 | public readonly int nTri; 55 | 56 | public readonly Vector3[] vertices; 57 | public readonly Vector3[] normals; 58 | public readonly Vector4[] tangents; 59 | public readonly Vector2[] uv; 60 | public readonly int[] triangles; 61 | 62 | /// 63 | /// Create a new unchecked mesh 64 | /// 65 | /// Number of vertexes 66 | /// Number of triangles 67 | public UncheckedMesh(int nVrt, int nTri) 68 | { 69 | this.nVrt = nVrt; 70 | this.nTri = nTri; 71 | 72 | vertices = new Vector3[nVrt]; 73 | normals = new Vector3[nVrt]; 74 | tangents = new Vector4[nVrt]; 75 | uv = new Vector2[nVrt]; 76 | 77 | triangles = new int[nTri * 3]; 78 | } 79 | 80 | /// 81 | /// Write the mesh data to the given mesh. 82 | /// 83 | /// Mesh to write into 84 | /// Name for the mesh 85 | public void WriteTo(Mesh mesh, string name = null) 86 | { 87 | mesh.Clear(); 88 | if (name != null) 89 | mesh.name = name; 90 | mesh.vertices = vertices; 91 | mesh.normals = normals; 92 | mesh.tangents = tangents; 93 | mesh.uv = uv; 94 | mesh.triangles = triangles; 95 | } 96 | 97 | /// 98 | /// Create a new mesh object with the mesh data as current. 99 | /// 100 | /// Name of the mesh 101 | /// The new mesh 102 | public Mesh AsMesh(string name = null) 103 | { 104 | Mesh mesh = new Mesh(); 105 | WriteTo(mesh, name); 106 | return mesh; 107 | } 108 | 109 | /// 110 | /// Dump the mesh as a string, useful for debugging. 111 | /// 112 | /// Mesh as string 113 | public string DumpMesh() 114 | { 115 | StringBuilder sb = new StringBuilder().AppendLine(); 116 | for (int i = 0; i < vertices.Length; ++i) 117 | { 118 | sb 119 | .Append(vertices[i].ToString("F4")).Append(", ") 120 | .Append(uv[i].ToString("F4")).Append(", ") 121 | .Append(normals[i].ToString("F4")).Append(", ") 122 | .Append(tangents[i].ToString("F4")).AppendLine(); 123 | } 124 | sb.Replace("(", "").Replace(")", ""); 125 | sb.AppendLine(); 126 | 127 | for (int i = 0; i < triangles.Length; i += 3) 128 | { 129 | sb 130 | .Append(triangles[i]).Append(',') 131 | .Append(triangles[i + 1]).Append(',') 132 | .Append(triangles[i + 2]).AppendLine(); 133 | } 134 | 135 | return sb.ToString(); 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /Source/UpgradePipeline.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using SaveUpgradePipeline; 4 | using UnityEngine; 5 | 6 | namespace ProceduralParts 7 | { 8 | [UpgradeModule(LoadContext.SFS | LoadContext.Craft, sfsNodeUrl = "GAME/FLIGHTSTATE/VESSEL/PART", craftNodeUrl = "PART")] 9 | public class ShapeBezierConeUpgrade : UpgradeScript 10 | { 11 | public override string Name { get => "ProceduralParts 2.1 Bezier Cone Upgrader"; } 12 | public override string Description { get => "Updates ProceduralParts Bezier Shapes to Custom Settings"; } 13 | public override Version EarliestCompatibleVersion { get => new Version(0, 0, 0); } 14 | public override Version TargetVersion { get => new Version(2, 1, 0); } 15 | 16 | public override TestResult OnTest(ConfigNode node, LoadContext loadContext, ref string nodeName) 17 | { 18 | nodeName = NodeUtil.GetPartNodeNameValue(node, loadContext); 19 | TestResult res = TestResult.Pass; 20 | if (node.GetNode("MODULE", "name", "ProceduralShapeBezierCone") is ConfigNode bezierNode) 21 | res = bezierNode.HasValue("shapePoints") ? TestResult.Pass : TestResult.Upgradeable; 22 | return res; 23 | } 24 | 25 | public override void OnUpgrade(ConfigNode node, LoadContext loadContext, ConfigNode parentNode) 26 | { 27 | string selectedShape = "Custom"; 28 | Vector4 shapePoints = Vector4.zero; 29 | var bezierNode = node.GetNode("MODULE", "name", "ProceduralShapeBezierCone"); 30 | if (bezierNode.TryGetValue("selectedShape", ref selectedShape) 31 | && ProceduralShapeBezierCone.shapePresets.Values.FirstOrDefault(x => x.displayName.Equals(selectedShape)) is var preset) 32 | { 33 | selectedShape = preset.name; 34 | shapePoints = preset.points; 35 | } 36 | bezierNode.SetValue("selectedShape", selectedShape, true); 37 | bezierNode.SetValue("shapePoints", shapePoints, true); 38 | Debug.Log($"[ProceduralParts] UpgradePipeline context {loadContext} updated part {NodeUtil.GetPartNodeNameValue(node, loadContext)} to {selectedShape}: {shapePoints}"); 39 | } 40 | } 41 | 42 | public class ShapeBezierConeUpgrade_KCTBase : ShapeBezierConeUpgrade 43 | { 44 | public override string Name { get => "ProceduralParts 2.1 Bezier Cone Upgrader KCT-" + nodeUrlSFS; } 45 | public override TestResult OnTest(ConfigNode node, LoadContext loadContext, ref string nodeName) => 46 | loadContext == LoadContext.Craft ? TestResult.Pass : base.OnTest(node, loadContext, ref nodeName); 47 | } 48 | 49 | [UpgradeModule(LoadContext.SFS, sfsNodeUrl = "GAME/SCENARIO/KSC/VABList/KCTVessel/ShipNode/PART", craftNodeUrl = "PART")] 50 | public class ShapeBezierConeUpgrade_KCT1 : ShapeBezierConeUpgrade_KCTBase { } 51 | 52 | [UpgradeModule(LoadContext.SFS, sfsNodeUrl = "GAME/SCENARIO/KSC/SPHList/KCTVessel/ShipNode/PART", craftNodeUrl = "PART")] 53 | public class ShapeBezierConeUpgrade_KCT2 : ShapeBezierConeUpgrade_KCTBase { } 54 | 55 | [UpgradeModule(LoadContext.SFS, sfsNodeUrl = "GAME/SCENARIO/KSC/VABWarehouse/KCTVessel/ShipNode/PART", craftNodeUrl = "PART")] 56 | public class ShapeBezierConeUpgrade_KCT3 : ShapeBezierConeUpgrade_KCTBase { } 57 | 58 | [UpgradeModule(LoadContext.SFS, sfsNodeUrl = "GAME/SCENARIO/KSC/SPHWarehouse/KCTVessel/ShipNode/PART", craftNodeUrl = "PART")] 59 | public class ShapeBezierConeUpgrade_KCT4 : ShapeBezierConeUpgrade_KCTBase { } 60 | 61 | [UpgradeModule(LoadContext.SFS, sfsNodeUrl = "GAME/SCENARIO/KSC/VABPlans/KCTVessel/ShipNode/PART", craftNodeUrl = "PART")] 62 | public class ShapeBezierConeUpgrade_KCT5 : ShapeBezierConeUpgrade_KCTBase { } 63 | 64 | [UpgradeModule(LoadContext.SFS, sfsNodeUrl = "GAME/SCENARIO/KSC/SPHPlans/KCTVessel/ShipNode/PART", craftNodeUrl = "PART")] 65 | public class ShapeBezierConeUpgrade_KCT6 : ShapeBezierConeUpgrade_KCTBase { } 66 | } 67 | -------------------------------------------------------------------------------- /Source/VectorUtils.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace ProceduralParts 4 | { 5 | public static class VectorUtils 6 | { 7 | 8 | public static Vector3 xz(this Vector3 v) 9 | { 10 | return new Vector3(v.x, 0, v.z); 11 | } 12 | 13 | public static Vector4 toVec4(this Vector3 v, float w) 14 | { 15 | return new Vector4(v.x, v.y, v.z, w); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /convertBB.sh: -------------------------------------------------------------------------------- 1 | #:/bin/sh 2 | 3 | cat ForumPost.bb | 4 | sed 's:\[SIZE=4\]\[B\]\(.*\)\[/B\]\[/SIZE\]:## \1:I' | \ 5 | sed 's:\[SIZE=3\]\[B\]\(.*\)\[/B\]\[/SIZE\]:#### \1:I' | \ 6 | sed 's:^\[\*\]\s*:* :' | \ 7 | sed '/\[\/*[Ll][Ii][Ss][Tt]\]/d' | \ 8 | sed '/\[\/*[Ss][Pp][Oo][Ii][Ll][Ee][Rr]\(=.*\)*\]/d' | \ 9 | sed 's:\[\/*CODE\]:~~~~:I' | \ 10 | sed 's:\[b\]\(.*\)\[/b\]:**\1**:I' | \ 11 | sed 's:\[i\]\(.*\)\[/i\]:_\1_:I' | \ 12 | sed 's:\[s\]\(.*\)\[/s\]:~~\1~~:I' | \ 13 | sed 's:\[URL=\"\(.*\)\"\]\(.*\)\[/URL\]:[\2]\(\1\):I' | \ 14 | sed 's:\[IMG\]\(.*\)\[/IMG\]:\![image]\(\1\):I' > README.md 15 | -------------------------------------------------------------------------------- /version-gen: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | use 5.010; 3 | use strict; 4 | use warnings; 5 | use autodie; 6 | use FindBin qw($Bin); 7 | use JSON::PP; 8 | use Tie::IxHash; 9 | 10 | # Write various version things for ProceduralParts. 11 | # Paul Fenwick, January 2015. 12 | # This code is CC-0 licensed. You can use it for anything, without attribution. 13 | 14 | # This requires JSON::PP to run, which comes with Perl since v5.14, or can be 15 | # installed with `cpanm JSON::PP`. 16 | 17 | my $VERSION_FILE = "GameData/ProceduralParts/ProceduralParts.version"; 18 | my $ASSEMBLY_TEMPLATE = "Source/Properties/AssemblyInfo.in"; 19 | my $ASSEMBLY_FILE = "Source/Properties/AssemblyInfo.cs"; 20 | 21 | # Fix the interface of Tie::IxHash to preserve key order 22 | sub tied_hash_ref { 23 | tie(my %hash, 'Tie::IxHash', @_); 24 | return \%hash; 25 | } 26 | 27 | # Here's our base metadata. We'll add VERSION info to this before outputting. 28 | my $metadata = tied_hash_ref( 29 | NAME => "Procedural Parts", 30 | URL => "https://raw.githubusercontent.com/KSP-RO/ProceduralParts/master/GameData/ProceduralParts/ProceduralParts.version", 31 | DOWNLOAD => "https://github.com/KSP-RO/ProceduralParts/releases", 32 | GITHUB => tied_hash_ref( 33 | USERNAME => "KSP-RO", 34 | REPOSITORY => "ProceduralParts", 35 | ALLOW_PRE_RELEASE => JSON::PP::false, 36 | ), 37 | VERSION => tied_hash_ref(), 38 | KSP_VERSION => tied_hash_ref( 39 | MAJOR => 1, 40 | MINOR => 8, 41 | PATCH => 1 42 | ), 43 | KSP_VERSION_MIN => tied_hash_ref( 44 | MAJOR => 1, 45 | MINOR => 8, 46 | PATCH => 1 47 | ), 48 | KSP_VERSION_MAX => tied_hash_ref( 49 | MAJOR => 1, 50 | MINOR => 12, 51 | PATCH => 99 52 | ), 53 | ); 54 | 55 | chdir($Bin); 56 | 57 | my $version = `git describe --tags --long --match "v*"`; 58 | chomp($version); 59 | 60 | if ($version !~ m{ 61 | # Parse a version in the form v1.2.3-4 62 | ^v 63 | (?\d+)\. 64 | (?\d+)\. 65 | (?\d+) 66 | (-pre)?- 67 | (?\d+) 68 | }x) { 69 | die "Cannot parse $version as a version!"; 70 | } 71 | 72 | my $assembly_version = "$+{major}.$+{minor}.$+{patch}.$+{build}"; 73 | my $assembly_version_major = "$+{major}"; 74 | my $assembly_version_minor = "$+{minor}"; 75 | my $assembly_version_major_first = "$+{major}.0.0.0"; 76 | 77 | say "Writing metadata for version $assembly_version"; 78 | 79 | # Using `int` below forces Perl to internally represent these as numbers, 80 | # even though they were the result of a string operation. This means no 81 | # unsightly quotes in the output JSON. 82 | $metadata->{VERSION} = tied_hash_ref( 83 | MAJOR => int $+{major}, 84 | MINOR => int $+{minor}, 85 | PATCH => int $+{patch}, 86 | # If used, AVC could try to get the user to 87 | # install git builds, which we don't want. 88 | BUILD => 0 89 | ); 90 | 91 | # Write our AVC metadata 92 | open(my $version_fh, '>', $VERSION_FILE); 93 | print {$version_fh} JSON::PP->new->indent->indent_length(4)->space_after->encode( $metadata ); 94 | close $version_fh; 95 | 96 | # Write our AssemblyInfo 97 | open(my $template_fh, '<', $ASSEMBLY_TEMPLATE); 98 | open(my $assembly_fh, '>', $ASSEMBLY_FILE); 99 | 100 | while (<$template_fh>) { 101 | s{\@VERSION\@}{$assembly_version}; 102 | s{\@VERSION_MAJOR_FIRST\@}{$assembly_version_major_first}; 103 | s{\@VERSION_MAJOR\@}{$assembly_version_major}; 104 | s{\@VERSION_MINOR\@}{$assembly_version_minor}; 105 | print {$assembly_fh} $_; 106 | } 107 | 108 | close($template_fh); 109 | close($assembly_fh); 110 | --------------------------------------------------------------------------------