public override void ApplyOnPawn(Pawn pawn, BodyPartRecord part, Pawn billDoer, List <Thing> ingredients, Bill bill)
        {
            CompAndroidState cas = pawn.TryGetComp <CompAndroidState>();

            if (cas == null)
            {
                return;
            }

            //Le cas echeant on deconnecte le controlleur s'il y en a un
            if (cas.surrogateController != null)
            {
                CompSurrogateOwner cso = cas.surrogateController.TryGetComp <CompSurrogateOwner>();
                if (cso != null)
                {
                    cso.disconnectControlledSurrogate(pawn);
                }
            }

            //On définis le fait qu'il ne sagit plus d'un surrogate mais d'un blank neural net andorid
            cas.isSurrogate = false;
            Hediff he = pawn.health.hediffSet.GetFirstHediffOfDef(Utils.hediffNoHost);

            if (he != null)
            {
                pawn.health.RemoveHediff(he);
            }

            cas.isBlankAndroid = true;
            pawn.health.AddHediff(Utils.hediffBlankAndroid);
        }
        public void stopMindActivities(Pawn mind, bool serverShutdown = false)
        {
            stopRemotelyControlledTurret(mind);
            CompSurrogateOwner cso = mind.ATCompSurrogateOwner;

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

            if (!serverShutdown && assistingMinds.Contains(mind))
            {
                assistingMinds.Remove(mind);
            }
        }
Beispiel #3
0
        public 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.ATCompState;
                    if (csm == null || cas == null)
                    {
                        continue;
                    }

                    csm.Infected = 4;

                    //Deconnection du contorlleur le cas echeant
                    if (cas.surrogateController != null)
                    {
                        CompSurrogateOwner cso = cas.surrogateController.ATCompSurrogateOwner;
                        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.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);
        }
        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();
        }
        public override IEnumerable <Gizmo> CompGetGizmosExtra()
        {
            Building build = (Building)parent;

            //Si aucun mind stocké
            if (storedMinds.Count() == 0 || !build.TryGetComp <CompPowerTrader>().PowerOn || !Booted())
            {
                yield break;
            }

            yield return(new Command_Action {
                icon = Tex.processInfo,
                defaultLabel = "ATPP_ProcessInfo".Translate(),
                defaultDesc = "ATPP_ProcessInfoDesc".Translate(),
                action = delegate() {
                    showFloatMenuMindsStored(delegate(Pawn p) {
                        Find.WindowStack.Add(new Dialog_InfoCard(p));
                    }, false, false, false, true);
                }
            });

            yield return(new Command_Action {
                icon = Tex.processRemove,
                defaultLabel = "ATPP_ProcessRemove".Translate(),
                defaultDesc = "ATPP_ProcessRemoveDesc".Translate(),
                action = delegate() {
                    showFloatMenuMindsStored(delegate(Pawn p) {
                        Find.WindowStack.Add(new Dialog_Msg("ATPP_ProcessRemove".Translate(), "ATPP_ProcessRemoveDescConfirm".Translate(p.LabelShortCap, getName()), delegate {
                            stopMindActivities(p);

                            RemoveMind(p);
                            p.Kill(null, null);

                            Messages.Message("ATPP_ProcessRemoveOK".Translate(p.LabelShortCap), parent, MessageTypeDefOf.PositiveEvent);

                            Utils.playVocal("soundDefSkyCloudMindDeletionCompleted");
                        }, false));
                    }, false, false, false, false);
                }
            });

            yield return(new Command_Action {
                icon = Tex.processDuplicate,
                defaultLabel = "ATPP_ProcessDuplicate".Translate(),
                defaultDesc = "ATPP_ProcessDuplicateDesc".Translate(),
                action = delegate() {
                    showFloatMenuMindsStored(delegate(Pawn p) {
                        CompSurrogateOwner cso = p.ATCompSurrogateOwner;
                        if (cso == null)
                        {
                            return;
                        }

                        int GT = Find.TickManager.TicksGame;

                        cso.replicationStartGT = GT;
                        cso.replicationEndingGT = GT + (Settings.mindReplicationHours * 2500);

                        replicatingMinds.Add(p);
                        stopMindActivities(p);

                        Messages.Message("ATPP_ProcessDuplicateOK".Translate(p.LabelShortCap), parent, MessageTypeDefOf.PositiveEvent);
                    }, false, false, false, false);
                }
            });

            yield return(new Command_Action {
                icon = Tex.processAssist,
                defaultLabel = "ATPP_ProcessAssist".Translate(),
                defaultDesc = "ATPP_ProcessAssistDesc".Translate(),
                action = delegate() {
                    List <FloatMenuOption> opts = new List <FloatMenuOption>();
                    //Affichage des minds affectés à l'assistement
                    opts.Add(new FloatMenuOption("ATPP_ProcessAssistAssignedMinds".Translate(), delegate {
                        List <FloatMenuOption> optsAdd = null;

                        //Check s'il y a lieu d'jaouter l'option (il y a au moin 1+ minds assigné à supprimer
                        if (assistingMinds.Count > 0)
                        {
                            optsAdd = new List <FloatMenuOption>();
                            optsAdd.Add(new FloatMenuOption("-" + ("ATPP_ProcessAssistUnassignAll".Translate()), delegate {
                                int nb = 0;
                                foreach (var m in storedMinds)
                                {
                                    if (assistingMinds.Contains(m))
                                    {
                                        assistingMinds.Remove(m);
                                        nb++;
                                    }
                                }

                                if (nb > 0)
                                {
                                    Messages.Message("ATPP_ProcessMassUnassist".Translate(nb), parent, MessageTypeDefOf.PositiveEvent);
                                }
                            }, MenuOptionPriority.Default, null, null, 0f, null, null));
                        }

                        showFloatMenuMindsStored(delegate(Pawn p) {
                            assistingMinds.Remove(p);

                            Messages.Message("ATPP_ProcessUnassistOK".Translate(p.LabelShortCap), parent, MessageTypeDefOf.PositiveEvent);
                        }, false, false, false, false, optsAdd, false, true);
                    }, MenuOptionPriority.Default, null, null, 0f, null, null));

                    //Affichage des minds non affectés à l'assistement
                    opts.Add(new FloatMenuOption("ATPP_ProcessAssistUnassignedMinds".Translate(), delegate {
                        List <FloatMenuOption> optsAdd = null;

                        //Check s'il y a lieu d'jaouter l'option (il y a des minds et des minds non ajoutés)
                        if (storedMinds.Count > 0 && getNbUnassistingMinds() > 0)
                        {
                            optsAdd = new List <FloatMenuOption>();
                            optsAdd.Add(new FloatMenuOption("-" + ("ATPP_ProcessAssistAssignAll".Translate()), delegate {
                                int nb = 0;
                                foreach (var m in storedMinds)
                                {
                                    if (!assistingMinds.Contains(m))
                                    {
                                        stopMindActivities(m);
                                        assistingMinds.Add(m);
                                        nb++;
                                    }
                                }

                                if (nb > 0)
                                {
                                    Messages.Message("ATPP_ProcessMassAssist".Translate(nb), parent, MessageTypeDefOf.PositiveEvent);
                                }
                            }, MenuOptionPriority.Default, null, null, 0f, null, null));
                        }

                        showFloatMenuMindsStored(delegate(Pawn p) {
                            stopMindActivities(p);
                            assistingMinds.Add(p);

                            Messages.Message("ATPP_ProcessAssistOK".Translate(p.LabelShortCap), parent, MessageTypeDefOf.PositiveEvent);
                        }, false, false, false, false, optsAdd, true);
                    }, MenuOptionPriority.Default, null, null, 0f, null, null));

                    FloatMenu floatMenuMap = new FloatMenu(opts);
                    Find.WindowStack.Add(floatMenuMap);
                }
            });

            yield return(new Command_Action {
                icon = Tex.processMigrate,
                defaultLabel = "ATPP_ProcessMigrate".Translate(),
                defaultDesc = "ATPP_ProcessMigrateDesc".Translate(),
                action = delegate() {
                    showFloatMenuMindsStored(delegate(Pawn p) {
                        Utils.ShowFloatMenuSkyCloudCores(delegate(Building core) {
                            CompSurrogateOwner cso = p.ATCompSurrogateOwner;
                            stopMindActivities(p);
                            cso.startMigration(core);
                        }, (Building)parent);
                    }, false, false, false, false);
                }
            });

            yield return(new Command_Action {
                icon = Tex.processSkillUp,
                defaultLabel = "ATPP_Skills".Translate(),
                defaultDesc = "ATPP_SkillsDesc".Translate(),
                action = delegate() {
                    showFloatMenuMindsStored(delegate(Pawn p) {
                        Find.WindowStack.Add(new Dialog_SkillUp(p, true));
                    }, false, false, false, true);
                }
            });

            yield return(new Command_Action {
                icon = Tex.AndroidToControlTarget,
                defaultLabel = "ATPP_AndroidToControlTarget".Translate(),
                defaultDesc = "ATPP_AndroidToControlTargetDesc".Translate(),
                action = delegate() {
                    showFloatMenuMindsStored(delegate(Pawn p) {
                        //Listing map de destination
                        List <FloatMenuOption> opts = new List <FloatMenuOption>();
                        string lib = "";
                        foreach (var m in Find.Maps)
                        {
                            if (m == Find.CurrentMap)
                            {
                                lib = "ATPP_ThisCurrentMap".Translate(m.Parent.Label);
                            }
                            else
                            {
                                lib = m.Parent.Label;
                            }

                            opts.Add(new FloatMenuOption(lib, delegate {
                                Current.Game.CurrentMap = m;
                                Designator_AndroidToControl x = new Designator_AndroidToControl(p, true);
                                Find.DesignatorManager.Select(x);
                            }, MenuOptionPriority.Default, null, null, 0f, null, null));
                        }
                        if (opts.Count != 0)
                        {
                            if (opts.Count == 1)
                            {
                                Designator_AndroidToControl x = new Designator_AndroidToControl(p, true);
                                Find.DesignatorManager.Select(x);
                            }
                            else
                            {
                                FloatMenu floatMenuMap = new FloatMenu(opts);
                                Find.WindowStack.Add(floatMenuMap);
                            }
                        }
                    }, true, true, false, false, null, true);
                }
            });

            if (Utils.isThereNotControlledSurrogateInCaravan())
            {
                //Si drones SX no controllés dans une caravane
                yield return(new Command_Action {
                    icon = Tex.AndroidToControlTargetRecovery,
                    defaultLabel = "ATPP_AndroidToControlTargetRecoverCaravan".Translate(),
                    defaultDesc = "ATPP_AndroidToControlTargetRecoverCaravanDesc".Translate(),
                    action = delegate() {
                        showFloatMenuMindsStored(delegate(Pawn p) {
                            Utils.ShowFloatMenuNotCOntrolledSurrogateInCaravan(p, delegate(Pawn sSX) {
                                CompSurrogateOwner cso = p.ATCompSurrogateOwner;
                                if (cso == null)
                                {
                                    return;
                                }

                                if (!Utils.GCATPP.isConnectedToSkyMind(sSX))
                                {
                                    //Tentative connection au skymind
                                    if (!Utils.GCATPP.connectUser(sSX))
                                    {
                                        return;
                                    }
                                }
                                cso.setControlledSurrogate(sSX);
                            });
                        }, true, true, false, false, null, true);
                    }
                });
            }

            if (getNbMindsConnectedToSurrogate() != 0 || controlledTurrets.Count() != 0)
            {
                yield return(new Command_Action {
                    icon = Tex.AndroidToControlTargetDisconnect,
                    defaultLabel = "ATPP_AndroidToControlTargetDisconnect".Translate(),
                    defaultDesc = "ATPP_AndroidToControlTargetDisconnectDesc".Translate(),
                    action = delegate() {
                        List <FloatMenuOption> opts = new List <FloatMenuOption>();
                        opts.Add(new FloatMenuOption("ATPP_ProcessDisconnectAllSurrogates".Translate(), delegate {
                            disconnectAllSurrogates();
                            disconnectAllRemotelyControlledTurrets();
                            Utils.playVocal("soundDefSkyCloudAllMindDisconnected");
                        }, MenuOptionPriority.Default, null, null, 0f, null, null));

                        showFloatMenuMindsStored(delegate(Pawn p) {
                            CompSurrogateOwner cso = p.ATCompSurrogateOwner;
                            if (cso != null && cso.isThereSX())
                            {
                                cso.disconnectControlledSurrogate(null);
                            }
                            stopRemotelyControlledTurret(p);
                        }, false, false, true, false, opts);
                    }
                });
            }

            yield break;
        }