private bool IsRotationValid(IntVec3 loc, Rot4 rot, Map map)
 {
     return(GenAdj.OccupiedRect(loc, rot, this.thingDef.size).InBounds(map) && !GenSpawn.WouldWipeAnythingWith(loc, rot, this.thingDef, map, (Thing x) => x.def == this.thingDef || (x.def.category != ThingCategory.Plant && x.def.category != ThingCategory.Filth)));
 }
Beispiel #2
0
        private static PlaceSpotQuality PlaceSpotQualityAt(IntVec3 c, Rot4 rot, Map map, Thing thing, IntVec3 center, bool allowStacking, Predicate <IntVec3> extraValidator = null)
        {
            if (!c.InBounds(map) || !c.Walkable(map))
            {
                return(PlaceSpotQuality.Unusable);
            }
            if (!GenAdj.OccupiedRect(c, rot, thing.def.Size).InBounds(map))
            {
                return(PlaceSpotQuality.Unusable);
            }
            if (extraValidator != null && !extraValidator(c))
            {
                return(PlaceSpotQuality.Unusable);
            }
            List <Thing> list = map.thingGrid.ThingsListAt(c);

            for (int i = 0; i < list.Count; i++)
            {
                Thing thing2 = list[i];
                if (thing.def.saveCompressible && thing2.def.saveCompressible)
                {
                    return(PlaceSpotQuality.Unusable);
                }
                if (thing.def.category == ThingCategory.Item && thing2.def.category == ThingCategory.Item && (!thing2.CanStackWith(thing) || thing2.stackCount >= thing.def.stackLimit))
                {
                    return(PlaceSpotQuality.Unusable);
                }
            }
            if (thing is Building)
            {
                foreach (IntVec3 item in GenAdj.OccupiedRect(c, rot, thing.def.size))
                {
                    Building edifice = item.GetEdifice(map);
                    if (edifice != null && GenSpawn.SpawningWipes(thing.def, edifice.def))
                    {
                        return(PlaceSpotQuality.Awful);
                    }
                }
            }
            if (c.GetRoom(map) != center.GetRoom(map))
            {
                if (!map.reachability.CanReach(center, c, PathEndMode.OnCell, TraverseMode.PassDoors, Danger.Deadly))
                {
                    return(PlaceSpotQuality.Awful);
                }
                return(PlaceSpotQuality.Bad);
            }
            if (allowStacking)
            {
                for (int j = 0; j < list.Count; j++)
                {
                    Thing thing3 = list[j];
                    if (thing3.def.category == ThingCategory.Item && thing3.CanStackWith(thing) && thing3.stackCount < thing.def.stackLimit)
                    {
                        return(PlaceSpotQuality.Perfect);
                    }
                }
            }
            bool             flag             = (thing as Pawn)?.Downed ?? false;
            PlaceSpotQuality placeSpotQuality = PlaceSpotQuality.Perfect;

            for (int k = 0; k < list.Count; k++)
            {
                Thing thing4 = list[k];
                if (thing4.def.IsDoor)
                {
                    return(PlaceSpotQuality.Bad);
                }
                if (thing4 is Building_WorkTable)
                {
                    return(PlaceSpotQuality.Bad);
                }
                Pawn pawn = thing4 as Pawn;
                if (pawn != null)
                {
                    if (pawn.Downed || flag)
                    {
                        return(PlaceSpotQuality.Bad);
                    }
                    if ((int)placeSpotQuality > 3)
                    {
                        placeSpotQuality = PlaceSpotQuality.Okay;
                    }
                }
                if (thing4.def.category == ThingCategory.Plant && thing4.def.selectable && (int)placeSpotQuality > 3)
                {
                    placeSpotQuality = PlaceSpotQuality.Okay;
                }
            }
            return(placeSpotQuality);
        }
 public static Thing Spawn(ThingDef def, IntVec3 loc, Map map)
 {
     return(GenSpawn.Spawn(ThingMaker.MakeThing(def, null), loc, map));
 }
        protected override bool TryCastShot()
        {
            if (currentTarget.HasThing && currentTarget.Thing.Map != caster.Map)
            {
                return(false);
            }
            ThingDef projectile = Projectile;

            if (projectile == null)
            {
                return(false);
            }
            ShootLine resultingLine;
            bool      flag = TryFindShootLineFromTo(caster.Position, currentTarget, out resultingLine);

            if (verbProps.stopBurstWithoutLos && !flag)
            {
                return(false);
            }
            if (base.EquipmentSource != null)
            {
                base.EquipmentSource.GetComp <CompChangeableProjectile>()?.Notify_ProjectileLaunched();
            }
            Thing        launcher     = caster;
            Thing        equipment    = base.EquipmentSource;
            CompMannable compMannable = caster.TryGetComp <CompMannable>();

            if (compMannable != null && compMannable.ManningPawn != null)
            {
                launcher  = compMannable.ManningPawn;
                equipment = caster;
            }
            Vector3    drawPos     = caster.DrawPos;
            Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, resultingLine.Source, caster.Map);

            if (verbProps.forcedMissRadius > 0.5f)
            {
                float num = VerbUtility.CalculateAdjustedForcedMiss(verbProps.forcedMissRadius, currentTarget.Cell - caster.Position);
                if (num > 0.5f)
                {
                    int max  = GenRadial.NumCellsInRadius(num);
                    int num2 = Rand.Range(0, max);
                    if (num2 > 0)
                    {
                        IntVec3 c = currentTarget.Cell + GenRadial.RadialPattern[num2];
                        ThrowDebugText("ToRadius");
                        ThrowDebugText("Rad\nDest", c);
                        ProjectileHitFlags projectileHitFlags = ProjectileHitFlags.NonTargetWorld;
                        if (Rand.Chance(0.5f))
                        {
                            projectileHitFlags = ProjectileHitFlags.All;
                        }
                        if (!canHitNonTargetPawnsNow)
                        {
                            projectileHitFlags &= ~ProjectileHitFlags.NonTargetPawns;
                        }
                        projectile2.Launch(launcher, drawPos, c, currentTarget, projectileHitFlags, equipment);
                        return(true);
                    }
                }
            }
            ShotReport shotReport            = ShotReport.HitReportFor(caster, this, currentTarget);
            Thing      randomCoverToMissInto = shotReport.GetRandomCoverToMissInto();
            ThingDef   targetCoverDef        = randomCoverToMissInto?.def;

            if (!Rand.Chance(shotReport.AimOnTargetChance_IgnoringPosture))
            {
                resultingLine.ChangeDestToMissWild(shotReport.AimOnTargetChance_StandardTarget);
                ThrowDebugText("ToWild" + ((!canHitNonTargetPawnsNow) ? string.Empty : "\nchntp"));
                ThrowDebugText("Wild\nDest", resultingLine.Dest);
                ProjectileHitFlags projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld;
                if (Rand.Chance(0.5f) && canHitNonTargetPawnsNow)
                {
                    projectileHitFlags2 |= ProjectileHitFlags.NonTargetPawns;
                }
                projectile2.Launch(launcher, drawPos, resultingLine.Dest, currentTarget, projectileHitFlags2, equipment, targetCoverDef);
                return(true);
            }
            if (currentTarget.Thing != null && currentTarget.Thing.def.category == ThingCategory.Pawn && !Rand.Chance(shotReport.PassCoverChance))
            {
                ThrowDebugText("ToCover" + ((!canHitNonTargetPawnsNow) ? string.Empty : "\nchntp"));
                ThrowDebugText("Cover\nDest", randomCoverToMissInto.Position);
                ProjectileHitFlags projectileHitFlags3 = ProjectileHitFlags.NonTargetWorld;
                if (canHitNonTargetPawnsNow)
                {
                    projectileHitFlags3 |= ProjectileHitFlags.NonTargetPawns;
                }
                projectile2.Launch(launcher, drawPos, randomCoverToMissInto, currentTarget, projectileHitFlags3, equipment, targetCoverDef);
                return(true);
            }
            ProjectileHitFlags projectileHitFlags4 = ProjectileHitFlags.IntendedTarget;

            if (canHitNonTargetPawnsNow)
            {
                projectileHitFlags4 |= ProjectileHitFlags.NonTargetPawns;
            }
            if (!currentTarget.HasThing || currentTarget.Thing.def.Fillage == FillCategory.Full)
            {
                projectileHitFlags4 |= ProjectileHitFlags.NonTargetWorld;
            }
            ThrowDebugText("ToHit" + ((!canHitNonTargetPawnsNow) ? string.Empty : "\nchntp"));
            if (currentTarget.Thing != null)
            {
                projectile2.Launch(launcher, drawPos, currentTarget, currentTarget, projectileHitFlags4, equipment, targetCoverDef);
                ThrowDebugText("Hit\nDest", currentTarget.Cell);
            }
            else
            {
                projectile2.Launch(launcher, drawPos, resultingLine.Dest, currentTarget, projectileHitFlags4, equipment, targetCoverDef);
                ThrowDebugText("Hit\nDest", resultingLine.Dest);
            }
            return(true);
        }
        public static bool SpawningWipes(BuildableDef newEntDef, BuildableDef oldEntDef)
        {
            ThingDef thingDef  = newEntDef as ThingDef;
            ThingDef thingDef2 = oldEntDef as ThingDef;

            if (thingDef != null && thingDef2 != null)
            {
                if (thingDef.category != ThingCategory.Attachment && thingDef.category != ThingCategory.Mote && thingDef.category != ThingCategory.Filth && thingDef.category != ThingCategory.Projectile)
                {
                    if (!thingDef2.destroyable)
                    {
                        return(false);
                    }
                    if (thingDef.category == ThingCategory.Plant)
                    {
                        return(false);
                    }
                    if (thingDef2.category == ThingCategory.Filth && thingDef.passability != 0)
                    {
                        return(true);
                    }
                    if (thingDef2.category == ThingCategory.Item && thingDef.passability == Traversability.Impassable && thingDef.surfaceType == SurfaceType.None)
                    {
                        return(true);
                    }
                    if (thingDef.EverTransmitsPower && thingDef2 == ThingDefOf.PowerConduit)
                    {
                        return(true);
                    }
                    if (thingDef.IsFrame && GenSpawn.SpawningWipes(thingDef.entityDefToBuild, oldEntDef))
                    {
                        return(true);
                    }
                    BuildableDef buildableDef  = GenConstruct.BuiltDefOf(thingDef);
                    BuildableDef buildableDef2 = GenConstruct.BuiltDefOf(thingDef2);
                    if (buildableDef != null && buildableDef2 != null)
                    {
                        ThingDef thingDef3 = thingDef.entityDefToBuild as ThingDef;
                        if (thingDef2.IsBlueprint)
                        {
                            if (thingDef.IsBlueprint)
                            {
                                if (thingDef3 != null && thingDef3.building != null && thingDef3.building.canPlaceOverWall && thingDef2.entityDefToBuild is ThingDef && (ThingDef)thingDef2.entityDefToBuild == ThingDefOf.Wall)
                                {
                                    return(true);
                                }
                                if (thingDef2.entityDefToBuild is TerrainDef)
                                {
                                    if (thingDef.entityDefToBuild is ThingDef && ((ThingDef)thingDef.entityDefToBuild).coversFloor)
                                    {
                                        return(true);
                                    }
                                    if (thingDef.entityDefToBuild is TerrainDef)
                                    {
                                        return(true);
                                    }
                                }
                            }
                            if (thingDef2.entityDefToBuild == ThingDefOf.PowerConduit && thingDef.entityDefToBuild is ThingDef && (thingDef.entityDefToBuild as ThingDef).EverTransmitsPower)
                            {
                                return(true);
                            }
                            return(false);
                        }
                        if ((thingDef2.IsFrame || thingDef2.IsBlueprint) && thingDef2.entityDefToBuild is TerrainDef)
                        {
                            ThingDef thingDef4 = buildableDef as ThingDef;
                            if (thingDef4 != null && !thingDef4.CoexistsWithFloors)
                            {
                                return(true);
                            }
                        }
                        if (thingDef2 == ThingDefOf.ActiveDropPod)
                        {
                            return(false);
                        }
                        if (thingDef == ThingDefOf.ActiveDropPod)
                        {
                            if (thingDef2 == ThingDefOf.ActiveDropPod)
                            {
                                return(false);
                            }
                            if (thingDef2.category == ThingCategory.Building && thingDef2.passability == Traversability.Impassable)
                            {
                                return(true);
                            }
                            return(false);
                        }
                        if (thingDef.IsEdifice())
                        {
                            if (thingDef.BlockPlanting && thingDef2.category == ThingCategory.Plant)
                            {
                                return(true);
                            }
                            if (!(buildableDef is TerrainDef) && buildableDef2.IsEdifice())
                            {
                                return(true);
                            }
                        }
                        return(false);
                    }
                    return(false);
                }
                return(false);
            }
            return(false);
        }
        public static void SpawnBuildingAsPossible(Building building, Map map, bool respawningAfterLoad = false)
        {
            bool flag = false;

            foreach (IntVec3 item in building.OccupiedRect())
            {
                List <Thing> thingList = item.GetThingList(map);
                int          num       = 0;
                while (num < thingList.Count)
                {
                    if (!(thingList[num] is Pawn) || building.def.passability != Traversability.Impassable)
                    {
                        if ((thingList[num].def.category == ThingCategory.Building || thingList[num].def.category == ThingCategory.Item) && GenSpawn.SpawningWipes(building.def, thingList[num].def))
                        {
                            flag = true;
                            break;
                        }
                        num++;
                        continue;
                    }
                    flag = true;
                    break;
                }
                if (flag)
                {
                    break;
                }
            }
            if (flag)
            {
                bool flag2 = false;
                if (building.def.Minifiable)
                {
                    MinifiedThing minifiedThing = building.MakeMinified();
                    if (GenPlace.TryPlaceThing(minifiedThing, building.Position, map, ThingPlaceMode.Near, null))
                    {
                        flag2 = true;
                    }
                    else
                    {
                        minifiedThing.GetDirectlyHeldThings().Clear();
                        minifiedThing.Destroy(DestroyMode.Vanish);
                    }
                }
                if (!flag2)
                {
                    GenLeaving.DoLeavingsFor(building, map, DestroyMode.Refund, building.OccupiedRect());
                }
            }
            else
            {
                GenSpawn.Spawn(building, building.Position, map, building.Rotation, respawningAfterLoad);
            }
        }
 public static bool WouldWipeAnythingWith(IntVec3 thingPos, Rot4 thingRot, BuildableDef thingDef, Map map, Predicate <Thing> predicate)
 {
     return(GenSpawn.WouldWipeAnythingWith(GenAdj.OccupiedRect(thingPos, thingRot, thingDef.Size), thingDef, map, predicate));
 }
 public static Thing Spawn(Thing newThing, IntVec3 loc, Map map)
 {
     return(GenSpawn.Spawn(newThing, loc, map, Rot4.North, false));
 }
Beispiel #9
0
        public static IntVec3 FindNoWipeSpawnLocNear(IntVec3 near, Map map, ThingDef thingToSpawn, Rot4 rot, int maxDist = 2, Predicate <IntVec3> extraValidator = null)
        {
            int     num    = GenRadial.NumCellsInRadius((float)maxDist);
            IntVec3 intVec = IntVec3.Invalid;
            float   num2   = 0f;

            for (int i = 0; i < num; i++)
            {
                IntVec3 intVec2 = near + GenRadial.RadialPattern[i];
                if (intVec2.InBounds(map))
                {
                    CellRect cellRect = GenAdj.OccupiedRect(intVec2, rot, thingToSpawn.size);
                    if (cellRect.InBounds(map))
                    {
                        if (GenSight.LineOfSight(near, intVec2, map, true, null, 0, 0))
                        {
                            if (extraValidator == null || extraValidator(intVec2))
                            {
                                if (thingToSpawn.category != ThingCategory.Building || GenConstruct.CanBuildOnTerrain(thingToSpawn, intVec2, map, rot, null))
                                {
                                    bool flag  = false;
                                    bool flag2 = false;
                                    CellFinder.tmpUniqueWipedThings.Clear();
                                    CellRect.CellRectIterator iterator = cellRect.GetIterator();
                                    while (!iterator.Done())
                                    {
                                        if (iterator.Current.Impassable(map))
                                        {
                                            flag2 = true;
                                        }
                                        List <Thing> thingList = iterator.Current.GetThingList(map);
                                        for (int j = 0; j < thingList.Count; j++)
                                        {
                                            if (thingList[j] is Pawn)
                                            {
                                                flag = true;
                                            }
                                            else if (GenSpawn.SpawningWipes(thingToSpawn, thingList[j].def) && !CellFinder.tmpUniqueWipedThings.Contains(thingList[j]))
                                            {
                                                CellFinder.tmpUniqueWipedThings.Add(thingList[j]);
                                            }
                                        }
                                        iterator.MoveNext();
                                    }
                                    if (flag && thingToSpawn.passability == Traversability.Impassable)
                                    {
                                        CellFinder.tmpUniqueWipedThings.Clear();
                                    }
                                    else if (flag2 && thingToSpawn.category == ThingCategory.Item)
                                    {
                                        CellFinder.tmpUniqueWipedThings.Clear();
                                    }
                                    else
                                    {
                                        float num3 = 0f;
                                        for (int k = 0; k < CellFinder.tmpUniqueWipedThings.Count; k++)
                                        {
                                            if (CellFinder.tmpUniqueWipedThings[k].def.category == ThingCategory.Building && !CellFinder.tmpUniqueWipedThings[k].def.costList.NullOrEmpty <ThingDefCountClass>() && CellFinder.tmpUniqueWipedThings[k].def.costStuffCount == 0)
                                            {
                                                List <ThingDefCountClass> list = CellFinder.tmpUniqueWipedThings[k].CostListAdjusted();
                                                for (int l = 0; l < list.Count; l++)
                                                {
                                                    num3 += list[l].thingDef.GetStatValueAbstract(StatDefOf.MarketValue, null) * (float)list[l].count * (float)CellFinder.tmpUniqueWipedThings[k].stackCount;
                                                }
                                            }
                                            else
                                            {
                                                num3 += CellFinder.tmpUniqueWipedThings[k].MarketValue * (float)CellFinder.tmpUniqueWipedThings[k].stackCount;
                                            }
                                            if (CellFinder.tmpUniqueWipedThings[k].def.category == ThingCategory.Building || CellFinder.tmpUniqueWipedThings[k].def.category == ThingCategory.Item)
                                            {
                                                num3 = Mathf.Max(num3, 0.001f);
                                            }
                                        }
                                        CellFinder.tmpUniqueWipedThings.Clear();
                                        if (!intVec.IsValid || num3 < num2)
                                        {
                                            if (num3 == 0f)
                                            {
                                                return(intVec2);
                                            }
                                            intVec = intVec2;
                                            num2   = num3;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return((!intVec.IsValid) ? near : intVec);
        }
        public static Thing Spawn(Thing newThing, IntVec3 loc, Map map, Rot4 rot, WipeMode wipeMode = WipeMode.Vanish, bool respawningAfterLoad = false)
        {
            if (map == null)
            {
                Log.Error("Tried to spawn " + newThing.ToStringSafe <Thing>() + " in a null map.", false);
                return(null);
            }
            if (!loc.InBounds(map))
            {
                Log.Error(string.Concat(new object[]
                {
                    "Tried to spawn ",
                    newThing.ToStringSafe <Thing>(),
                    " out of bounds at ",
                    loc,
                    "."
                }), false);
                return(null);
            }
            if (newThing.def.randomizeRotationOnSpawn)
            {
                rot = Rot4.Random;
            }
            CellRect occupiedRect = GenAdj.OccupiedRect(loc, rot, newThing.def.Size);

            if (!occupiedRect.InBounds(map))
            {
                Log.Error(string.Concat(new object[]
                {
                    "Tried to spawn ",
                    newThing.ToStringSafe <Thing>(),
                    " out of bounds at ",
                    loc,
                    " (out of bounds because size is ",
                    newThing.def.Size,
                    ")."
                }), false);
                return(null);
            }
            if (newThing.Spawned)
            {
                Log.Error("Tried to spawn " + newThing + " but it's already spawned.", false);
                return(newThing);
            }
            if (wipeMode == WipeMode.Vanish)
            {
                GenSpawn.WipeExistingThings(loc, rot, newThing.def, map, DestroyMode.Vanish);
            }
            else if (wipeMode == WipeMode.FullRefund)
            {
                GenSpawn.WipeAndRefundExistingThings(loc, rot, newThing.def, map);
            }
            if (newThing.def.category == ThingCategory.Item)
            {
                foreach (IntVec3 intVec in occupiedRect)
                {
                    foreach (Thing thing in intVec.GetThingList(map).ToList <Thing>())
                    {
                        if (thing != newThing)
                        {
                            if (thing.def.category == ThingCategory.Item)
                            {
                                thing.DeSpawn(DestroyMode.Vanish);
                                if (!GenPlace.TryPlaceThing(thing, intVec, map, ThingPlaceMode.Near, null, (IntVec3 x) => !occupiedRect.Contains(x)))
                                {
                                    thing.Destroy(DestroyMode.Vanish);
                                }
                            }
                        }
                    }
                }
            }
            newThing.Rotation = rot;
            newThing.Position = loc;
            if (newThing.holdingOwner != null)
            {
                newThing.holdingOwner.Remove(newThing);
            }
            newThing.SpawnSetup(map, respawningAfterLoad);
            if (newThing.Spawned && newThing.stackCount == 0)
            {
                Log.Error("Spawned thing with 0 stackCount: " + newThing, false);
                newThing.Destroy(DestroyMode.Vanish);
                return(null);
            }
            if (newThing.def.passability == Traversability.Impassable)
            {
                foreach (IntVec3 c in occupiedRect)
                {
                    foreach (Thing thing2 in c.GetThingList(map).ToList <Thing>())
                    {
                        if (thing2 != newThing)
                        {
                            Pawn pawn = thing2 as Pawn;
                            if (pawn != null)
                            {
                                pawn.pather.TryRecoverFromUnwalkablePosition(false);
                            }
                        }
                    }
                }
            }
            return(newThing);
        }
 public static Thing Spawn(Thing newThing, IntVec3 loc, Map map, WipeMode wipeMode = WipeMode.Vanish)
 {
     return(GenSpawn.Spawn(newThing, loc, map, Rot4.North, wipeMode, false));
 }
        public static void SpawnBuildingAsPossible(Building building, Map map, bool respawningAfterLoad = false)
        {
            bool flag = false;

            if (!building.OccupiedRect().InBounds(map))
            {
                flag = true;
            }
            else
            {
                foreach (IntVec3 c in building.OccupiedRect())
                {
                    List <Thing> thingList = c.GetThingList(map);
                    for (int i = 0; i < thingList.Count; i++)
                    {
                        if (thingList[i] is Pawn && building.def.passability == Traversability.Impassable)
                        {
                            flag = true;
                            break;
                        }
                        if ((thingList[i].def.category == ThingCategory.Building || thingList[i].def.category == ThingCategory.Item) && GenSpawn.SpawningWipes(building.def, thingList[i].def))
                        {
                            flag = true;
                            break;
                        }
                    }
                    if (flag)
                    {
                        break;
                    }
                }
            }
            if (flag)
            {
                GenSpawn.Refund(building, map, CellRect.Empty);
            }
            else
            {
                GenSpawn.Spawn(building, building.Position, map, building.Rotation, WipeMode.FullRefund, respawningAfterLoad);
            }
        }
 public static Thing Spawn(ThingDef def, IntVec3 loc, Map map, WipeMode wipeMode = WipeMode.Vanish)
 {
     return(GenSpawn.Spawn(ThingMaker.MakeThing(def, null), loc, map, wipeMode));
 }