示例#1
0
        public virtual bool TryAbsorbStack(Thing other, bool respectStackLimit)
        {
            if (!CanStackWith(other))
            {
                return(false);
            }
            int num = ThingUtility.TryAbsorbStackNumToTake(this, other, respectStackLimit);

            if (def.useHitPoints)
            {
                HitPoints = Mathf.CeilToInt((float)(HitPoints * stackCount + other.HitPoints * num) / (float)(stackCount + num));
            }
            stackCount       += num;
            other.stackCount -= num;
            StealAIDebugDrawer.Notify_ThingChanged(this);
            if (Spawned)
            {
                Map.listerMergeables.Notify_ThingStackChanged(this);
            }
            if (other.stackCount <= 0)
            {
                other.Destroy();
                return(true);
            }
            return(false);
        }
示例#2
0
        /// <summary>
        /// destroying a resource outright causes too much overhead: fog, area reveal, pathing, roof updates, etc
        ///	we just want to replace it. So, we manually strip it out of the map and do some cleanup.
        /// The following is Thing.Despawn code with the unnecessary (for buildings, ar least) parts stripped out, plus key parts from Building.Despawn
        /// TODO: This approach may break with future releases (if thing despawning changes), so it's worth checking over.
        /// </summary>
        private static void SneakilyDestroyResource(Thing res)
        {
            var map = res.Map;

            RegionListersUpdater.DeregisterInRegions(res, map);
            map.spawnedThings.Remove(res);
            map.listerThings.Remove(res);
            map.thingGrid.Deregister(res);
            map.coverGrid.DeRegister(res);
            map.tooltipGiverList.Notify_ThingDespawned(res);
            if (res.def.graphicData != null && res.def.graphicData.Linked)
            {
                map.linkGrid.Notify_LinkerCreatedOrDestroyed(res);
                map.mapDrawer.MapMeshDirty(res.Position, MapMeshFlag.Things, true, false);
            }
            Find.Selector.Deselect(res);
            res.DirtyMapMesh(map);
            if (res.def.drawerType != DrawerType.MapMeshOnly)
            {
                map.dynamicDrawManager.DeRegisterDrawable(res);
            }
            ReflectionCache.Thing_State.SetValue(res, res.def.DiscardOnDestroyed ? ThingDiscardedState : ThingMemoryState);
            Find.TickManager.DeRegisterAllTickabilityFor(res);
            map.attackTargetsCache.Notify_ThingDespawned(res);
            StealAIDebugDrawer.Notify_ThingChanged(res);
            // building-specific cleanup
            var b = (Building)res;

            if (res.def.IsEdifice())
            {
                map.edificeGrid.DeRegister(b);
            }
            var sustainer = (Sustainer)ReflectionCache.Building_SustainerAmbient.GetValue(res);

            if (sustainer != null)
            {
                sustainer.End();
            }
            map.mapDrawer.MapMeshDirty(b.Position, MapMeshFlag.Buildings);
            map.glowGrid.MarkGlowGridDirty(b.Position);
            map.listerBuildings.Remove((Building)res);
            map.listerBuildingsRepairable.Notify_BuildingDeSpawned(b);
            map.designationManager.Notify_BuildingDespawned(b);
        }
示例#3
0
        public virtual bool TryAbsorbStack(Thing other, bool respectStackLimit)
        {
            if (!this.CanStackWith(other))
            {
                return(false);
            }
            int num = ThingUtility.TryAbsorbStackNumToTake(this, other, respectStackLimit);

            if (this.def.useHitPoints)
            {
                this.HitPoints = Mathf.CeilToInt((float)(this.HitPoints * this.stackCount + other.HitPoints * num) / (float)(this.stackCount + num));
            }
            this.stackCount  += num;
            other.stackCount -= num;
            StealAIDebugDrawer.Notify_ThingChanged(this);
            if (other.stackCount <= 0)
            {
                other.Destroy(DestroyMode.Vanish);
                return(true);
            }
            return(false);
        }
示例#4
0
 public override void DeSpawn()
 {
     if (this.Destroyed)
     {
         Log.Error("Tried to despawn " + this.ToStringSafe() + " which is already destroyed.");
     }
     else if (!this.Spawned)
     {
         Log.Error("Tried to despawn " + this.ToStringSafe() + " which is not spawned.");
     }
     else
     {
         Map map = this.Map;
         RegionListersUpdater.DeregisterInRegions(this, map);
         map.spawnedThings.Remove(this);
         map.listerThings.Remove(this);
         map.thingGrid.Deregister(this, false);
         map.coverGrid.DeRegister(this);
         if (this.def.receivesSignals)
         {
             Find.SignalManager.DeregisterReceiver(this);
         }
         map.tooltipGiverList.Notify_ThingDespawned(this);
         if (this.def.graphicData != null && this.def.graphicData.Linked)
         {
             map.linkGrid.Notify_LinkerCreatedOrDestroyed(this);
             map.mapDrawer.MapMeshDirty(this.Position, MapMeshFlag.Things, true, false);
         }
         Find.Selector.Deselect(this);
         this.DirtyMapMesh(map);
         if (this.def.drawerType != DrawerType.MapMeshOnly)
         {
             map.dynamicDrawManager.DeRegisterDrawable(this);
         }
         Region validRegionAt_NoRebuild = map.regionGrid.GetValidRegionAt_NoRebuild(this.Position);
         Room   room = (validRegionAt_NoRebuild != null) ? validRegionAt_NoRebuild.Room : null;
         if (room != null)
         {
             room.Notify_ContainedThingSpawnedOrDespawned(this);
         }
         if (this.def.AffectsRegions)
         {
             map.regionDirtyer.Notify_ThingAffectingRegionsDespawned(this);
         }
         if (this.def.pathCost != 0 || this.def.passability == Traversability.Impassable)
         {
             map.pathGrid.RecalculatePerceivedPathCostUnderThing(this);
         }
         if (this.def.AffectsReachability)
         {
             map.reachability.ClearCache();
         }
         Find.TickManager.DeRegisterAllTickabilityFor(this);
         this.mapIndexOrState = -1;
         if (this.def.category == ThingCategory.Item)
         {
             map.listerHaulables.Notify_DeSpawned(this);
         }
         map.attackTargetsCache.Notify_ThingDespawned(this);
         StealAIDebugDrawer.Notify_ThingChanged(this);
         if (this is IThingHolder && Find.ColonistBar != null)
         {
             Find.ColonistBar.MarkColonistsDirty();
         }
         if (this.def.category == ThingCategory.Item)
         {
             SlotGroup slotGroup = this.Position.GetSlotGroup(map);
             if (slotGroup != null && slotGroup.parent != null)
             {
                 slotGroup.parent.Notify_LostThing(this);
             }
         }
     }
 }
示例#5
0
 public override void SpawnSetup(Map map, bool respawningAfterLoad)
 {
     if (this.Destroyed)
     {
         Log.Error("Spawning destroyed thing " + this + " at " + this.Position + ". Correcting.");
         this.mapIndexOrState = -1;
         if (this.HitPoints <= 0 && this.def.useHitPoints)
         {
             this.HitPoints = 1;
         }
     }
     if (this.Spawned)
     {
         Log.Error("Tried to spawn already-spawned thing " + this + " at " + this.Position);
     }
     else
     {
         int num = Find.Maps.IndexOf(map);
         if (num < 0)
         {
             Log.Error("Tried to spawn thing " + this + ", but the map provided does not exist.");
         }
         else
         {
             if (this.stackCount > this.def.stackLimit)
             {
                 Log.Error("Spawned " + this + " with stackCount " + this.stackCount + " but stackLimit is " + this.def.stackLimit + ". Truncating.");
                 this.stackCount = this.def.stackLimit;
             }
             this.mapIndexOrState = (sbyte)num;
             RegionListersUpdater.RegisterInRegions(this, map);
             if (!map.spawnedThings.TryAdd(this, false))
             {
                 Log.Error("Couldn't add thing " + this + " to spawned things.");
             }
             map.listerThings.Add(this);
             map.thingGrid.Register(this);
             if (Find.TickManager != null)
             {
                 Find.TickManager.RegisterAllTickabilityFor(this);
             }
             this.DirtyMapMesh(map);
             if (this.def.drawerType != DrawerType.MapMeshOnly)
             {
                 map.dynamicDrawManager.RegisterDrawable(this);
             }
             map.tooltipGiverList.Notify_ThingSpawned(this);
             if (this.def.graphicData != null && this.def.graphicData.Linked)
             {
                 map.linkGrid.Notify_LinkerCreatedOrDestroyed(this);
                 map.mapDrawer.MapMeshDirty(this.Position, MapMeshFlag.Things, true, false);
             }
             if (!this.def.CanOverlapZones)
             {
                 map.zoneManager.Notify_NoZoneOverlapThingSpawned(this);
             }
             if (this.def.AffectsRegions)
             {
                 map.regionDirtyer.Notify_ThingAffectingRegionsSpawned(this);
             }
             if (this.def.pathCost != 0 || this.def.passability == Traversability.Impassable)
             {
                 map.pathGrid.RecalculatePerceivedPathCostUnderThing(this);
             }
             if (this.def.AffectsReachability)
             {
                 map.reachability.ClearCache();
             }
             map.coverGrid.Register(this);
             if (this.def.category == ThingCategory.Item)
             {
                 map.listerHaulables.Notify_Spawned(this);
             }
             map.attackTargetsCache.Notify_ThingSpawned(this);
             Region validRegionAt_NoRebuild = map.regionGrid.GetValidRegionAt_NoRebuild(this.Position);
             Room   room = (validRegionAt_NoRebuild != null) ? validRegionAt_NoRebuild.Room : null;
             if (room != null)
             {
                 room.Notify_ContainedThingSpawnedOrDespawned(this);
             }
             StealAIDebugDrawer.Notify_ThingChanged(this);
             if (this is IThingHolder && Find.ColonistBar != null)
             {
                 Find.ColonistBar.MarkColonistsDirty();
             }
             if (this.def.category == ThingCategory.Item)
             {
                 SlotGroup slotGroup = this.Position.GetSlotGroup(map);
                 if (slotGroup != null && slotGroup.parent != null)
                 {
                     slotGroup.parent.Notify_ReceivedThing(this);
                 }
             }
             if (this.def.receivesSignals)
             {
                 Find.SignalManager.RegisterReceiver(this);
             }
         }
     }
 }
示例#6
0
        public override void DeSpawn(DestroyMode mode = DestroyMode.Vanish)
        {
            if (Destroyed)
            {
                Log.Error("Tried to despawn " + this.ToStringSafe() + " which is already destroyed.");
                return;
            }
            if (!Spawned)
            {
                Log.Error("Tried to despawn " + this.ToStringSafe() + " which is not spawned.");
                return;
            }
            Map map = Map;

            RegionListersUpdater.DeregisterInRegions(this, map);
            map.spawnedThings.Remove(this);
            map.listerThings.Remove(this);
            map.thingGrid.Deregister(this);
            map.coverGrid.DeRegister(this);
            if (def.receivesSignals)
            {
                Find.SignalManager.DeregisterReceiver(this);
            }
            map.tooltipGiverList.Notify_ThingDespawned(this);
            if (def.graphicData != null && def.graphicData.Linked)
            {
                map.linkGrid.Notify_LinkerCreatedOrDestroyed(this);
                map.mapDrawer.MapMeshDirty(Position, MapMeshFlag.Things, regenAdjacentCells: true, regenAdjacentSections: false);
            }
            if (Find.Selector.IsSelected(this))
            {
                Find.Selector.Deselect(this);
                Find.MainButtonsRoot.tabs.Notify_SelectedObjectDespawned();
            }
            DirtyMapMesh(map);
            if (def.drawerType != DrawerType.MapMeshOnly)
            {
                map.dynamicDrawManager.DeRegisterDrawable(this);
            }
            (map.regionGrid.GetValidRegionAt_NoRebuild(Position)?.Room)?.Notify_ContainedThingSpawnedOrDespawned(this);
            if (def.AffectsRegions)
            {
                map.regionDirtyer.Notify_ThingAffectingRegionsDespawned(this);
            }
            if (def.pathCost != 0 || def.passability == Traversability.Impassable)
            {
                map.pathGrid.RecalculatePerceivedPathCostUnderThing(this);
            }
            if (def.AffectsReachability)
            {
                map.reachability.ClearCache();
            }
            Find.TickManager.DeRegisterAllTickabilityFor(this);
            mapIndexOrState = -1;
            if (def.category == ThingCategory.Item)
            {
                map.listerHaulables.Notify_DeSpawned(this);
                map.listerMergeables.Notify_DeSpawned(this);
            }
            map.attackTargetsCache.Notify_ThingDespawned(this);
            map.physicalInteractionReservationManager.ReleaseAllForTarget(this);
            StealAIDebugDrawer.Notify_ThingChanged(this);
            IHaulDestination haulDestination = this as IHaulDestination;

            if (haulDestination != null)
            {
                map.haulDestinationManager.RemoveHaulDestination(haulDestination);
            }
            if (this is IThingHolder && Find.ColonistBar != null)
            {
                Find.ColonistBar.MarkColonistsDirty();
            }
            if (def.category == ThingCategory.Item)
            {
                SlotGroup slotGroup = Position.GetSlotGroup(map);
                if (slotGroup != null && slotGroup.parent != null)
                {
                    slotGroup.parent.Notify_LostThing(this);
                }
            }
            QuestUtility.SendQuestTargetSignals(questTags, "Despawned", this.Named("SUBJECT"));
        }
示例#7
0
        public override void SpawnSetup(Map map, bool respawningAfterLoad)
        {
            if (Destroyed)
            {
                Log.Error(string.Concat("Spawning destroyed thing ", this, " at ", Position, ". Correcting."));
                mapIndexOrState = -1;
                if (HitPoints <= 0 && def.useHitPoints)
                {
                    HitPoints = 1;
                }
            }
            if (Spawned)
            {
                Log.Error(string.Concat("Tried to spawn already-spawned thing ", this, " at ", Position));
                return;
            }
            int num = Find.Maps.IndexOf(map);

            if (num < 0)
            {
                Log.Error(string.Concat("Tried to spawn thing ", this, ", but the map provided does not exist."));
                return;
            }
            if (stackCount > def.stackLimit)
            {
                Log.Error(string.Concat("Spawned ", this, " with stackCount ", stackCount, " but stackLimit is ", def.stackLimit, ". Truncating."));
                stackCount = def.stackLimit;
            }
            mapIndexOrState = (sbyte)num;
            RegionListersUpdater.RegisterInRegions(this, map);
            if (!map.spawnedThings.TryAdd(this, canMergeWithExistingStacks: false))
            {
                Log.Error(string.Concat("Couldn't add thing ", this, " to spawned things."));
            }
            map.listerThings.Add(this);
            map.thingGrid.Register(this);
            if (Find.TickManager != null)
            {
                Find.TickManager.RegisterAllTickabilityFor(this);
            }
            DirtyMapMesh(map);
            if (def.drawerType != DrawerType.MapMeshOnly)
            {
                map.dynamicDrawManager.RegisterDrawable(this);
            }
            map.tooltipGiverList.Notify_ThingSpawned(this);
            if (def.graphicData != null && def.graphicData.Linked)
            {
                map.linkGrid.Notify_LinkerCreatedOrDestroyed(this);
                map.mapDrawer.MapMeshDirty(Position, MapMeshFlag.Things, regenAdjacentCells: true, regenAdjacentSections: false);
            }
            if (!def.CanOverlapZones)
            {
                map.zoneManager.Notify_NoZoneOverlapThingSpawned(this);
            }
            if (def.AffectsRegions)
            {
                map.regionDirtyer.Notify_ThingAffectingRegionsSpawned(this);
            }
            if (def.pathCost != 0 || def.passability == Traversability.Impassable)
            {
                map.pathGrid.RecalculatePerceivedPathCostUnderThing(this);
            }
            if (def.AffectsReachability)
            {
                map.reachability.ClearCache();
            }
            map.coverGrid.Register(this);
            if (def.category == ThingCategory.Item)
            {
                map.listerHaulables.Notify_Spawned(this);
                map.listerMergeables.Notify_Spawned(this);
            }
            map.attackTargetsCache.Notify_ThingSpawned(this);
            (map.regionGrid.GetValidRegionAt_NoRebuild(Position)?.Room)?.Notify_ContainedThingSpawnedOrDespawned(this);
            StealAIDebugDrawer.Notify_ThingChanged(this);
            IHaulDestination haulDestination = this as IHaulDestination;

            if (haulDestination != null)
            {
                map.haulDestinationManager.AddHaulDestination(haulDestination);
            }
            if (this is IThingHolder && Find.ColonistBar != null)
            {
                Find.ColonistBar.MarkColonistsDirty();
            }
            if (def.category == ThingCategory.Item)
            {
                SlotGroup slotGroup = Position.GetSlotGroup(map);
                if (slotGroup != null && slotGroup.parent != null)
                {
                    slotGroup.parent.Notify_ReceivedThing(this);
                }
            }
            if (def.receivesSignals)
            {
                Find.SignalManager.RegisterReceiver(this);
            }
            if (!respawningAfterLoad)
            {
                QuestUtility.SendQuestTargetSignals(questTags, "Spawned", this.Named("SUBJECT"));
            }
        }
示例#8
0
        internal void _SpawnSetup()
        {
            if (this.Destroyed)
            {
                Log.Error(string.Concat(new object[]
                {
                    "Spawning destroyed thing ",
                    this,
                    " at ",
                    this.Position,
                    ". Correcting."
                }));
                SetThingStateInt(this, ThingState.Unspawned);
                if (this.HitPoints <= 0 && this.def.useHitPoints)
                {
                    this.HitPoints = 1;
                }
            }
            if (this.Spawned)
            {
                Log.Error(string.Concat(new object[]
                {
                    "Tried to spawn already-spawned thing ",
                    this,
                    " at ",
                    this.Position
                }));
                return;
            }

            this.holder = null;
            SetThingStateInt(this, ThingState.Spawned);
            Find.Map.listerThings.Add(this);
            if (Find.TickManager != null)
            {
                Find.TickManager.RegisterAllTickabilityFor(this);
            }
            if (this.def.drawerType != DrawerType.RealtimeOnly)
            {
                CellRect.CellRectIterator iterator = this.OccupiedRect().GetIterator();
                while (!iterator.Done())
                {
                    Find.Map.mapDrawer.MapMeshDirty(iterator.Current, MapMeshFlag.Things);
                    iterator.MoveNext();
                }
            }
            if (this.def.drawerType != DrawerType.MapMeshOnly)
            {
                Find.DynamicDrawManager.RegisterDrawable(this);
            }
            if (this.def.hasTooltip)
            {
                Find.TooltipGiverList.RegisterTooltipGiver(this);
            }
            if (this.def.graphicData != null && this.def.graphicData.Linked)
            {
                LinkGrid.Notify_LinkerCreatedOrDestroyed(this);
                Find.MapDrawer.MapMeshDirty(this.Position, MapMeshFlag.Things, true, false);
            }
            if (!this.def.CanOverlapZones)
            {
                rNotify_NoZoneOverlapThingSpawned(this);
            }
            if (this.def.regionBarrier)
            {
                rNotify_BarrierSpawned(this);
            }
            if (this.def.pathCost != 0 || this.def.passability == Traversability.Impassable)
            {
                Find.PathGrid.RecalculatePerceivedPathCostUnderThing(this);
            }
            if (this.def.passability == Traversability.Impassable)
            {
                Reachability.ClearCache();
            }
            Find.CoverGrid.Register(this);
            if (this.def.category == ThingCategory.Item)
            {
                ListerHaulables.Notify_Spawned(this);
            }
            Find.AttackTargetsCache.Notify_ThingSpawned(this);
            Region validRegionAt_NoRebuild = Find.RegionGrid.GetValidRegionAt_NoRebuild(this.Position);
            Room   room = (validRegionAt_NoRebuild != null) ? validRegionAt_NoRebuild.Room : null;

            if (room != null)
            {
                room.Notify_ContainedThingSpawnedOrDespawned(this);
            }
            if (this.def.category == ThingCategory.Item)
            {
                Building_Door building_Door = this.Position.GetEdifice() as Building_Door;
                if (building_Door != null)
                {
                    building_Door.Notify_ItemSpawnedOrDespawnedOnTop(this);
                }
            }
            StealAIDebugDrawer.Notify_ThingChanged(this);
        }
示例#9
0
        public static bool Prefix(Thing __instance, Thing other, bool respectStackLimit, ref bool __result)
        {
            Mod.Debug("Thing.TryAbsorbStack begin");
            if (!Limits.HasStackLimit(__instance))
            {
                return(true);
            }

            if (!__instance.CanStackWith(other))
            {
                __result = false;
                return(false);
            }

            int num;

            if (respectStackLimit)
            {
                var t = Limits.CalculateStackLimit(__instance) - __instance.stackCount;
                if (t < 0)
                {
                    t = 0;
                }

                num = Mathf.Min(other.stackCount, t);
            }
            else
            {
                num = other.stackCount;
            }

            if (num <= 0)
            {
                __result = false;
                return(false);
            }

            if (__instance.def.useHitPoints)
            {
                __instance.HitPoints =
                    Mathf.CeilToInt(((__instance.HitPoints * __instance.stackCount) + (other.HitPoints * num)) /
                                    (float)(__instance.stackCount + num));
            }

            __instance.stackCount += num;
            other.stackCount      -= num;
            StealAIDebugDrawer.Notify_ThingChanged(__instance);
            if (__instance.Spawned)
            {
                __instance.Map.listerMergeables.Notify_ThingStackChanged(__instance);
            }

            if (other.stackCount <= 0)
            {
                other.Destroy();
                __result = true;
            }
            else
            {
                __result = false;
            }

            return(false);
        }