Tw1

How to make a part only work when submerged

Recommended Posts

Posted (edited)

 

I have a very old water propeller mod (not mine) which I've been using and tweaking over the years. But a few years ago, KSP finally changed too much, and it stopped working. I've made it work again. (sorta) using firespitter to make it spin, and the stock ModuleEngineFx to give it thrust, but naturally, it gives thrust no matter the situation. MHvUMgG.png

I would like it to not produce thrust when the part isn't touching water. (Or at least if the center isn't in water). Is there a way, using either the stock modules or a common mod, to stop all thrust when not in water? 

If you wish to have a look, here's the part from the original mod. 

https://drive.mobisystems.com/sharelink/MXRob21hc3dhbGRlcjFAZ21haWwuY29t.4PhGMvOM0JvBC82MNKQ4NC?fbclid=IwAR2KLxx1W_BpwTv_y-bW-eReiRMnDfBMzdqHF4iUADrbM_V0N9Kcuu8hH3Q

This should be the version I bodged to make work, but I might have the links the wrong way around. 

https://drive.mobisystems.com/sharelink/MXRob21hc3dhbGRlcjFAZ21haWwuY29t.2XnRPiVswqDrVbGTDKusoh?fbclid=IwAR0eicn8gcEJEQWO20V0lqUjpDpgmpJXfOAs6AblPMWMISbTGE-x1--NqUs

Alternatively, if you are able to, this is the source code from the original mod: Perhaps something here could be salvaged to make it work again? It also didn't support action groups, which was a bit of a downside...
But even then perhaps someone could get this to work with modern KSP?

 

Spoiler

===Version .2====

Change Log-
Modified steering code to be more robust
Should resume from save without needing to cycle

Known issues-
	-Propellers do not "spool" if they are cut while in reverse
	-Not tested on Laythe or Eve
	-Activate via action group not supported

Tips-
	-Reverse by making the pitch "Up" past the 50% mark. By default just hold "S"
	-Negative "MaxRPM" values in CFG will make prop spin counter-clockwise (looking forward), but will also cause thrust to go backwards. To 	solve this have the Z-axis for the transform face forwards (not tested, but should work).
	



====License====
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.


====Source (For Reference)====

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using KSP.IO;
using UnityEngine;

public class ModuleSeaPropeller : PartModule
{
    ////////////////////
    //
    // Variable Declaration
    //
    ////////////////////

    private Transform tCenter;
    private bool bHasFuel;
    //private float fCurrentRPS;
    private float deltaRPS;
    //private float requestedRPS;
    private float fSpoolRate;

    [KSPField(guiActive = true,guiName = "Current RPS",isPersistant = false)]
    private float fCurrentRPS;
    [KSPField(guiActive = true, guiName = "Commanded RPS", isPersistant = false)]
    private float requestedRPS;

    [KSPField]
    public float MaxThrust;

    [KSPField]
    public float MaxRPS;

    [KSPField]
    public float SpoolTime;

    [KSPField]
    public float MaxResourceRate;

    [KSPField]
    public string thrustTransformName;

    [KSPField]
    public string resourceName;


    //Turn on off engines

    [KSPField(isPersistant = true)]
    public bool bIsActive = false;

    [KSPEvent(guiActive = true, guiName = "Activate Engine", active = true)]
    public void ToggleEngineIsActive()
    {
        Events["ToggleEngineIsActive"].active = false;
        Events["ToggleEngineIsDisabled"].active = true;
        bIsActive = true;
        fCurrentRPS = 0;
        fSpoolRate = MaxRPS / SpoolTime;
    }

    [KSPEvent(guiActive = true, guiName = "Disable Engine", active = false)]
    public void ToggleEngineIsDisabled()
    {
        Events["ToggleEngineIsActive"].active = true;
        Events["ToggleEngineIsDisabled"].active = false;
        bIsActive = false;
    }

    ////////////////////
    //
    // Update Cycle
    //
    ////////////////////

    public void FixedUpdate()
    {
        if (bIsActive && this.vessel.isActiveVessel)
        {
            if (fSpoolRate < .001)
                ToggleEngineIsActive();

            RunEngine();
        }
    }

    public void RunEngine()
    {
        requestedRPS = FlightInputHandler.state.mainThrottle * MaxRPS;
        CheckFuel();

        CheckYaw();

        CheckReverse();
        CheckRPS();

        tCenter = this.part.FindModelTransform(thrustTransformName);
        AnimateEngine();

        if (this.part.WaterContact)
        {
            part.Rigidbody.AddForceAtPosition(-tCenter.forward * (fCurrentRPS/MaxRPS) * MaxThrust, tCenter.position);
            //part.Rigidbody.AddForceAtPosition(-tCenter.forward * FlightInputHandler.state.mainThrottle * MaxThrust / 60, tCenter.position);
        }
    }

    public void AnimateEngine()
    {
        tCenter.transform.RotateAround(tCenter.forward, fCurrentRPS * TimeWarp.fixedDeltaTime);
    }

    public void CheckFuel()
    {
        bHasFuel = false;
        if(this.part.RequestResource(resourceName, MaxResourceRate * FlightInputHandler.state.mainThrottle * TimeWarp.fixedDeltaTime) >0)
        {
            bHasFuel = true;
        }
    }

    public void CheckRPS()
    {
        deltaRPS = requestedRPS - fCurrentRPS;
        int iCaseSwitch = 0;

        //following two statements will regulate prop spool
        if (deltaRPS > .05 * fSpoolRate)
            iCaseSwitch = 1;

        if (deltaRPS < -.05 * fSpoolRate)
            iCaseSwitch = -1;

        if (bHasFuel == false)
            iCaseSwitch = -2;

        switch (iCaseSwitch)
        {
            case 1: //prop needs to speed up, restricted
                fCurrentRPS = fCurrentRPS + fSpoolRate * TimeWarp.fixedDeltaTime;
                //check to ensure no overshoot
                if (fCurrentRPS > requestedRPS)
                    fCurrentRPS = requestedRPS;
                break;

            case 0: //no difference
                fCurrentRPS = requestedRPS;
                break;

            case -1: //prop needs to slow down, restricted
                fCurrentRPS = fCurrentRPS - fSpoolRate * TimeWarp.fixedDeltaTime;
                //check to ensure no overshoot
                if (fCurrentRPS < requestedRPS) //sudden stop when engine spinning reverse
                    fCurrentRPS = requestedRPS;
                break;

            case -2: //prop needs to slow down, restricted
                fCurrentRPS = fCurrentRPS - fSpoolRate * TimeWarp.fixedDeltaTime * 1.5f;
                //check to ensure no overshoot
                if (fCurrentRPS < requestedRPS)
                    fCurrentRPS = requestedRPS;
                break;
        }
    }

    public void CheckYaw()
    {
        //this commented block worked okay in .1, could be improved
        //if (Mathf.Abs(FlightInputHandler.state.yaw) < .01)
        //    return;

        //if (FlightInputHandler.state.yaw > -0.1) //inside engine, sharp turn right
        //{
        //    if (Mathf.Sign(this.part.orgPos.x) == 1 && Mathf.Abs(this.part.orgPos.x) > .5)
        //    requestedRPS =  -(Mathf.Abs(FlightInputHandler.state.yaw) - .5f) * 2;
        //}
        //if (FlightInputHandler.state.yaw < 0.1) //inside engine, sharp turn left
        //{
        //    if (Mathf.Sign(this.part.orgPos.x) == -1 && Mathf.Abs(this.part.orgPos.x) > .5)
        //        requestedRPS = -(Mathf.Abs(FlightInputHandler.state.yaw) - .5f) * 2;
        //}



        if (Mathf.Abs(FlightInputHandler.state.yaw) < .01)
            return;

        if (FlightInputHandler.state.yaw > -0.1) //inside engine, sharp turn right
        {
            //if (Mathf.Sign(this.part.orgPos.x) == 1 && Mathf.Abs(this.part.orgPos.x) > .5)
            if (this.part.transform.InverseTransformPoint(vessel.CoM).x > .5f)
                requestedRPS = -(Mathf.Abs(FlightInputHandler.state.yaw) - .5f) * 2 * MaxRPS;
        }
        if (FlightInputHandler.state.yaw < 0.1) //inside engine, sharp turn left
        {
            //if (Mathf.Sign(this.part.orgPos.x) == -1 && Mathf.Abs(this.part.orgPos.x) > .5)
            if (this.part.transform.InverseTransformPoint(vessel.CoM).x < -.5f)
                requestedRPS = -(Mathf.Abs(FlightInputHandler.state.yaw) - .5f) * 2 * MaxRPS;
        }


        //constrain to maxRPS
        if (requestedRPS > MaxRPS)
            requestedRPS = MaxRPS;

        if (requestedRPS < -MaxRPS)
            requestedRPS = -MaxRPS;
    }

    public void CheckReverse()
    {
        if (FlightInputHandler.state.pitch > .5)
        {
            requestedRPS = -requestedRPS;
            if (requestedRPS > 0)
                requestedRPS = 0;
        }   
    }
}

 

 

 

Edited by Tw1

Share this post


Link to post
Share on other sites

this may or may not help - but from Snark - MM patch

Spoiler
// Disable all jet intakes if they're underwater.
// (It's possible to disable jet engines the same way, but I figure that's
// OK as long as they have intakes that are out of the water.)
 
@PART[*]:HAS[@MODULE[ModuleResourceIntake]]
{
@description ^= :^(.+)$:$0 Does not work underwater.:
@MODULE[ModuleResourceIntake]
{
%disableUnderwater = true
}

}

 

Share this post


Link to post
Share on other sites

This is pretty much what I want, but the other way around. It sounds like it might work on the engines too, it also does sound like it can check if things are under water..

Share this post


Link to post
Share on other sites

One possible place to look for all the "hidden" fields (those that are usually left at default) is the KSP documentation - more of a API listing but still some good info. Look for the Public Attributes - many are settable in the config.

Share this post


Link to post
Share on other sites

Join the conversation

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

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

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

×   Your previous content has been restored.   Clear editor

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