Exemple #1
0
 /// <summary>Handles keyboard input.</summary>
 private void UpdateKey()
 {
     if (isRunning)
     {
         if (KIS_Shared.IsKeyUp(KeyCode.Escape) || KIS_Shared.IsKeyDown(KeyCode.Return))
         {
             DebugEx.Fine("Cancel key pressed, stop eva attach mode");
             CancelPointer(this);
         }
         if (GameSettings.Editor_toggleSymMethod.GetKeyDown()) // "R" by default.
         {
             if (pointerTarget != PointerTarget.PartMount && attachNodes.Count() > 1)
             {
                 if (attachNodeIndex < attachNodes.Count - 1)
                 {
                     attachNodeIndex++;
                 }
                 else
                 {
                     attachNodeIndex = 0;
                 }
                 DebugEx.Fine("Attach node index changed to: {0}", attachNodeIndex);
                 ResetMouseOver();
                 SendPointerState(pointerTarget, PointerState.OnChangeAttachNode, null, null);
             }
             else
             {
                 ScreenMessaging.ShowInfoScreenMessage(OnlyOneAttachNodeMsg);
                 UISounds.PlayBipWrong();
             }
         }
     }
 }
        /// <summary>
        /// Refuels kerbal's EVA pack up to the maximum, and decreases canister reserve.
        /// </summary>
        /// <param name="item">Item to get fuel from.</param>
        protected virtual void RefillEVAPack(KIS_Item item)
        {
            var canisterFuelResource = GetCanisterFuelResource(item);
            var evaFuelResource      = item.inventory.part.Resources.Get(
                item.inventory.part.GetComponent <KerbalEVA>().propellantResourceName);
            var needsFuel = evaFuelResource.maxAmount - evaFuelResource.amount;

            if (needsFuel < double.Epsilon)
            {
                ScreenMessaging.ShowPriorityScreenMessage(NoNeedToRefillMsg);
            }
            else
            {
                if (canisterFuelResource.amount < double.Epsilon)
                {
                    ScreenMessaging.ShowPriorityScreenMessage(CanisterIsEmptyMsg);
                    UISounds.PlayBipWrong();
                }
                else
                {
                    var canRefuel = Math.Min(needsFuel, canisterFuelResource.amount);
                    item.UpdateResource(StockResourceNames.EvaPropellant, canisterFuelResource.amount - canRefuel);
                    evaFuelResource.amount += canRefuel;
                    if (canRefuel < needsFuel)
                    {
                        ScreenMessaging.ShowPriorityScreenMessage(NotEnoughPropellantMsg);
                    }
                    else
                    {
                        ScreenMessaging.ShowPriorityScreenMessage(JetpackRefueledMsg);
                    }
                    UISoundPlayer.instance.Play(refuelSndPath);
                }
            }
        }
Exemple #3
0
        /// <summary>Fills up canister to the maximum capacity.</summary>
        /// <param name="item">Item to refill.</param>
        void RefillCanister(KIS_Item item)
        {
            var canisterResource = GetCanisterFuelResource(item);
            var needResource     = canisterResource.maxAmount - canisterResource.amount;

            if (needResource <= double.Epsilon)
            {
                ScreenMessaging.ShowPriorityScreenMessage(NoNeedToRefillCanisterMsg);
                return;
            }
            double newAmount;

            if (_mainResourceName != StockResourceNames.EvaPropellant)
            {
                var hasAmount = item.inventory.part.RequestResource(_mainResourceName, needResource);
                if (hasAmount <= double.Epsilon)
                {
                    ScreenMessaging.ShowPriorityScreenMessage(
                        NoResourceInVesselMsg.Format(canisterResource.resourceName));
                    UISounds.PlayBipWrong();
                    return;
                }
                newAmount = canisterResource.amount + hasAmount;
                ScreenMessaging.ShowPriorityScreenMessage(
                    CanisterPartialRefilledMsg.Format(canisterResource.resourceName, hasAmount));
            }
            else
            {
                newAmount = canisterResource.maxAmount;
                ScreenMessaging.ShowPriorityScreenMessage(CanisterFullyRefilledMsg);
            }
            item.UpdateResource(_mainResourceName, newAmount);
            UISoundPlayer.instance.Play(refuelSndPath);
        }
Exemple #4
0
        /// <summary>
        /// Refuels kerbal's EVA pack up to the maximum, and decreases canister reserve.
        /// </summary>
        /// <param name="item">Item to get fuel from.</param>
        void RefillEvaPack(KIS_Item item)
        {
            var evaFuelResource = item.inventory.part.Resources.Get(StockResourceNames.EvaPropellant);
            var needsFuel       = evaFuelResource.maxAmount - evaFuelResource.amount;

            if (needsFuel < double.Epsilon)
            {
                ScreenMessaging.ShowPriorityScreenMessage(NoNeedToRefillJetpackMsg);
                return;
            }
            var canisterFuelResource = GetCanisterFuelResource(item);

            if (canisterFuelResource.amount < double.Epsilon)
            {
                ScreenMessaging.ShowPriorityScreenMessage(CanisterIsEmptyMsg);
                UISounds.PlayBipWrong();
                return;
            }
            var canRefuel = Math.Min(needsFuel, canisterFuelResource.amount);

            item.UpdateResource(_mainResourceName, -canRefuel, isAmountRelative: true);
            evaFuelResource.amount += canRefuel;
            if (canRefuel < needsFuel)
            {
                ScreenMessaging.ShowPriorityScreenMessage(JetpackPartiallyRefueledMsg.Format(canRefuel));
            }
            else
            {
                ScreenMessaging.ShowPriorityScreenMessage(JetpackFullyRefueledMsg);
            }
            UISoundPlayer.instance.Play(refuelSndPath);
        }
Exemple #5
0
 /// <summary>Handles keyboard input.</summary>
 private void UpdateKey()
 {
     if (isRunning)
     {
         if (KIS_Shared.IsKeyUp(KeyCode.Escape) || KIS_Shared.IsKeyDown(KeyCode.Return))
         {
             Debug.Log("Cancel key pressed, stop eva attach mode");
             StopPointer(unlockUI: false);
             SendPointerClick(PointerTarget.Nothing, Vector3.zero, Quaternion.identity, null, null);
             // Delay unlocking to not let ESC be handled by the game.
             AsyncCall.CallOnEndOfFrame(this, UnlockUI);
         }
         if (GameSettings.Editor_toggleSymMethod.GetKeyDown()) // "R" by default.
         {
             if (pointerTarget != PointerTarget.PartMount && attachNodes.Count() > 1)
             {
                 attachNodeIndex++;
                 if (attachNodeIndex > (attachNodes.Count - 1))
                 {
                     attachNodeIndex = 0;
                 }
                 Debug.LogFormat("Attach node index changed to: {0}", attachNodeIndex);
                 UpdatePointerAttachNode();
                 ResetMouseOver();
                 SendPointerState(pointerTarget, PointerState.OnChangeAttachNode, null, null);
             }
             else
             {
                 ScreenMessaging.ShowInfoScreenMessage(OnlyOneAttachNodeMsg);
                 UISounds.PlayBipWrong();
             }
         }
     }
 }
Exemple #6
0
        public bool CanStackAdd(float qty, bool checkVolume = true)
        {
            if (qty <= 0)
            {
                return(false);
            }
            if (equipped)
            {
                ScreenMessaging.ShowPriorityScreenMessage(CannotStackItemEquippedMsg);
                UISounds.PlayBipWrong();
                return(false);
            }
            float newVolume = inventory.totalVolume + (volume * qty);

            if (checkVolume && newVolume > inventory.maxVolume)
            {
                ScreenMessaging.ShowPriorityScreenMessage(
                    CannotStackMaxVolumeReachedMsg.Format(newVolume - inventory.maxVolume));
                return(false);
            }
            return(true);
        }
Exemple #7
0
        public bool CanStackAdd(float qty, bool checkVolume = true)
        {
            if (qty <= 0)
            {
                return(false);
            }
            if (equipped)
            {
                ScreenMessaging.ShowPriorityScreenMessage("Cannot stack with equipped item");
                UISounds.PlayBipWrong();
                return(false);
            }
            float newVolume = inventory.totalVolume + (volume * qty);

            if (checkVolume && newVolume > inventory.maxVolume)
            {
                ScreenMessaging.ShowPriorityScreenMessage("Max destination volume reached (+{0:#.####})",
                                                          newVolume - inventory.maxVolume);
                return(false);
            }
            return(true);
        }
Exemple #8
0
        public void UpdatePointer()
        {
            // Stop pointer on map
            if (running && MapView.MapIsEnabled)
            {
                StopPointer();
                return;
            }

            // Remove pointer if not running.
            if (!running)
            {
                DestroyPointer();
                return;
            }

            // Hide pointer if the raycast do not hit anything.
            if (pointerTarget == PointerTarget.Nothing)
            {
                SetPointerVisible(false);
                return;
            }

            SetPointerVisible(true);

            // Custom rotation
            float rotDegree = 15;

            if (Input.GetKey(KeyCode.LeftShift))
            {
                rotDegree = 1;
            }
            if (GameSettings.Editor_rollLeft.GetKeyDown())
            {
                customRot -= new Vector3(0, -1, 0) * rotDegree;
            }
            if (GameSettings.Editor_rollRight.GetKeyDown())
            {
                customRot += new Vector3(0, -1, 0) * rotDegree;
            }
            if (GameSettings.Editor_pitchDown.GetKeyDown())
            {
                customRot -= new Vector3(1, 0, 0) * rotDegree;
            }
            if (GameSettings.Editor_pitchUp.GetKeyDown())
            {
                customRot += new Vector3(1, 0, 0) * rotDegree;
            }
            if (GameSettings.Editor_yawLeft.GetKeyDown())
            {
                customRot -= new Vector3(0, 0, 1) * rotDegree;
            }
            if (GameSettings.Editor_yawRight.GetKeyDown())
            {
                customRot += new Vector3(0, 0, 1) * rotDegree;
            }
            if (GameSettings.Editor_resetRotation.GetKeyDown())
            {
                customRot = new Vector3(0, 0, 0);
            }
            Quaternion rotAdjust =
                Quaternion.Euler(0, 0, customRot.z) * Quaternion.Euler(customRot.x, customRot.y, 0);

            // Move to position
            if (pointerTarget == PointerTarget.PartMount)
            {
                //Mount snap
                KIS_Shared.MoveAlign(pointer.transform, pointerNodeTransform, hoveredNode.nodeTransform);
            }
            else if (pointerTarget == PointerTarget.PartNode)
            {
                //Part node snap
                KIS_Shared.MoveAlign(pointer.transform, pointerNodeTransform,
                                     hoveredNode.nodeTransform, rotAdjust);
            }
            else
            {
                KIS_Shared.MoveAlign(pointer.transform, pointerNodeTransform, hit, rotAdjust);
            }

            // Move above
            if (allowOffset)
            {
                if (pointerTarget != PointerTarget.PartMount)
                {
                    if (KIS_Shared.IsKeyDown(offsetUpKey) && aboveDistance < maxOffsetDist)
                    {
                        aboveDistance += aboveOffsetStep;
                    }
                    if (KIS_Shared.IsKeyDown(offsetDownKey) && aboveDistance > -maxOffsetDist)
                    {
                        aboveDistance -= aboveOffsetStep;
                    }
                    if (GameSettings.Editor_resetRotation.GetKeyDown())
                    {
                        aboveDistance = 0;
                    }
                    pointer.transform.position =
                        pointer.transform.position + (hit.normal.normalized * aboveDistance);
                }
            }

            //Check distance
            float sourceDist = 0;

            if (sourceTransform)
            {
                sourceDist =
                    Vector3.Distance(FlightGlobals.ActiveVessel.transform.position, sourceTransform.position);
            }
            float targetDist = Vector3.Distance(FlightGlobals.ActiveVessel.transform.position, hit.point);

            //Set color
            Color color               = colorOk;
            bool  invalidTarget       = false;
            bool  notAllowedOnMount   = false;
            bool  cannotSurfaceAttach = false;
            bool  invalidCurrentNode  = false;
            bool  itselfIsInvalid     = !allowPartItself &&
                                        partToAttach != null && partToAttach.hasIndirectChild(hoveredPart);
            bool restrictedPart =
                allowedAttachmentParts != null && !allowedAttachmentParts.Contains(hoveredPart);

            switch (pointerTarget)
            {
            case PointerTarget.Static:
            case PointerTarget.StaticRb:
                invalidTarget = !allowStatic;
                break;

            case PointerTarget.KerbalEva:
                invalidTarget = !allowEva;
                break;

            case PointerTarget.Part:
                if (allowPart)
                {
                    if (useAttachRules)
                    {
                        if (hoveredPart.attachRules.allowSrfAttach)
                        {
                            invalidCurrentNode = currentAttachNode.nodeType != AttachNode.NodeType.Surface;
                        }
                        else
                        {
                            cannotSurfaceAttach = true;
                        }
                    }
                }
                else
                {
                    invalidTarget = true;
                }
                break;

            case PointerTarget.PartMount:
                if (allowMount)
                {
                    ModuleKISPartMount pMount = hoveredPart.GetComponent <ModuleKISPartMount>();
                    var allowedPartNames      = new List <string>();
                    pMount.GetMounts().TryGetValue(hoveredNode, out allowedPartNames);
                    notAllowedOnMount =
                        partToAttach != null && !allowedPartNames.Contains(partToAttach.partInfo.name);
                    color = colorMountOk;
                }
                break;

            case PointerTarget.PartNode:
                invalidTarget = !allowStack;
                color         = colorStack;
                break;
            }

            // Handle generic "not OK" color.
            if (sourceDist > maxDist || targetDist > maxDist)
            {
                color = colorDistNok;
            }
            else if (invalidTarget || cannotSurfaceAttach || invalidCurrentNode ||
                     itselfIsInvalid || restrictedPart)
            {
                color = colorNok;
            }

            color.a = 0.5f;
            foreach (var mr in allModelRenderers)
            {
                mr.material.color = color;
            }

            //On click.
            if (Input.GetMouseButtonDown(0))
            {
                if (invalidTarget)
                {
                    ScreenMessaging.ShowInfoScreenMessage(TargetObjectNotAllowedMsg);
                    UISounds.PlayBipWrong();
                }
                else if (itselfIsInvalid)
                {
                    ScreenMessaging.ShowInfoScreenMessage(CannotAttachOnItselfMsg);
                    UISounds.PlayBipWrong();
                }
                else if (notAllowedOnMount)
                {
                    ScreenMessaging.ShowInfoScreenMessage(NotAllowedOnTheMountMsg);
                    UISounds.PlayBipWrong();
                }
                else if (cannotSurfaceAttach)
                {
                    ScreenMessaging.ShowInfoScreenMessage(TargetDoesntAllowSurfaceAttachMsg);
                    UISounds.PlayBipWrong();
                }
                else if (invalidCurrentNode)
                {
                    ScreenMessaging.ShowInfoScreenMessage(NodeNotForSurfaceAttachMsg);
                    UISounds.PlayBipWrong();
                }
                else if (sourceDist > maxDist)
                {
                    ScreenMessaging.ShowInfoScreenMessage(TooFarFromSourceMsg.Format(sourceDist, maxDist));
                    UISounds.PlayBipWrong();
                }
                else if (targetDist > maxDist)
                {
                    ScreenMessaging.ShowInfoScreenMessage(TooFarFromTargetMsg.Format(targetDist, maxDist));
                    UISounds.PlayBipWrong();
                }
                else if (restrictedPart)
                {
                    ScreenMessaging.ShowInfoScreenMessage(
                        CannotAttachToPartMsg.Format(hoveredPart.partInfo.title));
                    UISounds.PlayBipWrong();
                }
                else
                {
                    SendPointerClick(pointerTarget, pointer.transform.position, pointer.transform.rotation,
                                     hoveredPart, currentAttachNode.id, hoveredNode);
                }
            }
        }
Exemple #9
0
        public void Equip(ActorType actorType = ActorType.API)
        {
            // Only equip EVA kerbals.
            if (!prefabModule || inventory.invType != ModuleKISInventory.InventoryType.Eva)
            {
                Debug.LogWarningFormat("Cannot equip item from inventory type: {0}", inventory.invType);
                return;
            }
            if (quantity > 1)
            {
                ScreenMessaging.ShowPriorityScreenMessage(CannotEquipItemStackedMsg);
                UISounds.PlayBipWrong();
                return;
            }
            Debug.LogFormat("Equip item {0} in mode {1}", availablePart.title, equipMode);

            // Check if the skill is needed. Skip the check in the sandbox modes.
            if (HighLogic.CurrentGame.Mode != Game.Modes.SANDBOX &&
                HighLogic.CurrentGame.Mode != Game.Modes.SCIENCE_SANDBOX &&
                !String.IsNullOrEmpty(prefabModule.equipSkill))
            {
                bool skillFound = false;
                List <ProtoCrewMember> protoCrewMembers = inventory.vessel.GetVesselCrew();
                foreach (var expEffect in protoCrewMembers[0].experienceTrait.Effects)
                {
                    if (expEffect.ToString().Replace("Experience.Effects.", "") == prefabModule.equipSkill)
                    {
                        skillFound = true;
                        break;
                    }
                }
                if (!skillFound)
                {
                    if (actorType == ActorType.Player)
                    {
                        ScreenMessaging.ShowPriorityScreenMessage(
                            CannotEquipRestrictedToSkillMsg.Format(prefabModule.equipSkill));
                        UISounds.PlayBipWrong();
                    }
                    return;
                }
            }

            // Check if slot is already occupied.
            if (equipSlot != null)
            {
                KIS_Item equippedItem = inventory.GetEquipedItem(equipSlot);
                if (equippedItem != null)
                {
                    if (equippedItem.carriable && actorType == ActorType.Player)
                    {
                        ScreenMessaging.ShowPriorityScreenMessage(
                            CannotEquipAlreadyCarryingMsg.Format(equipSlot, equippedItem.availablePart.title));
                        UISounds.PlayBipWrong();
                        return;
                    }
                    equippedItem.Unequip();
                }
            }

            if (equipMode == EquipMode.Model)
            {
                GameObject modelGo = availablePart.partPrefab.FindModelTransform("model").gameObject;
                equippedGameObj = UnityEngine.Object.Instantiate(modelGo);
                foreach (Collider col in equippedGameObj.GetComponentsInChildren <Collider>())
                {
                    UnityEngine.Object.DestroyImmediate(col);
                }
                evaTransform = null;
                var skmrs = new List <SkinnedMeshRenderer>(
                    inventory.part.GetComponentsInChildren <SkinnedMeshRenderer>());
                foreach (SkinnedMeshRenderer skmr in skmrs)
                {
                    if (skmr.name != prefabModule.equipMeshName)
                    {
                        continue;
                    }
                    foreach (Transform bone in skmr.bones)
                    {
                        if (bone.name == prefabModule.equipBoneName)
                        {
                            evaTransform = bone.transform;
                            break;
                        }
                    }
                }

                if (!evaTransform)
                {
                    Debug.LogError("evaTransform not found ! ");
                    UnityEngine.Object.Destroy(equippedGameObj);
                    return;
                }
            }
            if (equipMode == EquipMode.Part || equipMode == EquipMode.Physic)
            {
                evaTransform = null;
                var skmrs = new List <SkinnedMeshRenderer>(
                    inventory.part.GetComponentsInChildren <SkinnedMeshRenderer>());
                foreach (SkinnedMeshRenderer skmr in skmrs)
                {
                    if (skmr.name != prefabModule.equipMeshName)
                    {
                        continue;
                    }
                    foreach (Transform bone in skmr.bones)
                    {
                        if (bone.name == prefabModule.equipBoneName)
                        {
                            evaTransform = bone.transform;
                            break;
                        }
                    }
                }

                if (!evaTransform)
                {
                    Debug.LogError("evaTransform not found ! ");
                    return;
                }

                var alreadyEquippedPart = inventory.part.FindChildPart(availablePart.name);
                if (alreadyEquippedPart)
                {
                    Debug.LogFormat("Part {0} already found on eva, use it as the item", availablePart.name);
                    equippedPart = alreadyEquippedPart;
                    // This magic is copied from the KervalEVA.OnVesselGoOffRails() method.
                    // There must be at least 3 fixed frames delay before updating the colliders.
                    AsyncCall.WaitForPhysics(
                        equippedPart, 3, () => false,
                        failure: () => OnEquippedPartReady(equippedPart));
                    if (equipMode == EquipMode.Part)
                    {
                        // Ensure the part doesn't have rigidbody and is not affected by physics.
                        // The part may not like it.
                        equippedPart.PhysicsSignificance = 1; // Disable physics on the part.
                        UnityEngine.Object.Destroy(equippedPart.rb);
                    }
                }
                else
                {
                    Vector3    equipPos = evaTransform.TransformPoint(prefabModule.equipPos);
                    Quaternion equipRot = evaTransform.rotation * Quaternion.Euler(prefabModule.equipDir);
                    equippedPart = KIS_Shared.CreatePart(
                        partNode, equipPos, equipRot, inventory.part, inventory.part,
                        srcAttachNodeId: "srfAttach",
                        onPartReady: OnEquippedPartReady,
                        createPhysicsless: equipMode != EquipMode.Physic);
                }
                if (equipMode == EquipMode.Part)
                {
                    equippedGameObj = equippedPart.gameObject;
                }
            }

            if (prefabModule.equipRemoveHelmet)
            {
                inventory.SetHelmet(false);
            }
            if (actorType == ActorType.Player)
            {
                UISoundPlayer.instance.Play(prefabModule.moveSndPath);
            }
            equipped = true;
            prefabModule.OnEquip(this);
        }
Exemple #10
0
        public void Equip(ActorType actorType = ActorType.API)
        {
            // Only equip EVA kerbals.
            if (!prefabModule || inventory.invType != ModuleKISInventory.InventoryType.Eva)
            {
                DebugEx.Warning("Cannot equip item from inventory type: {0}", inventory.invType);
                return;
            }
            if (quantity > 1)
            {
                ScreenMessaging.ShowPriorityScreenMessage(CannotEquipItemStackedMsg);
                UISounds.PlayBipWrong();
                return;
            }
            DebugEx.Info("Equip item: partName={0}, mode={1}", availablePart.title, equipMode);

            // Check if the skill is needed. Skip the check in the sandbox modes.
            if (HighLogic.CurrentGame.Mode != Game.Modes.SANDBOX &&
                HighLogic.CurrentGame.Mode != Game.Modes.SCIENCE_SANDBOX &&
                !String.IsNullOrEmpty(prefabModule.equipSkill))
            {
                bool skillFound = false;
                List <ProtoCrewMember> protoCrewMembers = inventory.vessel.GetVesselCrew();
                foreach (var expEffect in protoCrewMembers[0].experienceTrait.Effects)
                {
                    if (expEffect.ToString().Replace("Experience.Effects.", "") == prefabModule.equipSkill)
                    {
                        skillFound = true;
                        break;
                    }
                }
                if (!skillFound)
                {
                    if (actorType == ActorType.Player)
                    {
                        ScreenMessaging.ShowPriorityScreenMessage(
                            CannotEquipRestrictedToSkillMsg.Format(prefabModule.equipSkill));
                        UISounds.PlayBipWrong();
                    }
                    return;
                }
            }

            // Check if slot is already occupied.
            if (equipSlot != null)
            {
                KIS_Item equippedItem = inventory.GetEquipedItem(equipSlot);
                if (equippedItem != null && equippedItem != this)
                {
                    if (equippedItem.carriable && actorType == ActorType.Player)
                    {
                        ScreenMessaging.ShowPriorityScreenMessage(
                            CannotEquipAlreadyCarryingMsg.Format(equipSlot, equippedItem.availablePart.title));
                        UISounds.PlayBipWrong();
                        return;
                    }
                    equippedItem.Unequip();
                }
            }

            // Find the bone for this item to follow.
            evaTransform =
                KISAddonConfig.FindEquipBone(inventory.part.transform, prefabModule.equipBoneName);
            if (evaTransform == null)
            {
                return; // Cannot equip!
            }
            if (equipMode == EquipMode.Model)
            {
                var modelGo = availablePart.partPrefab.FindModelTransform("model").gameObject;
                equippedGameObj = UnityEngine.Object.Instantiate(modelGo);
                equippedGameObj.transform.parent = inventory.part.transform;
                foreach (Collider col in equippedGameObj.GetComponentsInChildren <Collider>())
                {
                    UnityEngine.Object.DestroyImmediate(col);
                }
            }
            else
            {
                var alreadyEquippedPart = inventory.part.FindChildPart(availablePart.name);
                if (alreadyEquippedPart)
                {
                    DebugEx.Info("Part {0} already found on eva, use it as the item", availablePart.name);
                    equippedPart = alreadyEquippedPart;
                    // This magic is copied from the KervalEVA.OnVesselGoOffRails() method.
                    // There must be at least 3 fixed frames delay before updating the colliders.
                    AsyncCall.WaitForPhysics(
                        equippedPart, 3, () => false,
                        failure: () => OnEquippedPartReady(equippedPart));
                    if (equipMode == EquipMode.Part)
                    {
                        // Ensure the part doesn't have rigidbody and is not affected by physics.
                        // The part may not like it.
                        equippedPart.PhysicsSignificance = 1; // Disable physics on the part.
                        UnityEngine.Object.Destroy(equippedPart.rb);
                    }
                }
                else
                {
                    Vector3    equipPos = evaTransform.TransformPoint(prefabModule.equipPos);
                    Quaternion equipRot = evaTransform.rotation * Quaternion.Euler(prefabModule.equipDir);
                    equippedPart = KIS_Shared.CreatePart(
                        partNode, equipPos, equipRot, inventory.part,
                        coupleToPart: inventory.part,
                        srcAttachNodeId: "srfAttach",
                        onPartReady: OnEquippedPartReady,
                        createPhysicsless: equipMode != EquipMode.Physic);
                }
                if (equipMode == EquipMode.Part)
                {
                    equippedGameObj = equippedPart.gameObject;
                }
            }

            // Hide the stock meshes if the custom helmet is equipped.
            if (equipSlot == HelmetSlotName)
            {
                var kerbalModule = inventory.part.FindModuleImplementing <KerbalEVA>();
                if (kerbalModule.helmetTransform != null)
                {
                    for (var i = 0; i < kerbalModule.helmetTransform.childCount; i++)
                    {
                        kerbalModule.helmetTransform.GetChild(i).gameObject.SetActive(false);
                    }
                    if (equippedGameObj != null)
                    {
                        equippedGameObj.transform.parent = kerbalModule.helmetTransform;
                    }
                }
                else
                {
                    DebugEx.Warning("Kerbal model doesn't have helmet transform: {0}", inventory);
                }
            }

            if (actorType == ActorType.Player)
            {
                UISoundPlayer.instance.Play(prefabModule.moveSndPath);
            }
            equipped = true;
            prefabModule.OnEquip(this);
            inventory.StartCoroutine(AlignEquippedPart());
        }
        /// <summary>
        /// Refuels kerbal's EVA pack up to the maximum, and decreases canister reserve.
        /// </summary>
        /// <param name="item">Item to get fuel from.</param>
        void RefillEvaPack(KIS_Item item)
        {
            var p = item.inventory.part;

            if (!p.isVesselEVA)
            {
                HostedDebugLog.Error(this, "Cannot refill non-EVA kerbal");
                return;
            }
            var stockInventory = p.FindModuleImplementing <ModuleInventoryPart>();

            if (stockInventory == null)
            {
                HostedDebugLog.Error(this, "Cannot find stock inventory module");
                return;
            }
            var evaModule = p.FindModuleImplementing <KerbalEVA>();
            var propellantResourceField = evaModule.GetType()
                                          .GetField("propellantResource", BindingFlags.Instance | BindingFlags.NonPublic);

            if (propellantResourceField == null)
            {
                HostedDebugLog.Error(this, "Cannot access internal KerbalEVA logic: propellant field");
                return;
            }
            var propellantResource = propellantResourceField.GetValue(evaModule) as PartResource;

            if (propellantResource == null)
            {
                HostedDebugLog.Error(this, "Cannot access internal KerbalEVA logic: propellant field value");
                return;
            }

            var needAmount = propellantResource.maxAmount - propellantResource.amount;

            if (needAmount <= double.Epsilon)
            {
                ScreenMessaging.ShowPriorityScreenMessage(NoNeedToRefillJetpackMsg);
                return;
            }
            var canisterFuelResource = GetCanisterFuelResource(item);

            if (canisterFuelResource.amount < double.Epsilon)
            {
                ScreenMessaging.ShowPriorityScreenMessage(CanisterIsEmptyMsg);
                UISounds.PlayBipWrong();
                return;
            }
            var canProvide = Math.Min(needAmount, canisterFuelResource.amount);

            var storedResources = stockInventory.storedParts.Values.SelectMany(x => x.snapshot.resources)
                                  .Where(x => x.resourceName == StockResourceNames.EvaPropellant)
                                  .ToArray();

            if (storedResources.Length == 0)
            {
                UISounds.PlayBipWrong();
                DebugEx.Error("Unexpectedly no EVA resource parts found in: {0}", evaModule);
                return;
            }
            item.UpdateResource(_mainResourceName, -canProvide, isAmountRelative: true);
            p.TransferResource(propellantResource, canProvide, p);
            var distributeAmount = canProvide;

            for (var i = 0; i < storedResources.Length && canProvide > double.Epsilon; i++)
            {
                var resource  = storedResources[i];
                var canAccept = resource.maxAmount - resource.amount;
                if (canAccept <= double.Epsilon)
                {
                    continue;
                }
                var refillAmount = Math.Min(canAccept, distributeAmount);
                resource.amount += refillAmount;
                resource.UpdateConfigNodeAmounts();
                distributeAmount -= refillAmount;
            }
            if (canProvide < needAmount)
            {
                ScreenMessaging.ShowPriorityScreenMessage(JetpackPartiallyRefueledMsg.Format(canProvide));
            }
            else
            {
                ScreenMessaging.ShowPriorityScreenMessage(JetpackFullyRefueledMsg);
            }
            UISoundPlayer.instance.Play(refuelSndPath);
        }
Exemple #12
0
        public void Equip(ActorType actorType = ActorType.API)
        {
            // Only equip EVA kerbals.
            if (!prefabModule || !inventory.vessel.isEVA)
            {
                return;
            }
            Debug.LogFormat("Equip item {0}", this.availablePart.name);

            // Check skill if needed. Skip the check in sandbox modes.
            if (HighLogic.CurrentGame.Mode != Game.Modes.SANDBOX &&
                HighLogic.CurrentGame.Mode != Game.Modes.SCIENCE_SANDBOX &&
                !String.IsNullOrEmpty(prefabModule.equipSkill))
            {
                bool skillFound = false;
                List <ProtoCrewMember> protoCrewMembers = inventory.vessel.GetVesselCrew();
                foreach (var expEffect in protoCrewMembers[0].experienceTrait.Effects)
                {
                    if (expEffect.ToString().Replace("Experience.Effects.", "") == prefabModule.equipSkill)
                    {
                        skillFound = true;
                        break;
                    }
                }
                if (!skillFound)
                {
                    if (actorType == ActorType.Player)
                    {
                        ScreenMessaging.ShowPriorityScreenMessage(
                            "This item can only be used by a kerbal with the skill : {0}",
                            prefabModule.equipSkill);
                        UISounds.PlayBipWrong();
                    }
                    return;
                }
            }

            // Check if already carried
            if (equipSlot != null)
            {
                KIS_Item equippedItem = inventory.GetEquipedItem(equipSlot);
                if (equippedItem != null)
                {
                    if (equippedItem.carriable)
                    {
                        if (actorType == ActorType.Player)
                        {
                            ScreenMessaging.ShowPriorityScreenMessage(
                                "Cannot equip item, slot <{0}> already used for carrying {1}",
                                equipSlot, equippedItem.availablePart.title);
                            UISounds.PlayBipWrong();
                            return;
                        }
                    }
                    equippedItem.Unequip();
                }
            }

            if (equipMode == EquipMode.Model)
            {
                GameObject modelGo = availablePart.partPrefab.FindModelTransform("model").gameObject;
                equippedGameObj = UnityEngine.Object.Instantiate(modelGo);
                foreach (Collider col in equippedGameObj.GetComponentsInChildren <Collider>())
                {
                    UnityEngine.Object.DestroyImmediate(col);
                }
                evaTransform = null;
                var skmrs = new List <SkinnedMeshRenderer>(
                    inventory.part.GetComponentsInChildren <SkinnedMeshRenderer>());
                foreach (SkinnedMeshRenderer skmr in skmrs)
                {
                    if (skmr.name != prefabModule.equipMeshName)
                    {
                        continue;
                    }
                    foreach (Transform bone in skmr.bones)
                    {
                        if (bone.name == prefabModule.equipBoneName)
                        {
                            evaTransform = bone.transform;
                            break;
                        }
                    }
                }

                if (!evaTransform)
                {
                    Debug.LogError("evaTransform not found ! ");
                    UnityEngine.Object.Destroy(equippedGameObj);
                    return;
                }
            }
            if (equipMode == EquipMode.Part || equipMode == EquipMode.Physic)
            {
                evaTransform = null;
                var skmrs = new List <SkinnedMeshRenderer>(
                    inventory.part.GetComponentsInChildren <SkinnedMeshRenderer>());
                foreach (SkinnedMeshRenderer skmr in skmrs)
                {
                    if (skmr.name != prefabModule.equipMeshName)
                    {
                        continue;
                    }
                    foreach (Transform bone in skmr.bones)
                    {
                        if (bone.name == prefabModule.equipBoneName)
                        {
                            evaTransform = bone.transform;
                            break;
                        }
                    }
                }

                if (!evaTransform)
                {
                    Debug.LogError("evaTransform not found ! ");
                    return;
                }

                Part alreadyEquippedPart =
                    this.inventory.part.vessel.Parts.Find(p => p.partInfo.name == this.availablePart.name);
                if (alreadyEquippedPart)
                {
                    Debug.LogFormat("Part: {0} already found on eva", availablePart.name);
                    equippedPart = alreadyEquippedPart;
                    OnEquippedPartCoupled(equippedPart);
                }
                else
                {
                    Vector3    equipPos = evaTransform.TransformPoint(prefabModule.equipPos);
                    Quaternion equipRot = evaTransform.rotation * Quaternion.Euler(prefabModule.equipDir);
                    equippedPart = KIS_Shared.CreatePart(
                        partNode, equipPos, equipRot, this.inventory.part, this.inventory.part, null, null,
                        OnEquippedPartCoupled);
                }
                if (equipMode == EquipMode.Part)
                {
                    equippedGameObj = equippedPart.gameObject;
                }
            }

            if (prefabModule.equipRemoveHelmet)
            {
                inventory.SetHelmet(false);
            }
            if (actorType == ActorType.Player)
            {
                UISoundPlayer.instance.Play(prefabModule.moveSndPath);
            }
            equipped = true;
            prefabModule.OnEquip(this);
        }