Esempio n. 1
0
            /// <summary>
            /// Calculates whether the dialog or any of its transferable items have changed since last remembered,
            /// and records the new state if there were changes
            /// </summary>
            public static bool HasChanged(RimWorld.Dialog_FormCaravan dialogInstance)
            {
                if (dialogInstance == null)
                {
                    Mod.LogError("Dialog instance was null");
                    return(true);
                }

                var hasChanged = false;

                if (lastDialogInstance != dialogInstance)
                {
                    Mod.LogTrace("Dialog instance changed");
                    hasChanged = true;
                }

                var transferablesHash = CalculateTransferablesHash(dialogInstance.transferables);

                if (transferablesHash != lastTransferablesHash)
                {
                    Mod.LogTrace("Transferables list changed");
                    hasChanged = true;
                }

                if (hasChanged)
                {
                    Remember(dialogInstance, transferablesHash);
                }

                return(hasChanged);
            }
Esempio n. 2
0
        static void CheckForErrors_Postfix(RimWorld.Dialog_FormCaravan __instance, ref bool __result,
                                           ref bool ___massUsageDirty, List <Pawn> pawns)
        {
            // Don't intevene if only closing dialog to choose route
            if (__instance.choosingRoute)
            {
                return;
            }

            // Don't intervene if other errors are already preventing the dialog from closing
            if (!__result)
            {
                return;
            }

            // Errors are evaluated a second time before rendering confirmation, for some reason... ignore that call
            var stackFrame    = new StackFrame(1);
            var callingMethod = stackFrame.GetMethod();

            if (callingMethod.Name == "DoBottomButtons")
            {
                return;
            }

            // Inject bedroll check after other error validation
            Mod.LogTrace("Postfixing Dialog_FormCaravan.CheckForErrors");
            __result          = CaravanBedrollHelper.CheckBeforeClosing(__instance, pawns);
            ___massUsageDirty = true;
        }
Esempio n. 3
0
            public static void Remember(RimWorld.Dialog_FormCaravan dialogInstance)
            {
                if (dialogInstance == null)
                {
                    Forget();
                    return;
                }

                var transferablesHash = CalculateTransferablesHash(dialogInstance.transferables);

                Remember(dialogInstance, transferablesHash);
            }
Esempio n. 4
0
        /// <summary>
        /// Checks if more bedrolls are needed for the caravan, and adds them if appropriate
        /// </summary>
        /// <returns>
        /// Whether to proceed with sending the caravan
        /// </returns>
        public static bool CheckBeforeClosing(RimWorld.Dialog_FormCaravan dialogInstance, List <Pawn> pawns)
        {
            var neededBedrolls = GetNeededBedrolls(dialogInstance.transferables, pawns);

            if (neededBedrolls.Count <= 0)
            {
                return(true);
            }

            var neededMass = GetNeededMass(neededBedrolls);

            Mod.LogTrace($"Need {neededMass} mass capacity for bedrolls");

            var availableMass = GetAvailableMass(dialogInstance);

            Mod.LogTrace($"Have {availableMass} mass capacity available");

            // Don't push the caravan over its mass limit
            if (neededMass > availableMass)
            {
                if (State.HasChanged(dialogInstance))
                {
                    // If the first time or if loadout changed, warn user and abort departure
                    Messages.Message(
                        $"Adding {neededBedrolls.Count} bedrolls would put caravan over weight by {neededMass - availableMass}. Accept or Confirm to leave as-is, or make changes to the caravan packing list to trigger re-processing.",
                        MessageTypeDefOf.RejectInput, false);

                    return(false);
                }
                else
                {
                    // If trying the same thing twice in a row, allow caravan to leave without bedrolls
                    State.Forget();
                    return(true);
                }
            }

            // Add needed bedrolls and leave
            if (neededBedrolls.Any())
            {
                foreach (var neededBedroll in neededBedrolls)
                {
                    neededBedroll.Key.AdjustBy(neededBedroll.Value);
                }
                Mod.LogMessage("Successfully added additional bedrolls");
                Messages.Message($"Successfully added {neededBedrolls.Count} bedrolls to caravan.", MessageTypeDefOf.RejectInput, false);
            }
            State.Forget();
            return(true);
        }
Esempio n. 5
0
 public static void Forget()
 {
     lastDialogInstance    = null;
     lastTransferablesHash = 0;
 }
Esempio n. 6
0
 private static void Remember(RimWorld.Dialog_FormCaravan dialogInstance, int transferablesHash)
 {
     lastDialogInstance    = dialogInstance;
     lastTransferablesHash = transferablesHash;
 }
Esempio n. 7
0
 public static float GetAvailableMass(RimWorld.Dialog_FormCaravan dialogInstance) =>
 dialogInstance.MassCapacity - dialogInstance.MassUsage;