protected override void OnUpdate()
        {
            base.OnUpdate();
            if (HighLogic.LoadedSceneIsFlight == false)
            {
                return;
            }
            if (State == ParameterState.Complete || State == ParameterState.Failed)
            {
                return;
            }
            if (ferryParam == null)
            {
                ferryParam = GetParameter <WBIFerryKerbalParam>();
            }
            if (ferryParam == null)
            {
                return;
            }
            if (ferryParam.State == ParameterState.Complete && !isAtLocation)
            {
                isAtLocation = true;
                ResetTimer();
            }
            else if (ferryParam.State == ParameterState.Incomplete)
            {
                isAtLocation = false;
                return;
            }

            //Calculate elapsed time
            double elapsedTime = Planetarium.GetUniversalTime() - lastUpdate;

            lastUpdate = Planetarium.GetUniversalTime();

            //Update the stay time
            timeRemaining -= elapsedTime;
            if (timeRemaining <= 0.0001)
            {
                timeRemaining = 0f;
                WBIContractScenario.Instance.registerKerbal(kerbalName);
                SetComplete();
            }
            else
            {
                SetIncomplete();
            }

            //GUI update
            GameEvents.Contract.onParameterChange.Fire(Root, this);
        }
        protected override bool Generate()
        {
            int contractCount = WBIContractScenario.Instance.GetContractCount(ContractType);

            Log("Trying to generate a WBIColonistContract, count: " + contractCount + "/" + WBIContractScenario.maxContracts);
            if (contractCount == WBIContractScenario.maxContracts)
            {
                return(false);
            }

            //Find destination candidates
            if (destinationCandidates.Count == 0)
            {
                getDestinationCandidates();
            }
            if (destinationCandidates.Count == 0)
            {
                return(false);
            }

            //Determine which candidate to use
            int    candidateID  = UnityEngine.Random.Range(0, destinationCandidates.Count);
            Vessel targetVessel = destinationCandidates[candidateID];

            vesselName = targetVessel.vesselName;
            targetBody = targetVessel.mainBody;
            Log("Target vessel: " + vesselName);
            Log("Target body: " + targetBody);

            bool isOrbiting = false;

            if (targetVessel.situation == Vessel.Situations.ORBITING)
            {
                isOrbiting = true;
            }

            //Generate number of tourists
            totalTourists = UnityEngine.Random.Range(1, MaxTourists) * ((int)prestige + 1);
            Log("totalTourists: " + totalTourists);

            //Generate total days
            totalDays = UnityEngine.Random.Range(minimumDays, maximumDays) * ((int)prestige + 1);
            Log("totalDays: " + totalDays);

            //Calculate completion funds
            float deliveryFunds;
            float stayFunds;
            float totalFunds;

            if (!isOrbiting)
            {
                deliveryFunds = fundsFerryComplete * targetBody.scienceValues.LandedDataValue;
                stayFunds     = fundsStayComplete * (float)totalDays * targetBody.scienceValues.LandedDataValue;
                totalFunds    = fundsCompleteBase * targetBody.scienceValues.LandedDataValue;
            }
            else
            {
                deliveryFunds = fundsFerryComplete * targetBody.scienceValues.InSpaceLowDataValue;
                stayFunds     = fundsStayComplete * (float)totalDays * targetBody.scienceValues.InSpaceLowDataValue;
                totalFunds    = fundsCompleteBase * targetBody.scienceValues.InSpaceLowDataValue;
            }
            stayFunds  *= ((float)prestige + 1.0f);
            totalFunds *= ((float)prestige + 1.0f);

            //Be in command of <targetVessel> parameter
            SpecificVesselParameter specificVesselParam = new SpecificVesselParameter(targetVessel);

            this.AddParameter(specificVesselParam, null);

            //Generate kerbals
            WBIFerryKerbalParam ferryParameter;
            WBIKerbalStayParam  stayParameter;
            KerbalRoster        roster = HighLogic.CurrentGame.CrewRoster;

            kerbalNames.Clear();
            for (int index = 0; index < totalTourists; index++)
            {
                tourist = createTourist();

                //Stay at vessel parameter
                stayParameter = new WBIKerbalStayParam(vesselName, tourist.name, totalDays);
                this.AddParameter(stayParameter, null); //Do this before setting other things in the parameter
                stayParameter.SetFunds(stayFunds, targetBody);

                //Ferry to vessel parameter
                ferryParameter = new WBIFerryKerbalParam(vesselName, tourist.name);
                stayParameter.AddParameter(ferryParameter, null);
                ferryParameter.SetFunds(deliveryFunds, targetBody);

                //Record funds
                totalFunds += stayFunds + deliveryFunds;

                //Clean up the roster- we only generate tourists when the contract is accepted.
                kerbalNames.Add(tourist.name);
                roster.Remove(tourist.name);
            }

            //Set rewards
            base.SetExpiry();
            base.SetDeadlineYears(10f, targetBody);
            base.SetReputation(repComplete, repFailure, targetBody);
            base.SetFunds(fundsAdvance, totalFunds, totalFunds * 0.25f, targetBody);

            //Record contract
            contractCount += 1;
            if (contractCount > WBIContractScenario.maxContracts)
            {
                contractCount = WBIContractScenario.maxContracts;
            }
            WBIContractScenario.Instance.SetContractCount(ContractType, contractCount);

            //Done
            if (string.IsNullOrEmpty(contractID))
            {
                contractID = Guid.NewGuid().ToString();
            }
            return(true);
        }