kRPC: Control the game using C#, C++, Java, Lua, Python...

kRPC: Control the game using C#, C++, Java, Lua, Python...

7.8k Downloads

Part.DecoupledAt incorrect if decoupler stays attached.

jj314 opened this issue ยท 1 comments

commented

What happened?

If the decoupler stays attached after decoupling, Part.DecoupledAt will return the wrong stage for parts below the decoupler.

How can someone else reproduce it?

  1. Root part command pod.
  2. Attach decoupler with non explosive node to command pod.
  3. attach fuel tank to explosive node.

image

import krpc

conn = krpc.connect(name='foo')
space_center = conn.space_center
vessel = conn.space_center.active_vessel
print([(p.name, p.decouple_stage) for p in vessel.parts.all])

prints:

[('mk1pod.v2', -1), ('Decoupler.1', -1), ('fuelTankSmallFlat', -1)]

expected:

[('mk1pod.v2', -1), ('Decoupler.1', -1), ('fuelTankSmallFlat', 0)]

What is your environment?

krpc v0.5.2

Anything else we need to know?

        /// <summary>
        /// Returns the index of the stage in which the part will be decoupled, or -1 if it is never decoupled.
        /// Transversed the tree of parts from the desired part to the root, and finds the activation stage
        /// for the first decoupler that will decouple the part (the one with the highest stage number)
        /// </summary>
        public static int DecoupledAt (this Part part)
        {
            int stage = -1;
            do {
                int candidate = -1;
                var parent = part.parent;
                var decoupler = new Compatibility.ModuleDecoupler(part);

                // If the part will decouple itself from its parent, use the parts activation stage
                if (part.HasModule<LaunchClamp> ()) {
                    candidate = part.inverseStage;
                } else if (decoupler.Instance != null && decoupler.IsEnabled) {
                    if (decoupler.IsOmniDecoupler)
                        candidate = part.inverseStage;
                    else if (parent != null && decoupler.ExplosiveNode != null && decoupler.ExplosiveNode.attachedPart == parent)
                        candidate = part.inverseStage;
                }
 
               // If the part will be decoupled by its parent, use the parents activation stage
                if (candidate == -1 && parent != null) {

// I think this line needs to be added to fix it. ////////////////////////////////
                   decoupler = new Compatibility.ModuleDecoupler(parent);
//////////////////////////////////////////////////////////////////////////////////

                    if (decoupler.Instance != null) {
                        if (decoupler.IsOmniDecoupler && decoupler.IsEnabled)
                            candidate = parent.inverseStage;
                        else if (decoupler.ExplosiveNode != null && decoupler.ExplosiveNode.attachedPart == part)
                            candidate = parent.inverseStage;
                    }
                }

                stage = Math.Max (candidate, stage);
                part = part.parent;
            } while (part != null);
            return stage;
        }
commented

Seems to work ok with your suggested fix. I don't have time right now to fully test it though.

If you'd like to try it out, here is a copy of the mod with this change included:
krpc-0.5.4.zip