public static bool UpdateFlickDesignation_Prefix(Thing t)
            {
                try
                {
                    int         CGT = Find.TickManager.TicksGame;
                    CompSkyMind csm = t.TryGetComp <CompSkyMind>();
                    if (csm == null)
                    {
                        return(true);
                    }

                    //Eviter les mods qui ont des doublons sur leur Comp_PropertieFlickable (cf Vanilla truc muche)
                    if (csm.lastRemoteFlickGT == CGT)
                    {
                        return(false);
                    }

                    String txt;

                    //Si serveur principal installé sur la map alors automatisation du flick
                    if (Utils.GCATPP.isThereSkyCloudCore())
                    {
                        if (!csm.connected)
                        {
                            return(true);
                        }

                        CompFlickable cf = t.TryGetComp <CompFlickable>();
                        if (cf != null)
                        {
                            //Affichage texte
                            if (cf.SwitchIsOn)
                            {
                                txt = "ATPP_FlickDisable".Translate();
                                Utils.playVocal("soundDefSkyCloudDeviceDeactivated");
                            }
                            else
                            {
                                txt = "ATPP_FlickEnable".Translate();
                                Utils.playVocal("soundDefSkyCloudDeviceActivated");
                            }

                            MoteMaker.ThrowText(t.TrueCenter() + new Vector3(0.5f, 0f, 0.5f), t.Map, txt, Color.white, -1f);

                            cf.DoFlick();
                            csm.lastRemoteFlickGT = CGT;
                        }

                        return(false);
                    }
                    return(true);
                }
                catch (Exception e)
                {
                    Log.Message("[ATPP] FlickUtility.UpdateFlickDesignation " + e.Message + " " + e.StackTrace);
                    return(true);
                }
            }
            public static bool Listener(Pawn __instance, DamageInfo?dinfo, Hediff exactCulprit = null)
            {
                try
                {
                    if (__instance.IsSurrogateAndroid())
                    {
                        Utils.insideKillFuncSurrogate = true;

                        //Si c'est un surrogate controllé temporaire alors on le restitue a sa faction
                        CompSkyMind csm = __instance.TryGetComp <CompSkyMind>();
                        if (csm != null)
                        {
                            //Log.Message("Restitution surrogate a sa faction");
                            csm.tempHackingEnding();
                        }
                    }
                    //disconnect killed user
                    Utils.GCATPP.disconnectUser(__instance);
                    //Log.Message("YOU KILLED "+__instance.LabelCap);
                    //Is surrogate android used ?
                    if (__instance.IsSurrogateAndroid(true))
                    {
                        //Obtention controlleur
                        CompAndroidState cas = __instance.TryGetComp <CompAndroidState>();
                        if (cas == null)
                        {
                            return(true);
                        }

                        //Arret du mode de control chez le controller
                        CompSurrogateOwner cso = cas.surrogateController.TryGetComp <CompSurrogateOwner>();
                        cso.stopControlledSurrogate(__instance, false, false, true);

                        //On reset les données pour une potentiel futur resurection
                        cas.resetInternalState();
                    }


                    //Log.Message("YOU KILLED END");
                    Utils.insideKillFuncSurrogate = false;
                    return(true);
                }
                catch (Exception e)
                {
                    Log.Message("[ATPP] Pawn.Kill(Error) : " + e.Message + " - " + e.StackTrace);

                    if (__instance.IsSurrogateAndroid())
                    {
                        Utils.insideKillFuncSurrogate = false;
                    }
                    return(true);
                }
            }
        public override AcceptanceReport CanDesignateThing(Thing t)
        {
            base.CanDesignateThing(t);

            if (t is Pawn)
            {
                Pawn             cp  = (Pawn)t;
                CompSkyMind      csm = cp.TryGetComp <CompSkyMind>();
                CompAndroidState cas = cp.TryGetComp <CompAndroidState>();

                //Si pas clone ou clone deja utilisé on degage
                if (cas == null || !cas.isSurrogate || cas.surrogateController != null || csm.Infected != -1)
                {
                    return(false);
                }

                if (!Utils.GCATPP.isConnectedToSkyMind(cp))
                {
                    //Tentative connection au skymind
                    if (!Utils.GCATPP.connectUser(cp))
                    {
                        return(false);
                    }
                }

                target       = cp;
                kindOfTarget = 1;
                return(true);
            }
            else if (fromSkyCloud && (t.def.thingClass == typeof(Building_Turret) || t.def.thingClass.IsSubclassOf(typeof(Building_Turret))))
            {
                Building build = (Building)t;
                CompRemotelyControlledTurret crt = t.TryGetComp <CompRemotelyControlledTurret>();

                if (crt != null && crt.controller == null && !t.IsBrokenDown() && t.TryGetComp <CompPowerTrader>().PowerOn)
                {
                    if (!Utils.GCATPP.isConnectedToSkyMind(t))
                    {
                        //Tentative connection au skymind
                        if (!Utils.GCATPP.connectUser(t))
                        {
                            return(false);
                        }
                    }

                    target       = t;
                    kindOfTarget = 2;
                    return(true);
                }
            }

            return(false);
        }
Пример #4
0
        public static void Listener(Building_TurretGun __instance)
        {
            CompRemotelyControlledTurret crt = __instance.TryGetComp <CompRemotelyControlledTurret>();

            //Si pas de controlleur alors on ne peut pas controller la tourelle
            if (crt == null || crt.controller == null)
            {
                return;
            }
            CompSkyMind csm = __instance.TryGetComp <CompSkyMind>();

            CompSurrogateOwner csc = crt.controller.TryGetComp <CompSurrogateOwner>();

            if (csm != null && csm.connected && crt.controller != null && csc != null && csc.skyCloudHost != null && csc.skyCloudHost.Map == __instance.Map)
            {
                GenDraw.DrawLineBetween(__instance.TrueCenter(), csc.skyCloudHost.TrueCenter(), SimpleColor.Red);
            }
        }
Пример #5
0
            public static void Listener(MentalState __instance)
            {
                if (__instance.pawn.IsSurrogateAndroid())
                {
                    CompSkyMind csm = __instance.pawn.TryGetComp <CompSkyMind>();
                    if (csm == null)
                    {
                        return;
                    }

                    if (csm.Infected == 4)
                    {
                        csm.Infected = -1;
                        Hediff he = __instance.pawn.health.hediffSet.GetFirstHediffOfDef(Utils.hediffNoHost);
                        if (he == null)
                        {
                            __instance.pawn.health.AddHediff(Utils.hediffNoHost);
                        }
                    }
                }
            }
Пример #6
0
 public static void Listener(ref bool __result, Pawn kidnapper, float maxDist, ref Pawn victim, List <Thing> disallowed = null)
 {
     if (__result && victim.IsSurrogateAndroid())
     {
         CompSkyMind csm = victim.TryGetComp <CompSkyMind>();
         //On previent le fait que les attaquant kidnappes leurs propres surrogates hackés temporairement
         if (csm != null && csm.hacked == 3 && csm.hackOrigFaction == kidnapper.Faction)
         {
             if (!kidnapper.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation) || !kidnapper.Map.reachability.CanReachMapEdge(kidnapper.Position, TraverseParms.For(kidnapper, Danger.Some, TraverseMode.ByPawn, false)))
             {
                 victim   = null;
                 __result = false;
             }
             Predicate <Thing> validator = delegate(Thing t)
             {
                 Pawn pawn = t as Pawn;
                 return(pawn.RaceProps.Humanlike && pawn.Downed && pawn.Faction == Faction.OfPlayer && !(pawn.IsSurrogateAndroid() && pawn.TryGetComp <CompAndroidState>() != null && pawn.TryGetComp <CompSkyMind>().hacked == 3 && pawn.TryGetComp <CompSkyMind>().hackOrigFaction == kidnapper.Faction) && pawn.Faction.HostileTo(kidnapper.Faction) && kidnapper.CanReserve(pawn, 1, -1, null, false) && (disallowed == null || !disallowed.Contains(pawn)));
             };
             victim   = (Pawn)GenClosest.ClosestThingReachable(kidnapper.Position, kidnapper.Map, ThingRequest.ForGroup(ThingRequestGroup.Pawn), PathEndMode.OnCell, TraverseParms.For(TraverseMode.NoPassClosedDoors, Danger.Some, false), maxDist, validator, null, 0, -1, false, RegionType.Set_Passable, false);
             __result = victim != null;
         }
     }
 }
            public static void Listener(Pawn __instance, ref IEnumerable <Gizmo> __result)
            {
                try
                {
                    CompSkyMind csm = __instance.TryGetComp <CompSkyMind>();

                    //Si prisonnier et possede une VX2 on va obtenir les GIZMOS associés OU virusé
                    if (__instance.IsPrisoner || (csm != null && csm.Hacked == 1))
                    {
                        IEnumerable <Gizmo> tmp;
                        //Si posseseur d'une VX2

                        if (__instance.VXChipPresent())
                        {
                            CompSurrogateOwner cso = __instance.TryGetComp <CompSurrogateOwner>();
                            if (cso != null)
                            {
                                tmp = cso.CompGetGizmosExtra();
                                if (tmp != null)
                                {
                                    __result = __result.Concat(tmp);
                                }
                            }
                        }

                        //Si android prisonier ou virusé
                        if (__instance.IsAndroidTier())
                        {
                            CompAndroidState cas = __instance.TryGetComp <CompAndroidState>();

                            if (cas != null)
                            {
                                tmp = cas.CompGetGizmosExtra();
                                if (tmp != null)
                                {
                                    __result = __result.Concat(tmp);
                                }
                            }
                        }

                        if (csm != null && csm.Hacked == -1)
                        {
                            tmp = csm.CompGetGizmosExtra();
                            if (tmp != null)
                            {
                                __result = __result.Concat(tmp);
                            }
                        }
                    }

                    //Si animal posséder par player
                    if (__instance.IsPoweredAnimalAndroids())
                    {
                        CompAndroidState cas = null;
                        cas = __instance.TryGetComp <CompAndroidState>();
                        if (cas != null)
                        {
                            IEnumerable <Gizmo> tmp = cas.CompGetGizmosExtra();
                            if (tmp != null)
                            {
                                __result = __result.Concat(tmp);
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Log.Message("[ATPP] Pawn.GetGizmos " + e.Message + " " + e.StackTrace);
                }
            }
        protected override void FinalizeDesignationSucceeded()
        {
            base.FinalizeDesignationSucceeded();

            CompSkyMind        csm           = target.TryGetComp <CompSkyMind>();
            CompAndroidState   cas           = target.TryGetComp <CompAndroidState>();
            string             surrogateName = target.LabelShortCap;
            CompSurrogateOwner cso           = null;

            if (cas.externalController != null)
            {
                surrogateName = cas.externalController.LabelShortCap;
                cso           = cas.externalController.TryGetComp <CompSurrogateOwner>();
            }

            Lord clord        = target.GetLord();
            int  nbp          = Utils.GCATPP.getNbHackingPoints();
            int  nbpToConsume = 0;

            //Check points
            switch (hackType)
            {
            case 1:
                nbpToConsume = Settings.costPlayerVirus;
                break;

            case 2:
                nbpToConsume = Settings.costPlayerExplosiveVirus;
                break;

            case 3:
                nbpToConsume = Settings.costPlayerHackTemp;
                break;

            case 4:
                nbpToConsume = Settings.costPlayerHack;
                break;
            }

            if (nbpToConsume > nbp)
            {
                Messages.Message("ATPP_CannotHackNotEnoughtHackingPoints".Translate(), MessageTypeDefOf.NegativeEvent);
                return;
            }

            //Si faction alliée ou neutre ==> pénalitée
            if (target.Faction.RelationKindWith(Faction.OfPlayer) != FactionRelationKind.Hostile)
            {
                target.Faction.TryAffectGoodwillWith(Faction.OfPlayer, -1 * Rand.Range(5, 36));
            }

            //Application effet
            switch (hackType)
            {
            case 1:
            case 2:

                csm.Hacked = hackType;
                //Surrogate va attaquer la colonnie
                target.SetFactionDirect(Faction.OfAncients);
                LordJob_AssistColony lordJob;
                Lord lord = null;

                IntVec3 fallbackLocation;
                RCellFinder.TryFindRandomSpotJustOutsideColony(target.PositionHeld, target.Map, out fallbackLocation);

                target.mindState.Reset();
                target.mindState.duty = null;
                target.jobs.StopAll();
                target.jobs.ClearQueuedJobs();
                target.ClearAllReservations();
                if (target.drafter != null)
                {
                    target.drafter.Drafted = false;
                }

                lordJob = new LordJob_AssistColony(Faction.OfAncients, fallbackLocation);
                if (lordJob != null)
                {
                    lord = LordMaker.MakeNewLord(Faction.OfAncients, lordJob, Current.Game.CurrentMap, null);
                }

                if (clord != null)
                {
                    if (clord.ownedPawns.Contains(target))
                    {
                        clord.Notify_PawnLost(target, PawnLostCondition.IncappedOrKilled, null);
                    }
                }

                lord.AddPawn(target);

                //Si virus explosive enclenchement de la détonnation
                if (hackType == 2)
                {
                    csm.infectedExplodeGT = Find.TickManager.TicksGame + (Settings.nbSecExplosiveVirusTakeToExplode * 60);
                }
                break;

            case 3:
            case 4:
                bool    wasPrisonner = target.IsPrisoner;
                Faction prevFaction  = target.Faction;
                target.SetFaction(Faction.OfPlayer);

                if (target.workSettings == null)
                {
                    target.workSettings = new Pawn_WorkSettings(target);
                    target.workSettings.EnableAndInitialize();
                }

                if (clord != null)
                {
                    if (clord.ownedPawns.Contains(target))
                    {
                        clord.Notify_PawnLost(target, PawnLostCondition.ChangedFaction, null);
                    }
                }

                if (cso != null)
                {
                    cso.disconnectControlledSurrogate(null);
                }

                if (hackType == 4)
                {
                    //Contorle definitif on jerte l'externalController
                    if (cas != null)
                    {
                        cas.externalController = null;
                    }
                }

                target.Map.attackTargetsCache.UpdateTarget(target);
                PawnComponentsUtility.AddAndRemoveDynamicComponents(target, false);
                Find.ColonistBar.MarkColonistsDirty();

                if (hackType == 3)
                {
                    csm.Hacked          = hackType;
                    csm.hackOrigFaction = prevFaction;
                    if (wasPrisonner)
                    {
                        csm.hackWasPrisoned = true;
                    }
                    else
                    {
                        csm.hackWasPrisoned = false;
                    }
                    csm.hackEndGT = Find.TickManager.TicksGame + (Settings.nbSecDurationTempHack * 60);
                }
                else
                {
                    //Si le surrogate quon veux controlé est infecté alors on enleve l'infection et on reset ses stats
                    if (csm.Infected != -1)
                    {
                        csm.Infected = -1;

                        if (target.skills != null && target.skills.skills != null)
                        {
                            foreach (var sr in target.skills.skills)
                            {
                                sr.levelInt = 0;
                            }
                        }
                    }
                }


                break;
            }

            Utils.GCATPP.decHackingPoints(nbpToConsume);

            Utils.soundDefSurrogateHacked.PlayOneShot(null);

            //Notif d'applciation de l'effet
            Messages.Message("ATPP_SurrogateHackOK".Translate(surrogateName), target, MessageTypeDefOf.PositiveEvent);

            //ANimation sonore et visuelle
            Utils.soundDefSurrogateConnection.PlayOneShot(null);
            MoteMaker.ThrowDustPuffThick(pos.ToVector3Shifted(), cmap, 4.0f, Color.red);

            Find.DesignatorManager.Deselect();
        }
        protected override bool TryExecuteWorker(IncidentParms parms)
        {
            if (Settings.disableSkyMindSecurityStuff)
            {
                return(false);
            }

            List <Pawn>   victims;
            List <string> cryptolockedThings = new List <string>();
            string        title = "";
            string        msg   = "";
            int           nbConnectedClients   = Utils.GCATPP.getNbThingsConnected();
            int           nbSurrogates         = Utils.GCATPP.getNbSurrogateAndroids();
            int           nbUnsecurisedClients = nbConnectedClients - Utils.GCATPP.getNbSlotSecurisedAvailable();

            LetterDef letter;
            //Selection type virus
            int attackType = 1;
            int fee        = 0;

            //Check si sur lensemble des clients connecté il y a quand meme des surrogates
            if (nbSurrogates <= 0)
            {
                return(false);
            }

            //Attaque virale faible
            if (nbUnsecurisedClients <= 0)
            {
                if (!Rand.Chance(Settings.riskSecurisedSecuritySystemGetVirus))
                {
                    return(false);
                }

                int nb = 0;


                nb = nbSurrogates / 2;
                if (nb != 0)
                {
                    nb = Rand.Range(1, nb + 1);
                }
                else
                {
                    nb = 1;
                }

                letter = LetterDefOf.ThreatSmall;
                //Obtention des victimes
                victims = Utils.GCATPP.getRandomSurrogateAndroids(nb);
                if (victims.Count == 0)
                {
                    return(false);
                }

                foreach (var v in victims)
                {
                    CompSkyMind      csm = v.TryGetComp <CompSkyMind>();
                    CompAndroidState cas = v.TryGetComp <CompAndroidState>();
                    if (csm == null || cas == null)
                    {
                        continue;
                    }

                    csm.Infected = 4;

                    //Deconnection du contorlleur le cas echeant
                    if (cas.surrogateController != null)
                    {
                        CompSurrogateOwner cso = cas.surrogateController.TryGetComp <CompSurrogateOwner>();
                        if (cso != null)
                        {
                            cso.disconnectControlledSurrogate(null);
                        }
                    }

                    Hediff he = v.health.hediffSet.GetFirstHediffOfDef(Utils.hediffNoHost);
                    if (he != null)
                    {
                        v.health.RemoveHediff(he);
                    }

                    Utils.ignoredPawnNotifications = v;
                    Utils.VirusedRandomMentalBreak.RandomElement().Worker.TryStart(v, null, false);
                    Utils.ignoredPawnNotifications = null;
                    //v.mindState.mentalStateHandler.TryStartMentalState(  , null, false, false, null, false);
                }


                title = "ATPP_IncidentSurrogateHackingVirus".Translate();
                msg   = "ATPP_IncidentSurrogateHackingLiteDesc".Translate(nb);
            }
            else
            {
                letter = LetterDefOf.ThreatBig;

                attackType = Rand.Range(1, 4);

                int nb = 0;
                LordJob_AssaultColony lordJob;
                Lord lord = null;

                if (attackType != 3)
                {
                    //Attaque virale douce
                    //Obtention des victimes (qui peut allez de 1 victime a N/2 victimes
                    nb = nbSurrogates / 2;
                    if (nb != 0)
                    {
                        nb = Rand.Range(1, nb + 1);
                    }
                    else
                    {
                        nb = 1;
                    }

                    lordJob = new LordJob_AssaultColony(Faction.OfAncientsHostile, false, false, false, false, false);

                    if (lordJob != null)
                    {
                        lord = LordMaker.MakeNewLord(Faction.OfAncientsHostile, lordJob, Current.Game.CurrentMap, null);
                    }
                }
                else
                {
                    nb = nbSurrogates;
                }

                msg = "ATPP_IncidentSurrogateHackingHardDesc".Translate(nb) + "\n";

                switch (attackType)
                {
                case 1:
                    title = "ATPP_IncidentSurrogateHackingVirus".Translate();
                    msg  += "ATPP_IncidentVirusedDesc".Translate();
                    break;

                case 2:
                    title = "ATPP_IncidentSurrogateHackingExplosiveVirus".Translate();
                    msg  += "ATPP_IncidentVirusedExplosiveDesc".Translate();
                    break;

                case 3:
                    title = "ATPP_IncidentSurrogateHackingCryptolocker".Translate();
                    msg  += "ATPP_IncidentCryptolockerDesc".Translate();
                    break;
                }

                victims = Utils.GCATPP.getRandomSurrogateAndroids(nb);
                if (victims.Count != nb)
                {
                    return(false);
                }

                foreach (var v in victims)
                {
                    CompSkyMind csm = v.TryGetComp <CompSkyMind>();

                    v.mindState.canFleeIndividual = false;
                    csm.Infected = attackType;
                    if (v.jobs != null)
                    {
                        v.jobs.StopAll();
                        v.jobs.ClearQueuedJobs();
                    }
                    if (v.mindState != null)
                    {
                        v.mindState.Reset(true);
                    }


                    switch (attackType)
                    {
                    //Virus
                    case 1:
                        //Devient hostile
                        if (lord != null)
                        {
                            lord.AddPawn(v);
                        }
                        break;

                    //Virus explosif
                    case 2:
                        //Devient hostile
                        if (lord != null)
                        {
                            lord.AddPawn(v);
                        }
                        break;

                    //Virus cryptolocker
                    case 3:
                        cryptolockedThings.Add(v.GetUniqueLoadID());

                        switch (v.def.defName)
                        {
                        case Utils.M7:
                            fee += Settings.ransomCostT5;
                            break;

                        case Utils.HU:
                            fee += Settings.ransomCostT4;
                            break;

                        case Utils.T2:
                            fee += Settings.ransomCostT2;
                            break;

                        case Utils.T3:
                            fee += Settings.ransomCostT3;
                            break;

                        case Utils.T4:
                            fee += Settings.ransomCostT4;
                            break;

                        case Utils.T5:
                            fee += Settings.ransomCostT5;
                            break;

                        case Utils.T1:
                        default:
                            fee += Settings.ransomCostT1;
                            break;
                        }
                        break;
                    }

                    if (attackType == 1 || attackType == 2)
                    {
                        //On va attribuer aleatoirement des poids d'attaque aux surrogate
                        SkillRecord shooting = v.skills.GetSkill(SkillDefOf.Shooting);
                        if (shooting != null && !shooting.TotallyDisabled)
                        {
                            shooting.levelInt = Rand.Range(3, 19);
                        }
                        SkillRecord melee = v.skills.GetSkill(SkillDefOf.Melee);
                        if (melee != null && !melee.TotallyDisabled)
                        {
                            melee.levelInt = Rand.Range(3, 19);
                        }
                    }
                }
            }

            Find.LetterStack.ReceiveLetter(title, msg, letter, (LookTargets)victims, null, null);


            if (attackType == 3)
            {
                //Déduction faction ennemis au hasard
                Faction faction = Find.FactionManager.RandomEnemyFaction();

                ChoiceLetter_RansomDemand ransom = (ChoiceLetter_RansomDemand)LetterMaker.MakeLetter(DefDatabase <LetterDef> .GetNamed("ATPP_CLPayCryptoRansom"));
                ransom.label              = "ATPP_CryptolockerNeedPayRansomTitle".Translate();
                ransom.text               = "ATPP_CryptolockerNeedPayRansom".Translate(faction.Name, fee);
                ransom.faction            = faction;
                ransom.radioMode          = true;
                ransom.fee                = fee;
                ransom.cryptolockedThings = cryptolockedThings;
                ransom.StartTimeout(60000);
                Find.LetterStack.ReceiveLetter(ransom, null);
            }

            return(true);
        }
Пример #10
0
        public override void PostSpawnSetup(bool respawningAfterLoad)
        {
            base.PostSpawnSetup(respawningAfterLoad);

            csm = parent.TryGetComp <CompSkyMind>();
        }
Пример #11
0
        protected override bool TryExecuteWorker(IncidentParms parms)
        {
            if (Settings.disableSkyMindSecurityStuff)
            {
                return(false);
            }

            List <Thing>  victims;
            string        title = "";
            string        msg   = "";
            int           nbConnectedClients   = Utils.GCATPP.getNbThingsConnected();
            List <string> cryptolockedThings   = new List <string>();
            int           nbDevices            = Utils.GCATPP.getNbDevices();
            int           nbUnsecurisedClients = nbConnectedClients - Utils.GCATPP.getNbSlotSecurisedAvailable();

            LetterDef letter;
            //Selection type virus
            int attackType = 1;
            int fee        = 0;

            //Check si sur lensemble des clients connecté il y a quand meme des devices
            if (nbDevices <= 0)
            {
                return(false);
            }

            //Attaque virale faible
            if (nbUnsecurisedClients <= 0)
            {
                if (!Rand.Chance(Settings.riskSecurisedSecuritySystemGetVirus))
                {
                    return(false);
                }

                int nb = 0;


                nb = nbDevices / 2;
                if (nb != 0)
                {
                    nb = Rand.Range(1, nb + 1);
                }
                else
                {
                    nb = 1;
                }

                letter = LetterDefOf.ThreatSmall;
                //Obtention des victimes
                victims = Utils.GCATPP.getRandomDevices(nb);
                if (victims.Count == 0)
                {
                    return(false);
                }

                foreach (var v in victims)
                {
                    CompSkyMind      csm = v.TryGetComp <CompSkyMind>();
                    CompAndroidState cas = v.TryGetComp <CompAndroidState>();
                    if (cas == null)
                    {
                        continue;
                    }

                    csm.Infected = 4;

                    //Piratage temporaire
                }


                title = "ATPP_IncidentDeviceHackingVirus".Translate();
                msg   = "ATPP_IncidentDeviceHackingLiteDesc".Translate(nb);

                victims = Utils.GCATPP.getRandomDevices(nb);
                if (victims.Count != nb)
                {
                    return(false);
                }

                foreach (var v in victims)
                {
                    CompSkyMind csm = v.TryGetComp <CompSkyMind>();
                    if (csm == null)
                    {
                        continue;
                    }

                    Utils.GCATPP.disconnectUser(v);
                    csm.Infected      = attackType;
                    csm.infectedEndGT = Find.TickManager.TicksGame + (Rand.Range(Settings.nbHourLiteHackingDeviceAttackLastMin, Settings.nbHourLiteHackingDeviceAttackLastMax) * 2500);
                }
            }
            else
            {
                letter = LetterDefOf.ThreatBig;

                attackType = Rand.Range(1, 4);

                int nb = 0;

                //Attaque virale douce
                //Obtention des victimes (qui peut allez de 1 victime a N/2 victimes
                nb = nbDevices / 2;
                if (nb != 0)
                {
                    nb = Rand.Range(1, nb + 1);
                }
                else
                {
                    nb = 1;
                }

                msg = "ATPP_IncidentDeviceHackingHardDesc".Translate(nb) + "\n";

                switch (attackType)
                {
                case 1:
                    title = "ATPP_IncidentDeviceHackingVirus".Translate();
                    msg  += "ATPP_IncidentDeviceVirusedDesc".Translate();
                    break;

                case 2:
                    title = "ATPP_IncidentDeviceHackingExplosiveVirus".Translate();
                    msg  += "ATPP_IncidentDeviceVirusedExplosiveDesc".Translate();
                    break;

                case 3:
                    title = "ATPP_IncidentDeviceHackingCryptolocker".Translate();
                    msg  += "ATPP_IncidentDeviceCryptolockerDesc".Translate();
                    break;
                }

                victims = Utils.GCATPP.getRandomDevices(nb);
                if (victims.Count != nb)
                {
                    return(false);
                }

                foreach (var v in victims)
                {
                    CompSkyMind csm = v.TryGetComp <CompSkyMind>();
                    if (csm == null)
                    {
                        continue;
                    }

                    Utils.GCATPP.disconnectUser(v);
                    csm.Infected = attackType;

                    //Virus cryptolocker
                    if (attackType == 3)
                    {
                        cryptolockedThings.Add(v.GetUniqueLoadID());
                        fee += (int)(v.def.BaseMarketValue * 0.25f);
                    }
                }
            }

            Find.LetterStack.ReceiveLetter(title, msg, letter, (LookTargets)victims, null, null);


            if (attackType == 3)
            {
                //Déduction faction ennemis au hasard
                Faction faction = Find.FactionManager.RandomEnemyFaction();

                ChoiceLetter_RansomDemand ransom = (ChoiceLetter_RansomDemand)LetterMaker.MakeLetter(DefDatabase <LetterDef> .GetNamed("ATPP_CLPayCryptoRansom"));
                ransom.label              = "ATPP_CryptolockerNeedPayRansomTitle".Translate();
                ransom.text               = "ATPP_CryptolockerNeedPayRansom".Translate(faction.Name, fee);
                ransom.faction            = faction;
                ransom.radioMode          = true;
                ransom.fee                = fee;
                ransom.cryptolockedThings = cryptolockedThings;
                ransom.deviceType         = true;
                ransom.StartTimeout(60000);
                Find.LetterStack.ReceiveLetter(ransom, null);
            }

            return(true);
        }