public override void DoEffect(Pawn user)
        {
            if (Props.thingDef == null)
            {
                return;
            }

            IntVec3 dropSpot;
            Thing   thing = ThingMaker.MakeThing(Props.thingDef);

            if (thing != null)
            {
                if (Props.amount > 0)
                {
                    thing.stackCount = Props.amount;
                }
                if (thing != null && DropCellFinder.TryFindDropSpotNear(parent.PositionHeld, parent.MapHeld, out dropSpot, false, false, false))
                {
                    TradeUtility.SpawnDropPod(dropSpot, parent.MapHeld, thing);
                }
            }
        }
Пример #2
0
        // Token: 0x06000003 RID: 3 RVA: 0x00002158 File Offset: 0x00000358
        public static void DropThingGroupsNear(IntVec3 dropCenter, Map map, List <List <Thing> > thingsGroups,
                                               int openDelay, bool instaDrop, bool leaveSlag, bool canRoofPunch)
        {
            foreach (var list in thingsGroups)
            {
                if (!DropCellFinder.TryFindDropSpotNear(dropCenter, map, out var intVec, true, canRoofPunch))
                {
                    Log.Warning(
                        string.Concat("DropThingsNear failed to find a place to drop ", list.FirstOrDefault(), " near ",
                                      dropCenter, ". Dropping on random square instead."));
                    intVec = CellFinderLoose.RandomCellWith(c => c.Walkable(map), map);
                }

                foreach (var thing in list)
                {
                    thing.SetForbidden(true, false);
                }

                if (instaDrop)
                {
                    foreach (var thing in list)
                    {
                        GenPlace.TryPlaceThing(thing, intVec, map, ThingPlaceMode.Near);
                    }
                }
                else
                {
                    var activeDropPodInfo = new ActiveDropPodInfo();
                    foreach (var item in list)
                    {
                        activeDropPodInfo.innerContainer.TryAdd(item);
                    }

                    activeDropPodInfo.openDelay = openDelay;
                    activeDropPodInfo.leaveSlag = leaveSlag;
                    MakeDropPodAt(intVec, map, activeDropPodInfo);
                }
            }
        }
Пример #3
0
        void LaunchSecurityDropPods(int dropPodsNumber, PawnKindDef securityForcesDef, bool assaultColony)
        {
            IntVec3     dropPodSpot;
            List <Pawn> securityForcesList = new List <Pawn>();

            if ((dropPodsNumber == 0) || (securityForcesDef == null))
            {
                return;
            }
            OG_Inhabitants.InitializeUniformColorAccordingToBiome(); // Necessary in case of small outpost (no inhabitants were generated).
            for (int soldierIndex = 0; soldierIndex < dropPodsNumber; soldierIndex++)
            {
                bool validDropPodCellIsFound = DropCellFinder.TryFindDropSpotNear(this.dropZoneCenter, out dropPodSpot, true, false);
                if (validDropPodCellIsFound)
                {
                    Pawn soldier = OG_Inhabitants.GeneratePawn(securityForcesDef);
                    securityForcesList.Add(soldier);
                    DropPodUtility.MakeDropPodAt(dropPodSpot, new DropPodInfo
                    {
                        SingleContainedThing = soldier,
                        openDelay            = 240,
                        leaveSlag            = false
                    });
                }
            }

            LordJob lordJob;

            if (assaultColony)
            {
                lordJob = new LordJob_AssaultColony(OG_Util.FactionOfMAndCo, true, true, false);
            }
            else
            {
                lordJob = new LordJob_DefendPoint(this.dropZoneCenter);
            }
            Lord lord = LordMaker.MakeNewLord(OG_Util.FactionOfMAndCo, lordJob, securityForcesList);
        }
Пример #4
0
 public static void DropThingGroupsNear_NewTmp(IntVec3 dropCenter, Map map, List <List <Thing> > thingsGroups, int openDelay = 110, bool instaDrop = false, bool leaveSlag = false, bool canRoofPunch = true, bool forbid = true, bool allowFogged = true)
 {
     foreach (List <Thing> thingsGroup in thingsGroups)
     {
         if (!DropCellFinder.TryFindDropSpotNear(dropCenter, map, out IntVec3 result, allowFogged, canRoofPunch) && (canRoofPunch || !DropCellFinder.TryFindDropSpotNear(dropCenter, map, out result, allowFogged, canRoofPunch: true)))
         {
             Log.Warning("DropThingsNear failed to find a place to drop " + thingsGroup.FirstOrDefault() + " near " + dropCenter + ". Dropping on random square instead.");
             result = CellFinderLoose.RandomCellWith((IntVec3 c) => c.Walkable(map), map);
         }
         if (forbid)
         {
             for (int i = 0; i < thingsGroup.Count; i++)
             {
                 thingsGroup[i].SetForbidden(value: true, warnOnFail: false);
             }
         }
         if (instaDrop)
         {
             foreach (Thing item in thingsGroup)
             {
                 GenPlace.TryPlaceThing(item, result, map, ThingPlaceMode.Near);
             }
         }
         else
         {
             ActiveDropPodInfo activeDropPodInfo = new ActiveDropPodInfo();
             foreach (Thing item2 in thingsGroup)
             {
                 activeDropPodInfo.innerContainer.TryAdd(item2);
             }
             activeDropPodInfo.openDelay = openDelay;
             activeDropPodInfo.leaveSlag = leaveSlag;
             MakeDropPodAt(result, map, activeDropPodInfo);
         }
     }
 }
Пример #5
0
        public override void Init()
        {
            base.Init();

            var customParams = CustomParams;

            Data.baseRadius = Mathf.InverseLerp(BaseRadiusMin, BaseRadiusMax, (float)lord.ownedPawns.Count / 50);
            Data.baseRadius = Mathf.Clamp(Data.baseRadius, BaseRadiusMin, BaseRadiusMax);
            List <Thing> list             = new List <Thing>();
            var          placedBlueprints = CustomSiegeUtility.PlaceBlueprints(Data, base.Map, lord.faction).ToList();

            for (int i = 0; i < placedBlueprints.Count; i++)
            {
                var blueprint_Build = placedBlueprints[i];
                Data.blueprints.Add(blueprint_Build);
                using (List <ThingDefCountClass> .Enumerator enumerator2 = blueprint_Build.MaterialsNeeded().GetEnumerator())
                {
                    while (enumerator2.MoveNext())
                    {
                        ThingDefCountClass cost = enumerator2.Current;
                        Thing thing             = list.FirstOrDefault((Thing t) => t.def == cost.thingDef);
                        if (thing != null)
                        {
                            thing.stackCount += cost.count;
                        }
                        else
                        {
                            Thing thing2 = ThingMaker.MakeThing(cost.thingDef, null);
                            thing2.stackCount = cost.count;
                            list.Add(thing2);
                        }
                    }
                }
                ThingDef thingDef = blueprint_Build.def.entityDefToBuild as ThingDef;
                if (thingDef != null)
                {
                    ThingDef  turret    = thingDef;
                    bool      allowEMP  = false;
                    TechLevel techLevel = lord.faction.def.techLevel;
                    ThingDef  thingDef2 = TurretGunUtility.TryFindRandomShellDef(turret, allowEMP, true, techLevel, false, 250f);
                    if (thingDef2 != null)
                    {
                        Thing thing3 = ThingMaker.MakeThing(thingDef2, null);
                        thing3.stackCount = InitalShellsPerCannon;
                        list.Add(thing3);
                    }
                }
            }
            for (int i = 0; i < list.Count; i++)
            {
                list[i].stackCount = Mathf.CeilToInt((float)list[i].stackCount * Rand.Range(1f, 1.2f));
            }
            List <List <Thing> > list2 = new List <List <Thing> >();

            for (int j = 0; j < list.Count; j++)
            {
                while (list[j].stackCount > list[j].def.stackLimit)
                {
                    int   num    = Mathf.CeilToInt((float)list[j].def.stackLimit * Rand.Range(0.9f, 0.999f));
                    Thing thing4 = ThingMaker.MakeThing(list[j].def, null);
                    thing4.stackCount   = num;
                    list[j].stackCount -= num;
                    list.Add(thing4);
                }
            }
            List <Thing> list3 = new List <Thing>();

            for (int k = 0; k < list.Count; k++)
            {
                list3.Add(list[k]);
                if (k % 2 == 1 || k == list.Count - 1)
                {
                    list2.Add(list3);
                    list3 = new List <Thing>();
                }
            }
            List <Thing> list4 = new List <Thing>();
            int          num2  = Mathf.RoundToInt(NutritionRangePerRaider.RandomInRange / customParams.mealDef.GetStatValueAbstract(StatDefOf.Nutrition) * lord.ownedPawns.Count);

            for (int l = 0; l < num2; l++)
            {
                Thing item = ThingMaker.MakeThing(customParams.mealDef, null);
                list4.Add(item);
            }
            list2.Add(list4);
            if (lord.faction.def.techLevel >= TechLevel.Industrial)
            {
                DropPodUtility.DropThingGroupsNear(Data.siegeCenter, Map, list2, 110);
            }
            else
            {
                for (int i = 0; i < list2.Count; i++)
                {
                    var group = list2[i];
                    if (DropCellFinder.TryFindDropSpotNear(Data.siegeCenter, Map, out IntVec3 pos, false, false))
                    {
                        for (int j = 0; j < group.Count; j++)
                        {
                            var thing = group[j];
                            thing.SetForbidden(true, false);
                            GenPlace.TryPlaceThing(thing, pos, Map, ThingPlaceMode.Near);
                        }
                    }
                }
            }
            Data.desiredBuilderFraction = BuilderCountFraction.RandomInRange;
        }
Пример #6
0
        public override void GenerateIntoMap(Map map)
        {
            if (Find.GameInitData == null)
            {
                return;
            }
            List <List <Thing> > list = new List <List <Thing> >();

            foreach (Pawn item in Find.GameInitData.startingAndOptionalPawns)
            {
                list.Add(new List <Thing>
                {
                    item
                });
            }
            List <Thing> list2 = new List <Thing>();

            foreach (ScenPart scenPart in Find.Scenario.AllParts)
            {
                list2.AddRange(scenPart.PlayerStartingThings());
            }
            int num = 0;

            for (int i = 0; i < list2.Count; i++)
            {
                Thing thing = list2[i];
                if (thing.def.CanHaveFaction)
                {
                    thing.SetFactionDirect(Faction.OfPlayer);
                }
                list[num].Add(thing);
                num++;
                if (num >= list.Count)
                {
                    num = 0;
                }
            }
            PlayerPawnsArriveMethod method = (PlayerPawnsArriveMethod)AccessTools.Field(typeof(ScenPart_PlayerPawnsArriveMethod), "method").GetValue(this);

            //     Log.Message("method = " + method.ToStringHuman() + " dropship: "+ (DropshipDef != null));
            if (DropshipDef != null && method == PlayerPawnsArriveMethod.DropPods)
            {
                Thing        ship     = ThingMaker.MakeThing(this.DropshipDef);
                CompDropship dropship = ship.TryGetCompFast <CompDropship>();
                if (dropship != null)
                {
                    foreach (List <Thing> item in list)
                    {
                        if (item.Contains(ship))
                        {
                            item.Remove(ship);
                        }
                        dropship.Transporter.innerContainer.TryAddRangeOrTransfer(item);
                    }
                    dropship.autodustoff = AutoDustoff;
                    if (DropCellFinder.TryFindDropSpotNear(MapGenerator.PlayerStartSpot, map, out IntVec3 spot, false, false, false, ship.def.Size))
                    {
                        GenPlace.TryPlaceThing(SkyfallerMaker.MakeSkyfaller(ThingDef.Named(ship.def.defName + "_Incoming"), ship), spot, map, ThingPlaceMode.Near, null, null, default(Rot4));
                    }
                    else
                    {
                        GenPlace.TryPlaceThing(SkyfallerMaker.MakeSkyfaller(ThingDef.Named(ship.def.defName + "_Incoming"), ship), MapGenerator.PlayerStartSpot, map, ThingPlaceMode.Near, null, null, default(Rot4));
                    }
                    return;
                }
            }
Пример #7
0
        public bool SendPawnBackToMap(Pawn pawn, Map map)
        {
            IntVec3 dropSpot        = IntVec3.Invalid;
            bool    dropSpotIsValid = false;

            // Check orbital relay is powered on.
            Building_OrbitalRelay orbitalRelay = Util_OrbitalRelay.GetOrbitalRelay(map);

            if (orbitalRelay == null)
            {
                return(false);
            }
            if (orbitalRelay.powerComp.PowerOn == false)
            {
                return(false);
            }
            // Look for an available landing pad.
            Building_LandingPad landingPad = Util_LandingPad.GetBestAvailableLandingPad(map);

            if (landingPad == null)
            {
                return(false);
            }
            // Get a nearby drop spot.
            dropSpotIsValid = DropCellFinder.TryFindDropSpotNear(landingPad.Position, map, out dropSpot, false, false);

            if (dropSpot.IsValid)
            {
                string hisHerIts = GenderUtility.GetPossessive(pawn.gender);
                string heSheIt   = GenderUtility.GetPronoun(pawn.gender);
                string himHerIt  = GenderUtility.GetObjective(pawn.gender);

                // Restore needs level.
                pawn.needs.food.ForceSetLevel(Rand.Range(0.75f, 1f));
                pawn.needs.rest.ForceSetLevel(Rand.Range(0.75f, 1f));
                pawn.needs.joy.ForceSetLevel(Rand.Range(0.5f, 0.8f));
                pawn.needs.comfort.ForceSetLevel(Rand.Range(0.6f, 0.9f));
                pawn.needs.space.ForceSetLevel(Rand.Range(0.1f, 0.3f)); // Drop-pod is very small.

                ActiveDropPodInfo dropPodInfo = new ActiveDropPodInfo();
                bool healingSuccessful        = (Rand.Value < 0.98f);
                if (healingSuccessful)
                {
                    string orbitalHealingFailedText = "-- Comlink with MiningCo. --\n\n"
                                                      + "\"Healing of " + pawn.NameStringShort + " is now finished. Everything went fine during the treatment.\n"
                                                      + "We just launched " + hisHerIts + " drop pod toward your colony.\n\n"
                                                      + "I hope you are satisfied of our services.\n\n"
                                                      + "MiningCo. medibay officer out.\"\n\n"
                                                      + "-- End of transmission --";
                    Find.LetterStack.ReceiveLetter("Orbital healing finished", orbitalHealingFailedText, LetterDefOf.PositiveEvent, new TargetInfo(dropSpot, map));
                }
                else
                {
                    // Dying pawn with heart attack.
                    string orbitalHealingSuccessfulText = "-- Comlink with MiningCo. --\n\n"
                                                          + "\"Though we did our best to heal " + pawn.NameStringShort + ", it seems " + hisHerIts + " metabolism was disturbed by the last injection.\n\n"
                                                          + "I am affraid that we need to immediately send " + himHerIt + " back to you as our rules strictly forbid civilian bodies storage.\n\n"
                                                          + "Please accept those silvers as a compensation.\n\n"
                                                          + "MiningCo. medibay officer out.\"\n\n"
                                                          + "-- End of transmission --";
                    Find.LetterStack.ReceiveLetter("Orbital healing interrupted", orbitalHealingSuccessfulText, LetterDefOf.NegativeEvent, new TargetInfo(dropSpot, map));
                    pawn.health.AddHediff(HediffDef.Named("HeartAttack"));
                    pawn.health.AddHediff(HediffDefOf.Anesthetic);
                    Thing compensation = ThingMaker.MakeThing(ThingDefOf.Silver);
                    compensation.stackCount = Mathf.RoundToInt(0.5f * Util_Spaceship.orbitalHealingCost);
                    dropPodInfo.innerContainer.TryAdd(compensation);
                }
                dropPodInfo.innerContainer.TryAdd(pawn);
                dropPodInfo.leaveSlag = true;
                DropPodUtility.MakeDropPodAt(dropSpot, map, dropPodInfo);
                return(true);
            }
            return(false);
        }
Пример #8
0
        protected override bool TryExecuteWorker(IncidentParms parms)
        {
            if (!DropCellFinder.TryFindRaidDropCenterClose(spot: out IntVec3 dropSpot, map: (Map)parms.target))
            {
                return(false);
            }
            if (!FindAlliedWarringFaction(faction: out Faction faction))
            {
                return(false);
            }
            if (faction == null)
            {
                return(false);
            }

            bool   bamboozle           = false;
            string arrivalText         = string.Empty;
            int    factionGoodWillLoss = FactionInteractionDiplomacyTuningsBlatantlyCopiedFromPeaceTalks
                                         .GoodWill_FactionWarPeaceTalks_ImpactSmall.RandomInRange / 2;

            IncidentParms raidParms =
                StorytellerUtility.DefaultParmsNow(incCat: IncidentCategoryDefOf.ThreatBig, target: (Map)parms.target);

            raidParms.forced          = true;
            raidParms.faction         = faction.EnemyInFactionWar();
            raidParms.raidStrategy    = RaidStrategyDefOf.ImmediateAttack;
            raidParms.raidArrivalMode = PawnsArrivalModeDefOf.CenterDrop;
            raidParms.spawnCenter     = dropSpot;

            if (faction.EnemyInFactionWar().def.techLevel >= TechLevel.Industrial &&
                faction.EnemyInFactionWar().RelationKindWith(other: Faction.OfPlayer) == FactionRelationKind.Hostile)
            {
                bamboozle = Rand.Chance(chance: 0.25f);
            }

            if (bamboozle)
            {
                arrivalText = string.Format(format: raidParms.raidArrivalMode.textEnemy, arg0: raidParms.faction.def.pawnsPlural, arg1: raidParms.faction.Name);
            }

            //get combat-pawns to spawn.
            PawnGroupMakerParms defaultPawnGroupMakerParms = IncidentParmsUtility.GetDefaultPawnGroupMakerParms(groupKind: PawnGroupKindDefOf.Combat, parms: raidParms);

            defaultPawnGroupMakerParms.points = IncidentWorker_Raid.AdjustedRaidPoints(points: defaultPawnGroupMakerParms.points, raidArrivalMode: raidParms.raidArrivalMode, raidStrategy: raidParms.raidStrategy, faction: defaultPawnGroupMakerParms.faction, groupKind: PawnGroupKindDefOf.Combat);
            IEnumerable <PawnKindDef> pawnKinds = PawnGroupMakerUtility.GeneratePawnKindsExample(parms: defaultPawnGroupMakerParms).ToList();
            List <Thing> pawnlist = new List <Thing>();

            for (int i = 0; i < this.pawnstoSpawn.RandomInRange; i++)
            {
                PawnGenerationRequest request = new PawnGenerationRequest(kind: pawnKinds.RandomElement(), faction: faction, allowDowned: true, allowDead: true, mustBeCapableOfViolence: true);
                Pawn woundedCombatant         = PawnGenerator.GeneratePawn(request: request);
                woundedCombatant.guest.getRescuedThoughtOnUndownedBecauseOfPlayer = true;
                ThingDef weapon = Rand.Bool ? DefDatabase <ThingDef> .AllDefsListForReading.Where(predicate : x => x.IsWeaponUsingProjectiles).RandomElement() : null;

                ThingDef  usedWeaponDef = weapon;
                DamageDef damageDef     = usedWeaponDef?.Verbs?.First()?.defaultProjectile?.projectile?.damageDef; //null? check? All? THE? THINGS!!!!?
                if (usedWeaponDef != null && damageDef == null)
                {
                    usedWeaponDef = null;
                }
                CustomFaction_HealthUtility.DamageUntilDownedWithSpecialOptions(p: woundedCombatant, allowBleedingWounds: true, damageDef: damageDef, weapon: usedWeaponDef);
                //todo: maybe add some storylogging.
                pawnlist.Add(item: woundedCombatant);
            }

            string  initialMessage = "MFI_WoundedCombatant".Translate(faction.Name);
            DiaNode diaNode        = new DiaNode(text: initialMessage);

            DiaOption diaOptionOk = new DiaOption(text: "OK".Translate())
            {
                resolveTree = true
            };

            DiaOption diaOptionAccept = new DiaOption(text: "RansomDemand_Accept".Translate())
            {
                action = () =>
                {
                    if (bamboozle)
                    {
                        Find.TickManager.slower.SignalForceNormalSpeedShort();
                        IncidentDefOf.RaidEnemy.Worker.TryExecute(parms: raidParms);
                    }
                    else
                    {
                        IntVec3 intVec = IntVec3.Invalid;

                        List <Building> allBuildingsColonist = ((Map)parms.target).listerBuildings.allBuildingsColonist.Where(predicate: x => x.def.thingClass == typeof(Building_Bed)).ToList();
                        for (int i = 0; i < allBuildingsColonist.Count; i++)
                        {
                            if (DropCellFinder.TryFindDropSpotNear(center: allBuildingsColonist[index: i].Position, map: (Map)parms.target, result: out intVec, allowFogged: false, canRoofPunch: false))
                            {
                                break;
                            }
                        }
                        if (intVec == IntVec3.Invalid)
                        {
                            intVec = DropCellFinder.RandomDropSpot(map: (Map)parms.target);
                        }
                        DropPodUtility.DropThingsNear(dropCenter: intVec, map: (Map)parms.target, things: pawnlist, openDelay: 180, leaveSlag: true, canRoofPunch: false);
                        Find.World.GetComponent <WorldComponent_MFI_FactionWar>().NotifyBattleWon(faction: faction);
                    }
                }
            };
            string  bamboozledAndAmbushed = "MFI_WoundedCombatantAmbush".Translate(faction, arrivalText);
            string  commanderGreatful     = "MFI_WoundedCombatantGratitude".Translate();
            DiaNode acceptDiaNode         = new DiaNode(text: bamboozle ? bamboozledAndAmbushed : commanderGreatful);

            diaOptionAccept.link = acceptDiaNode;
            diaNode.options.Add(item: diaOptionAccept);
            acceptDiaNode.options.Add(item: diaOptionOk);

            DiaOption diaOptionRejection = new DiaOption(text: "RansomDemand_Reject".Translate())
            {
                action = () =>
                {
                    if (bamboozle)
                    {
                        Find.World.GetComponent <WorldComponent_MFI_FactionWar>().NotifyBattleWon(faction: faction);
                    }
                    else
                    {
                        faction.TryAffectGoodwillWith(other: Faction.OfPlayer, goodwillChange: factionGoodWillLoss, canSendMessage: false);
                    }
                }
            };
            string  rejectionResponse        = "MFI_WoundedCombatantRejected".Translate(faction.Name, factionGoodWillLoss);
            string  bamboozlingTheBamboozler = "MFI_WoundedCombatantAmbushAvoided".Translate();
            DiaNode rejectionDiaNode         = new DiaNode(text: bamboozle ? bamboozlingTheBamboozler : rejectionResponse);

            diaOptionRejection.link = rejectionDiaNode;
            diaNode.options.Add(item: diaOptionRejection);
            rejectionDiaNode.options.Add(item: diaOptionOk);

            string title = "MFI_WoundedCombatantTitle".Translate(((Map)parms.target).Parent.Label);

            Find.WindowStack.Add(window: new Dialog_NodeTreeWithFactionInfo(nodeRoot: diaNode, faction: faction, delayInteractivity: true, radioMode: true, title: title));
            Find.Archive.Add(archivable: new ArchivedDialog(text: diaNode.text, title: title, relatedFaction: faction));
            return(true);
        }
Пример #9
0
        public void LaunchInvasion(string eventTitle, string eventText, float raidPointsFactor, int dropsNumber, LetterType letterType, IntVec3 spawnPosition)
        {
            this.invasionIsDone = true;

            // Get an indicative amount of points based on the colony wealth so it scales up well for late-game colonies.
            IncidentParms invasionParameters = IncidentMakerUtility.DefaultParmsNow(Find.Storyteller.def, IncidentCategory.ThreatBig);

            invasionParameters.faction                 = Faction.OfMechanoids;
            invasionParameters.raidStrategy            = RaidStrategyDefOf.ImmediateAttack;
            invasionParameters.raidArrivalMode         = PawnsArriveMode.EdgeDrop;
            invasionParameters.raidNeverFleeIndividual = true;
            invasionParameters.raidPodOpenDelay        = 800;
            if (dropsNumber > 0)
            {
                invasionParameters.points *= (raidPointsFactor / dropsNumber);
                if (invasionParameters.points < 320)
                {
                    invasionParameters.points = 320;
                }
                for (int dropIndex = 0; dropIndex < dropsNumber; dropIndex++)
                {
                    IntVec3 dropPodSpawningPosition;
                    float   squadPoint = invasionParameters.points;
                    if (spawnPosition.IsValid)
                    {
                        invasionParameters.spawnCenter = spawnPosition;
                    }
                    else
                    {
                        RCellFinder.TryFindRandomPawnEntryCell(out invasionParameters.spawnCenter);
                    }
                    List <Pawn> mechanoidsList = new List <Pawn>();
                    while (squadPoint >= PawnKindDef.Named("Scyther").combatPower)
                    {
                        bool validDropPodCellIsFound = DropCellFinder.TryFindDropSpotNear(invasionParameters.spawnCenter, out dropPodSpawningPosition, false, true);
                        if (validDropPodCellIsFound)
                        {
                            Faction faction = Faction.OfMechanoids;
                            Pawn    squadMember;
                            if (Rand.Value < 0.6f)
                            {
                                squadMember = PawnGenerator.GeneratePawn(PawnKindDef.Named("Scyther"), faction);
                                squadPoint -= PawnKindDef.Named("Scyther").combatPower;
                            }
                            else
                            {
                                squadMember = PawnGenerator.GeneratePawn(PawnKindDef.Named("Centipede"), faction);
                                squadPoint -= (int)PawnKindDef.Named("Centipede").combatPower;
                            }
                            mechanoidsList.Add(squadMember);
                            DropPodUtility.MakeDropPodAt(dropPodSpawningPosition, new DropPodInfo
                            {
                                SingleContainedThing = squadMember,
                                openDelay            = 800,
                                leaveSlag            = true
                            });
                        }
                    }
                    StateGraph stateGraph = GraphMaker.AssaultColonyGraph(Faction.OfMechanoids, false, false);
                    BrainMaker.MakeNewBrain(Faction.OfMechanoids, stateGraph, mechanoidsList);
                }
            }
            Find.LetterStack.ReceiveLetter(eventTitle, eventText, letterType, this.Position);
        }
Пример #10
0
        protected override bool TryExecuteWorker(IncidentParms parms)
        {
            if (!DropCellFinder.TryFindRaidDropCenterClose(out var dropSpot, (Map)parms.target))
            {
                return(false);
            }

            if (!FindAlliedWarringFaction(out var faction))
            {
                return(false);
            }

            if (faction == null)
            {
                return(false);
            }

            var bamboozle           = false;
            var arrivalText         = string.Empty;
            var factionGoodWillLoss = MFI_DiplomacyTunings
                                      .GoodWill_FactionWarPeaceTalks_ImpactSmall.RandomInRange / 2;

            var raidParms =
                StorytellerUtility.DefaultParmsNow(IncidentCategoryDefOf.ThreatBig, (Map)parms.target);

            raidParms.forced          = true;
            raidParms.faction         = faction.EnemyInFactionWar();
            raidParms.raidStrategy    = RaidStrategyDefOf.ImmediateAttack;
            raidParms.raidArrivalMode = PawnsArrivalModeDefOf.CenterDrop;
            raidParms.spawnCenter     = dropSpot;

            if (faction.EnemyInFactionWar().def.techLevel >= TechLevel.Industrial &&
                faction.EnemyInFactionWar().RelationKindWith(Faction.OfPlayer) == FactionRelationKind.Hostile)
            {
                bamboozle = Rand.Chance(0.25f);
            }

            if (bamboozle)
            {
                arrivalText = string.Format(raidParms.raidArrivalMode.textEnemy, raidParms.faction.def.pawnsPlural,
                                            raidParms.faction.Name);
            }

            //get combat-pawns to spawn.
            var defaultPawnGroupMakerParms =
                IncidentParmsUtility.GetDefaultPawnGroupMakerParms(PawnGroupKindDefOf.Combat, raidParms);

            defaultPawnGroupMakerParms.points = IncidentWorker_Raid.AdjustedRaidPoints(
                defaultPawnGroupMakerParms.points, raidParms.raidArrivalMode, raidParms.raidStrategy,
                defaultPawnGroupMakerParms.faction, PawnGroupKindDefOf.Combat);
            IEnumerable <PawnKindDef> pawnKinds =
                PawnGroupMakerUtility.GeneratePawnKindsExample(defaultPawnGroupMakerParms).ToList();
            var pawnlist = new List <Thing>();

            for (var i = 0; i < pawnstoSpawn.RandomInRange; i++)
            {
                var request = new PawnGenerationRequest(pawnKinds.RandomElement(), faction, allowDowned: true,
                                                        allowDead: true, mustBeCapableOfViolence: true);
                var woundedCombatant = PawnGenerator.GeneratePawn(request);
                woundedCombatant.guest.getRescuedThoughtOnUndownedBecauseOfPlayer = true;
                var weapon = Rand.Bool
                    ? DefDatabase <ThingDef> .AllDefsListForReading.Where(x => x.IsWeaponUsingProjectiles).RandomElement()
                    : null;

                var usedWeaponDef = weapon;
                var damageDef     =
                    usedWeaponDef?.Verbs?.First()?.defaultProjectile?.projectile
                    ?.damageDef;     //null? check? All? THE? THINGS!!!!?
                if (usedWeaponDef != null && damageDef == null)
                {
                    usedWeaponDef = null;
                }

                CustomFaction_HealthUtility.DamageUntilDownedWithSpecialOptions(woundedCombatant,
                                                                                true, damageDef, usedWeaponDef);
                //todo: maybe add some story logging.
                pawnlist.Add(woundedCombatant);
            }

            string initialMessage = "MFI_WoundedCombatant".Translate(faction.Name);
            var    diaNode        = new DiaNode(initialMessage);

            var diaOptionOk = new DiaOption("OK".Translate())
            {
                resolveTree = true
            };

            var diaOptionAccept = new DiaOption("RansomDemand_Accept".Translate())
            {
                action = () =>
                {
                    if (bamboozle)
                    {
                        Find.TickManager.slower.SignalForceNormalSpeedShort();
                        IncidentDefOf.RaidEnemy.Worker.TryExecute(raidParms);
                    }
                    else
                    {
                        var intVec = IntVec3.Invalid;

                        var allBuildingsColonist = ((Map)parms.target).listerBuildings.allBuildingsColonist
                                                   .Where(x => x.def.thingClass == typeof(Building_Bed)).ToList();
                        foreach (var building in allBuildingsColonist)
                        {
                            if (DropCellFinder.TryFindDropSpotNear(building.Position, (Map)parms.target,
                                                                   out intVec, false, false))
                            {
                                break;
                            }
                        }

                        if (intVec == IntVec3.Invalid)
                        {
                            intVec = DropCellFinder.RandomDropSpot((Map)parms.target);
                        }

                        DropPodUtility.DropThingsNear(intVec, (Map)parms.target, pawnlist, 180, leaveSlag: true,
                                                      canRoofPunch: false);
                        Find.World.GetComponent <WorldComponent_MFI_FactionWar>().NotifyBattleWon(faction);
                    }
                }
            };
            string bamboozledAndAmbushed = "MFI_WoundedCombatantAmbush".Translate(faction, arrivalText);
            string commanderGreatful     = "MFI_WoundedCombatantGratitude".Translate();
            var    acceptDiaNode         = new DiaNode(bamboozle ? bamboozledAndAmbushed : commanderGreatful);

            diaOptionAccept.link = acceptDiaNode;
            diaNode.options.Add(diaOptionAccept);
            acceptDiaNode.options.Add(diaOptionOk);

            var diaOptionRejection = new DiaOption("RansomDemand_Reject".Translate())
            {
                action = () =>
                {
                    if (bamboozle)
                    {
                        Find.World.GetComponent <WorldComponent_MFI_FactionWar>().NotifyBattleWon(faction);
                    }
                    else
                    {
                        faction.TryAffectGoodwillWith(Faction.OfPlayer, factionGoodWillLoss, false);
                    }
                }
            };
            string rejectionResponse        = "MFI_WoundedCombatantRejected".Translate(faction.Name, factionGoodWillLoss);
            string bamboozlingTheBamboozler = "MFI_WoundedCombatantAmbushAvoided".Translate();
            var    rejectionDiaNode         = new DiaNode(bamboozle ? bamboozlingTheBamboozler : rejectionResponse);

            diaOptionRejection.link = rejectionDiaNode;
            diaNode.options.Add(diaOptionRejection);
            rejectionDiaNode.options.Add(diaOptionOk);

            string title = "MFI_WoundedCombatantTitle".Translate(((Map)parms.target).Parent.Label);

            Find.WindowStack.Add(new Dialog_NodeTreeWithFactionInfo(diaNode, faction, true, true, title));
            Find.Archive.Add(new ArchivedDialog(diaNode.text, title, faction));
            return(true);
        }
Пример #11
0
        public static void DropThingGroupsNear(IntVec3 dropCenter, Map map, List <List <Thing> > thingsGroups, int openDelay = 110, bool instaDrop = false, bool leaveSlag = false, bool canRoofPunch = true, DeepStrikeType strikeType = DeepStrikeType.DropPod, bool scatters = true)
        {
            foreach (List <Thing> list in thingsGroups)
            {
                List <Thing>        list2     = list.Where(x => x.def.thingClass == typeof(Pawn) && (x.Faction != null && x.Faction.def.HasModExtension <FactionDefExtension>())).ToList();
                FactionDefExtension extension = list2.NullOrEmpty() ? null : list2.RandomElement().Faction.def.GetModExtensionFast <FactionDefExtension>();
                if (!DropCellFinder.TryFindDropSpotNear(dropCenter, map, out IntVec3 intVec, true, canRoofPunch) || !scatters)
                {
                    if (scatters)
                    {
                        Log.Warning(string.Concat(new object[]
                        {
                            "DropThingsNear failed to find a place to drop ",
                            list.FirstOrDefault <Thing>(),
                            " near ",
                            dropCenter,
                            ". Dropping on random square instead."
                        }));
                    }
                    intVec = CellFinderLoose.RandomCellWith((IntVec3 c) => c.Walkable(map) && (c.Roofed(map) && c.GetRoof(map) != RoofDefOf.RoofRockThick), map, 1000);
                }
                for (int i = 0; i < list.Count; i++)
                {
                    list[i].SetForbidden(true, false);
                }
                if (instaDrop)
                {
                    foreach (Thing thing in list)
                    {
                        GenPlace.TryPlaceThing(thing, intVec, map, ThingPlaceMode.Near, null, null);
                    }
                }
                else
                {
                    ActiveDropPodInfo activeDropPodInfo = new ActiveDropPodInfo();
                    foreach (Thing item in list)
                    {
                        activeDropPodInfo.innerContainer.TryAddOrTransfer(item, true);
                    }
                    activeDropPodInfo.openDelay = openDelay;
                    activeDropPodInfo.leaveSlag = leaveSlag;

                    switch (strikeType)
                    {
                    /*
                     * case DeepStrikeType.DropPara:
                     *  DeepStrikeUtility.MakeDropParaAt(intVec, map, activeDropPodInfo, extension);
                     *  break;
                     * case DeepStrikeType.DropShip:
                     *  DeepStrikeUtility.MakeDropShipLandAt(intVec, map, activeDropPodInfo, extension);
                     *  break;
                     */
                    case DeepStrikeType.Fly:
                        DeepStrikeUtility.MakeFlyerLandAt(intVec, map, activeDropPodInfo, extension);
                        break;

                    case DeepStrikeType.Teleport:
                        DeepStrikeUtility.MakeTeleportAt(intVec, map, activeDropPodInfo, extension);
                        break;

                    case DeepStrikeType.Tunnel:
                        DeepStrikeUtility.MakeTunnelAt(intVec, map, activeDropPodInfo, extension);
                        break;

                    default:
                        DeepStrikeUtility.MakeDropPodAt(intVec, map, activeDropPodInfo, extension);
                        break;
                    }
                }
            }
        }
Пример #12
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            yield return(Toils_Reserve.Reserve(terraformerIndex));

            yield return(Toils_Goto.GotoCell(terraformerIndex, PathEndMode.InteractionCell).FailOnDestroyed(terraformerIndex));

            yield return(Toils_General.Wait(240).FailOnDestroyed(terraformerIndex));

            Toil scytherScoutsArrivalToil = new Toil()
            {
                initAction = () =>
                {
                    IntVec3     spawningCell;
                    List <Pawn> scytherScoutsList = new List <Pawn>();
                    for (int scytherIndex = 0; scytherIndex < 4; scytherIndex++)
                    {
                        bool validDropPodCellIsFound = DropCellFinder.TryFindDropSpotNear(this.TargetThingA.InteractionCell, out spawningCell, true, true);
                        if (validDropPodCellIsFound)
                        {
                            Faction faction      = Faction.OfMechanoids;
                            Pawn    scytherScout = PawnGenerator.GeneratePawn(PawnKindDef.Named("Scyther"), faction);
                            scytherScoutsList.Add(scytherScout);
                            DropPodUtility.MakeDropPodAt(spawningCell, new DropPodInfo
                            {
                                SingleContainedThing = scytherScout,
                                openDelay            = 600,
                                leaveSlag            = false
                            });
                        }
                    }
                    StateGraph stateGraph = GraphMaker.MechanoidsDefendShipGraph(this.TargetThingA, defensiveRadiusAroundTerraformer);
                    BrainMaker.MakeNewBrain(Faction.OfMechanoids, stateGraph, scytherScoutsList);
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            };

            yield return(scytherScoutsArrivalToil);

            Toil pawnEscapingToil = new Toil()
            {
                initAction = () =>
                {
                    (this.TargetThingA as Building_MechanoidTerraformer).reverseEngineeringState = Building_MechanoidTerraformer.ReverseEngineeringState.BuildingNotSecured;

                    ThingRequest thingRequest = new ThingRequest();
                    thingRequest.singleDef = ThingDefOf.CommsConsole;
                    Thing commsConsole = GenClosest.ClosestThingReachable(pawn.Position, thingRequest, PathEndMode.InteractionCell, TraverseParms.For(pawn));
                    if (commsConsole != null)
                    {
                        pawn.pather.StartPath(commsConsole, PathEndMode.InteractionCell);
                    }
                    else
                    {
                        // The player has no comms console. He should move his colonist manually... and fast!
                        pawn.pather.StartPath(pawn.Position, PathEndMode.OnCell);
                    }

                    string herHimOrIt = "it";
                    string sheHeOrIt  = "it";
                    if (pawn.gender == Gender.Female)
                    {
                        herHimOrIt = "her";
                        sheHeOrIt  = "she";
                    }
                    else if (pawn.gender == Gender.Male)
                    {
                        herHimOrIt = "him";
                        sheHeOrIt  = "he";
                    }
                    string eventText = "   " + pawn.Name.ToStringShort + " is just arriving near the strange building when " + sheHeOrIt + " hears the loud noise of incoming drop pods.\n\n"
                                       + "You should better take " + herHimOrIt + " to safety... and fast!\n";
                    Find.LetterStack.ReceiveLetter("Drop pods", eventText, LetterType.BadUrgent, this.pawn.Position);
                },
                defaultCompleteMode = ToilCompleteMode.PatherArrival
            };

            yield return(pawnEscapingToil);

            yield return(Toils_Reserve.Release(terraformerIndex));
        }