public override void PostMapGenerate(Map map) { if (Find.TickManager.TicksGame > 5f) { return; } StructureLayoutDef structureLayoutDef; if (ModLister.GetActiveModWithIdentifier("EdB.PrepareCarefully") != null) { structureLayoutDef = PrepareCarefully_Util.pcScenariosSave.First().Key; nearMapCenter = PrepareCarefully_Util.pcScenariosSave.First().Value; } else { structureLayoutDef = chooseFrom.RandomElement(); } KCSG_Utilities.HeightWidthFromLayout(structureLayoutDef, out int h, out int w); CellRect cellRect = this.CreateCellRect(map, h, w); foreach (List <string> item in structureLayoutDef.layouts) { KCSG_Utilities.GenerateRoomFromLayout(item, cellRect, map, structureLayoutDef); } FloodFillerFog.DebugRefogMap(map); }
public override void MapComponentUpdate() { base.MapComponentUpdate(); if (this.doGeneration && path?.Length > 0) { try { SettlementGeneration.DoSettlementGeneration(this.map, this.path, this.locationDef, this.map.ParentFaction, false); } catch (Exception ex) { Log.Error(ex.ToString()); } GetOrGenerateMapPatch.caravanArrival = false; GetOrGenerateMapPatch.locationData = null; GetOrGenerateMapPatch.customSettlementGeneration = false; this.doGeneration = false; } if (this.reFog) { Log.Message("Refog" + this.map); try { FloodFillerFog.DebugRefogMap(this.map); } catch { } this.reFog = false; } }
public override void MapComponentUpdate() { base.MapComponentUpdate(); //if (this.DoGeneration && path.Length > 0) //{ // SettlementGeneration.DoSettlementGeneration(this.map, this.path, this.map.ParentFaction, false); // this.DoGeneration = false; //} if (this.ReFog) { ZLogger.Message("Refog" + this.map); FloodFillerFog.DebugRefogMap(this.map); this.ReFog = false; } }
public override void Generate(Map map, GenStepParams parms) { StructureLayoutDef structureLayoutDef = structureLayoutDefs.RandomElement(); RectUtils.HeightWidthFromLayout(structureLayoutDef, out int h, out int w); CellRect cellRect = CellRect.CenteredOn(map.Center, w, h); GenUtils.PreClean(map, cellRect, structureLayoutDef.roofGrid, fullClear); foreach (List <string> item in structureLayoutDef.layouts) { GenUtils.GenerateRoomFromLayout(item, cellRect, map, structureLayoutDef); } if (shouldRuin) { CGO.factionSettlement = new CustomGenOption { filthTypes = filthTypes, scatterThings = scatterThings, scatterChance = scatterChance }; ResolveParams rp = new ResolveParams { faction = map.ParentFaction, rect = cellRect }; foreach (string resolver in ruinSymbolResolvers) { if (!(ruinSymbolResolvers.Contains("kcsg_randomroofremoval") && resolver == "kcsg_scatterstuffaround")) { BaseGen.symbolStack.Push(resolver, rp, null); } } } // Flood refog if (map.mapPawns.FreeColonistsSpawned.Count > 0) { FloodFillerFog.DebugRefogMap(map); } }
public override void PostMapGenerate(Map map) { if (Find.TickManager.TicksGame > 5f || chooseFrom.Count <= 0 || PrepareCarefully_Util.pcScenariosSave.Count <= 0) { return; } StructureLayoutDef structureLayoutDef; if (ModLister.GetActiveModWithIdentifier("EdB.PrepareCarefully") != null) { structureLayoutDef = PrepareCarefully_Util.pcScenariosSave.First().Key; nearMapCenter = PrepareCarefully_Util.pcScenariosSave.First().Value; } else { structureLayoutDef = chooseFrom.RandomElement(); } RectUtils.HeightWidthFromLayout(structureLayoutDef, out int h, out int w); CellRect cellRect = this.CreateCellRect(map, h, w); if (preGenClear) { GenUtils.PreClean(map, cellRect, structureLayoutDef.roofGrid, fullClear); } foreach (List <string> item in structureLayoutDef.layouts) { GenUtils.GenerateRoomFromLayout(item, cellRect, map, structureLayoutDef, spawnConduits); } if (spawnTheStartingPawn && Find.GameInitData != null) { List <List <Thing> > thingsGroups = new List <List <Thing> >(); foreach (Pawn startingAndOptionalPawn in Find.GameInitData.startingAndOptionalPawns) { thingsGroups.Add(new List <Thing>() { startingAndOptionalPawn }); } List <Thing> thingList = new List <Thing>(); foreach (ScenPart allPart in Find.Scenario.AllParts) { thingList.AddRange(allPart.PlayerStartingThings()); } int index = 0; foreach (Thing thing in thingList) { if (thing.def.CanHaveFaction) { thing.SetFactionDirect(Faction.OfPlayer); } thingsGroups[index].Add(thing); ++index; if (index >= thingsGroups.Count) { index = 0; } } IntVec3 center = map.Center; Pos offset = structureLayoutDef.spawnAtPos.RandomElement(); center.x += offset.x; center.y += offset.y; KLog.Message($"Spawning pawns and stuff at {center}"); this.DropThingGroupsAt(center, map, thingsGroups, instaDrop: (Find.GameInitData.QuickStarted || this.method != PlayerPawnsArriveMethod.DropPods), leaveSlag: true, allowFogged: false); } if (map.mapPawns.FreeColonistsSpawned.Count > 0) { FloodFillerFog.DebugRefogMap(map); } }
public static HashSet <IntVec3> DoSettlementGeneration(Map map, string path, LocationDef locationDef, Faction faction, bool disableFog) { Log.Message("DoSettlementGeneration: GetOrGenerateMapPatch.locationData: " + GetOrGenerateMapPatch.locationData?.locationDef); Log.Message("DoSettlementGeneration: path: " + path); Log.Message("DoSettlementGeneration: locationDef: " + locationDef); GetOrGenerateMapPatch.locationData = null; GetOrGenerateMapPatch.caravanArrival = false; var mapComp = map.GetComponent <MapComponentGeneration>(); try { if (locationDef != null && locationDef.destroyEverythingOnTheMapBeforeGeneration) { var thingsToDespawn = map.listerThings.AllThings; if (thingsToDespawn != null && thingsToDespawn.Count > 0) { for (int i = thingsToDespawn.Count - 1; i >= 0; i--) { try { if (thingsToDespawn[i].Spawned) { thingsToDespawn[i].DeSpawn(DestroyMode.WillReplace); } } catch (Exception ex) { Log.Error("4 Cant despawn: " + thingsToDespawn[i] + " - " + thingsToDespawn[i].Position + "error: " + ex); } } } } if (locationDef != null && locationDef.factionDefForNPCsAndTurrets != null) { faction = Find.FactionManager.FirstFactionOfDef(locationDef.factionDefForNPCsAndTurrets); } else if (faction == Faction.OfPlayer || faction == null) { faction = Faction.OfAncients; } List <Thing> thingsToDestroy = new List <Thing>(); HashSet <IntVec3> tilesToProcess = new HashSet <IntVec3>(); int radiusToClear = 0; // //foreach (var building in map.listerThings.AllThings // .Where(x => x is Building && x.Faction == faction && !(x is Mineable))) //{ // foreach (var pos in GenRadial.RadialCellsAround(building.Position, radiusToClear, true)) // { // if (GenGrid.InBounds(pos, map)) // { // tilesToProcess.Add(pos); // } // } // thingsToDestroy.Add(building); //} List <Corpse> corpses = new List <Corpse>(); List <Pawn> pawnCorpses = new List <Pawn>(); List <Pawn> pawns = new List <Pawn>(); List <Building> buildings = new List <Building>(); List <Thing> things = new List <Thing>(); List <Filth> filths = new List <Filth>(); List <Plant> plants = new List <Plant>(); Dictionary <IntVec3, TerrainDef> terrains = new Dictionary <IntVec3, TerrainDef>(); Dictionary <IntVec3, RoofDef> roofs = new Dictionary <IntVec3, RoofDef>(); HashSet <IntVec3> tilesToSpawnPawnsOnThem = new HashSet <IntVec3>(); Scribe.loader.InitLoading(path); Scribe_Collections.Look <Pawn>(ref pawnCorpses, "PawnCorpses", LookMode.Deep, new object[0]); Scribe_Collections.Look <Corpse>(ref corpses, "Corpses", LookMode.Deep, new object[0]); Scribe_Collections.Look <Pawn>(ref pawns, "Pawns", LookMode.Deep, new object[0]); Scribe_Collections.Look <Building>(ref buildings, "Buildings", LookMode.Deep, new object[0]); Scribe_Collections.Look <Filth>(ref filths, "Filths", LookMode.Deep, new object[0]); Scribe_Collections.Look <Thing>(ref things, "Things", LookMode.Deep, new object[0]); Scribe_Collections.Look <Plant>(ref plants, "Plants", LookMode.Deep, new object[0]); Scribe_Collections.Look <IntVec3, TerrainDef>(ref terrains, "Terrains", LookMode.Value, LookMode.Def, ref terrainKeys, ref terrainValues); Scribe_Collections.Look <IntVec3, RoofDef>(ref roofs, "Roofs", LookMode.Value, LookMode.Def, ref roofsKeys, ref roofsValues); Scribe_Collections.Look <IntVec3>(ref tilesToSpawnPawnsOnThem, "tilesToSpawnPawnsOnThem", LookMode.Value); Scribe.loader.FinalizeLoading(); if (corpses is null) { corpses = new List <Corpse>(); } else { corpses.RemoveAll(x => x is null); } if (pawnCorpses is null) { pawnCorpses = new List <Pawn>(); } else { pawnCorpses.RemoveAll(x => x is null); } if (pawns is null) { pawns = new List <Pawn>(); } else { pawns.RemoveAll(x => x is null); } if (buildings is null) { buildings = new List <Building>(); } else { buildings.RemoveAll(x => x is null); } if (things is null) { things = new List <Thing>(); } else { things.RemoveAll(x => x is null); } if (filths is null) { filths = new List <Filth>(); } else { filths.RemoveAll(x => x is null); } if (plants is null) { plants = new List <Plant>(); } else { plants.RemoveAll(x => x is null); } var cells = new List <IntVec3>(tilesToSpawnPawnsOnThem); cells.AddRange(buildings.Select(x => x.Position).ToList()); var centerCell = GetCellCenterFor(cells); var offset = map.Center - centerCell; if (corpses != null && corpses.Count > 0) { foreach (var corpse in corpses) { try { var position = GetOffsetPosition(locationDef, corpse.Position, offset); if (GenGrid.InBounds(position, map)) { GenSpawn.Spawn(corpse, position, map, WipeMode.Vanish); } } catch (Exception ex) { Log.Error("1 Error in map generating, cant spawn " + corpse + " - " + ex); } } } if (pawns != null && pawns.Count > 0) { foreach (var pawn in pawns) { try { var position = GetOffsetPosition(locationDef, pawn.Position, offset); if (GenGrid.InBounds(position, map)) { pawn.pather = new Pawn_PathFollower(pawn); GenSpawn.Spawn(pawn, position, map, WipeMode.Vanish); if (pawn.Faction != faction) { pawn.SetFaction(faction); } } } catch (Exception ex) { Log.Error("2 Error in map generating, cant spawn " + pawn + " - " + ex); } } } if (tilesToSpawnPawnsOnThem != null && tilesToSpawnPawnsOnThem.Count > 0) { foreach (var tile in tilesToSpawnPawnsOnThem) { var position = GetOffsetPosition(locationDef, tile, offset); try { if (GenGrid.InBounds(position, map)) { var things2 = map.thingGrid.ThingsListAt(position); foreach (var thing in things2) { if (thing is Building || (thing is Plant plant && plant.def != ThingDefOf.Plant_Grass) || IsChunk(thing)) { thingsToDestroy.Add(thing); } } } } catch (Exception ex) { Log.Error("3 Error in map generating, cant spawn " + position + " - " + ex); } } } if (buildings != null && buildings.Count > 0) { foreach (var building in buildings) { var position = GetOffsetPosition(locationDef, building.Position, offset); foreach (var pos in GenRadial.RadialCellsAround(position, radiusToClear, true)) { if (GenGrid.InBounds(pos, map)) { tilesToProcess.Add(pos); } } } if (tilesToProcess != null && tilesToProcess.Count > 0) { foreach (var pos in tilesToProcess) { if (pos.InBounds(map)) { var things2 = map.thingGrid.ThingsListAt(pos); foreach (var thing in things2) { if (thing is Building || (thing is Plant plant && plant.def != ThingDefOf.Plant_Grass) || IsChunk(thing)) { thingsToDestroy.Add(thing); } } var terrain = pos.GetTerrain(map); if (terrain != null) { if (terrain.IsWater) { map.terrainGrid.SetTerrain(pos, TerrainDefOf.Soil); } if (map.terrainGrid.CanRemoveTopLayerAt(pos)) { map.terrainGrid.RemoveTopLayer(pos, false); } } var roof = pos.GetRoof(map); if (roof != null && (!map.roofGrid.RoofAt(pos).isNatural || map.roofGrid.RoofAt(pos) == RoofDefOf.RoofRockThin)) { map.roofGrid.SetRoof(pos, null); } } } } if (thingsToDestroy != null && thingsToDestroy.Count > 0) { for (int i = thingsToDestroy.Count - 1; i >= 0; i--) { try { if (thingsToDestroy[i].Spawned) { thingsToDestroy[i].DeSpawn(DestroyMode.WillReplace); } } catch (Exception ex) { Log.Error("4 Cant despawn: " + thingsToDestroy[i] + " - " + thingsToDestroy[i].Position + "error: " + ex); } } } foreach (var building in buildings) { var position = GetOffsetPosition(locationDef, building.Position, offset); try { if (GenGrid.InBounds(position, map)) { GenSpawn.Spawn(building, position, map, building.Rotation, WipeMode.Vanish); if (building.def.CanHaveFaction && building.Faction != faction) { building.SetFaction(faction); } } } catch (Exception ex) { Log.Error("5 Error in map generating, cant spawn " + building + " - " + position + " - " + ex); } } } if (filths != null && filths.Count > 0) { foreach (var filth in filths) { try { var position = GetOffsetPosition(locationDef, filth.Position, offset); if (position.InBounds(map)) { GenSpawn.Spawn(filth, position, map, WipeMode.Vanish); } } catch (Exception ex) { Log.Error("6.5 Error in map generating, cant spawn " + filth + " - " + ex); } } } if (plants != null && plants.Count > 0) { foreach (var plant in plants) { try { var position = GetOffsetPosition(locationDef, plant.Position, offset); if (position.InBounds(map) && map.fertilityGrid.FertilityAt(position) >= plant.def.plant.fertilityMin) { GenSpawn.Spawn(plant, position, map, WipeMode.Vanish); } } catch (Exception ex) { Log.Error("6 Error in map generating, cant spawn " + plant + " - " + ex); } } } var containers = map.listerThings.AllThings.Where(x => x is Building_Storage).ToList(); if (things != null && things.Count > 0) { foreach (var thing in things) { try { var position = GetOffsetPosition(locationDef, thing.Position, offset); if (position.InBounds(map)) { GenSpawn.Spawn(thing, position, map, WipeMode.Vanish); if (locationDef != null && locationDef.moveThingsToShelves) { TryDistributeTo(thing, map, containers, faction != Faction.OfPlayer); } } } catch (Exception ex) { Log.Error("7 Error in map generating, cant spawn " + thing + " - " + ex); } } } if (locationDef != null && locationDef.moveThingsToShelves) { foreach (var item in map.listerThings.AllThings) { if (item.IsForbidden(Faction.OfPlayer)) { TryDistributeTo(item, map, containers, faction != Faction.OfPlayer); } } } if (terrains != null && terrains.Count > 0) { foreach (var terrain in terrains) { try { var position = GetOffsetPosition(locationDef, terrain.Key, offset); if (GenGrid.InBounds(position, map)) { map.terrainGrid.SetTerrain(position, terrain.Value); } } catch (Exception ex) { Log.Error("8 Error in map generating, cant spawn " + terrain.Key + " - " + ex); } } } if (roofs != null && roofs.Count > 0) { foreach (var roof in roofs) { try { var position = GetOffsetPosition(locationDef, roof.Key, offset); if (GenGrid.InBounds(position, map)) { map.roofGrid.SetRoof(position, roof.Value); } } catch (Exception ex) { Log.Error("9 Error in map generating, cant spawn " + roof.Key + " - " + ex); } } } if (locationDef != null && (locationDef.percentOfDamagedWalls.HasValue || locationDef.percentOfDestroyedWalls.HasValue) || locationDef.percentOfDamagedFurnitures.HasValue) { var walls = map.listerThings.AllThings.Where(x => x.def.IsEdifice() && x.def.defName.ToLower().Contains("wall")).ToList(); if (locationDef.percentOfDestroyedWalls.HasValue) { var percent = locationDef.percentOfDestroyedWalls.Value.RandomInRange * 100f; var countToTake = (int)((percent * walls.Count()) / 100f); var wallsToDestroy = walls.InRandomOrder().Take(countToTake).ToList(); for (int num = wallsToDestroy.Count - 1; num >= 0; num--) { walls.Remove(wallsToDestroy[num]); wallsToDestroy[num].DeSpawn(); } } if (locationDef.percentOfDamagedWalls.HasValue) { var percent = locationDef.percentOfDamagedWalls.Value.RandomInRange * 100f; var countToTake = (int)((percent * walls.Count()) / 100f); var wallsToDamage = walls.InRandomOrder().Take(countToTake).ToList(); for (int num = wallsToDamage.Count - 1; num >= 0; num--) { var damagePercent = Rand.Range(0.3f, 0.6f); var hitpointsToTake = (int)(wallsToDamage[num].MaxHitPoints * damagePercent); wallsToDamage[num].HitPoints = hitpointsToTake; } } if (locationDef.percentOfDamagedFurnitures.HasValue) { var furnitures = map.listerThings.AllThings.Where(x => !walls.Contains(x) && x.def.IsBuildingArtificial).ToList(); var percent = locationDef.percentOfDamagedFurnitures.Value.RandomInRange * 100f; var countToTake = (int)((percent * furnitures.Count()) / 100f); var furnituresToDamage = furnitures.InRandomOrder().Take(countToTake).ToList(); for (int num = furnituresToDamage.Count - 1; num >= 0; num--) { var damagePercent = Rand.Range(0.3f, 0.6f); var hitpointsToTake = (int)(furnituresToDamage[num].MaxHitPoints * damagePercent); furnituresToDamage[num].HitPoints = hitpointsToTake; } } } if (faction.def.HasModExtension <SettlementOptionModExtension>()) { var options = faction.def.GetModExtension <SettlementOptionModExtension>(); if (options.removeVanillaGeneratedPawns) { for (int i = map.mapPawns.PawnsInFaction(faction).Count - 1; i >= 0; i--) { map.mapPawns.PawnsInFaction(faction)[i].DeSpawn(DestroyMode.Vanish); } } if (options.pawnsToGenerate != null && options.pawnsToGenerate.Count > 0 && tilesToSpawnPawnsOnThem != null && tilesToSpawnPawnsOnThem.Count > 0) { foreach (var pawn in options.pawnsToGenerate) { foreach (var i in Enumerable.Range(1, (int)pawn.selectionWeight)) { var settler = PawnGenerator.GeneratePawn(new PawnGenerationRequest(pawn.kind, faction)); try { var pos = tilesToSpawnPawnsOnThem.Where(x => map.thingGrid.ThingsListAt(x) .Where(y => y is Building).Count() == 0).RandomElement(); GenSpawn.Spawn(settler, pos, map); } catch (Exception ex) { Log.Error("10 Error in map generating, cant spawn " + settler + " - " + ex); } } } } } foreach (var pawn in map.mapPawns.PawnsInFaction(faction)) { var lord = pawn.GetLord(); if (lord != null) { map.lordManager.RemoveLord(lord); } var lordJob = new LordJob_DefendBase(); if (tilesToSpawnPawnsOnThem != null && tilesToSpawnPawnsOnThem.Count > 0) { lordJob = new LordJob_DefendBase(faction, tilesToSpawnPawnsOnThem.RandomElement()); } else { lordJob = new LordJob_DefendBase(faction, pawn.Position); } LordMaker.MakeNewLord(faction, lordJob, map, null).AddPawn(pawn); } if (disableFog != true) { try { FloodFillerFog.DebugRefogMap(map); } catch { foreach (var cell in map.AllCells) { if (!tilesToProcess.Contains(cell) && !(cell.GetFirstBuilding(map) is Mineable)) { var item = cell.GetFirstItem(map); if (item != null) { var room = item.GetRoom(); if (room != null) { if (room.PsychologicallyOutdoors) { FloodFillerFog.FloodUnfog(cell, map); } } } } } } mapComp.reFog = true; } mapComp.doGeneration = false; mapComp.path = null; GetOrGenerateMapPatch.caravanArrival = false; return(tilesToSpawnPawnsOnThem.Select(x => GetOffsetPosition(locationDef, x, offset)).ToHashSet()); } catch (Exception ex) { Log.Error("Error in DoSettlementGeneration: " + ex); } mapComp.doGeneration = false; mapComp.path = null; return(null); }
private void AttackUpdate() { bool inTimerEvent = false; try { //Scribe.ForceStop(); Find.TickManager.Pause(); if (InTimer) { return; } InTimer = true; AttackUpdateTick++; Loger.Log("Client AttackUpdate #" + AttackUpdateTick.ToString()); inTimerEvent = true; SessionClientController.Command((connect) => { try { Loger.Log("Client AttackUpdate 2"); var toSendCommand = ToSendCommand; ToSendCommand = new Dictionary <int, AttackPawnCommand>(); var toClient = connect.AttackOnlineInitiator(new AttackInitiatorToSrv() { State = 10, UpdateCommand = toSendCommand.Values.ToList(), }); Action actUpdateState = () => { Loger.Log("Client AttackUpdate 4. UpdateState=" + toClient.UpdateState.Count); //Применение изменения местоположения и пр. по ID хоста for (int i = 0; i < toClient.UpdateState.Count; i++) { int id; if (!ThingsIDDicRev.TryGetValue(toClient.UpdateState[i].HostThingID, out id)) { Loger.Log("Client AttackUpdate 4 Err1 " + toClient.UpdateState[i].ToString()); continue; } Thing thing; if (!ThingsObjDic.TryGetValue(id, out thing)) { Loger.Log("Client AttackUpdate 4 Err2 " + toClient.UpdateState[i].ToString() + " id=" + id.ToString()); continue; } if (thing == null) { Loger.Log("Client AttackUpdate 4 Err3 " + toClient.UpdateState[i].ToString() + " id=" + id.ToString()); continue; } if (!(thing is Pawn)) { Loger.Log("Client AttackUpdate 4 Apply " + toClient.UpdateState[i].ToString() + " thing=" + thing.Label + " ID=" + thing.thingIDNumber); } if (thing is Pawn && toClient.UpdateState[i].DownState == AttackThingState.PawnHealthState.Dead) { DelayDestroyPawn.Remove(thing); } GameUtils.ApplyState(thing, toClient.UpdateState[i]); } for (int i = 0; i < DelayDestroyPawn.Count; i++) { Thing thing = DelayDestroyPawn[i]; Loger.Log("Client AttackUpdate 4 DelayDestroyPawn " + toClient.Delete[i].ToString() + " thing=" + thing.Label + " ID=" + thing.thingIDNumber); DestroyThing(thing); } DelayDestroyPawn.Clear(); for (int i = 0; i < toClient.Delete.Count; i++) { int id; if (!ThingsIDDicRev.TryGetValue(toClient.Delete[i], out id)) { Loger.Log("Client AttackUpdate 4 Err4 " + toClient.Delete[i].ToString()); continue; } Thing thing; if (!ThingsObjDic.TryGetValue(id, out thing)) { Loger.Log("Client AttackUpdate 4 Err5 " + toClient.Delete[i].ToString() + " id=" + id.ToString()); continue; } if (thing == null) { Loger.Log("Client AttackUpdate 4 Err6 " + toClient.Delete[i].ToString() + " id=" + id.ToString()); continue; } if (thing is Pawn) { Loger.Log("Client AttackUpdate 4 ToDelayDestroy " + toClient.Delete[i].ToString() + " thing=" + thing.Label + " ID=" + thing.thingIDNumber); DelayDestroyPawn.Add(thing); } else { Loger.Log("Client AttackUpdate 4 Destroy " + toClient.Delete[i].ToString() + " thing=" + thing.Label + " ID=" + thing.thingIDNumber); DestroyThing(thing, toClient.Delete[i]); } } }; if (toClient.NewPawns.Count > 0 || toClient.NewThings.Count > 0) { LongEventHandler.QueueLongEvent(delegate { try { Loger.Log("Client AttackUpdate 3. NewPawn=" + toClient.NewPawns.Count); if (toClient.NewPawns.Count > 0) { //удаляем пешки NewPawnsId (здесь список thingIDNumber от хоста), которые сейчас обновим for (int i = 0; i < toClient.NewPawnsId.Count; i++) { var hostid = toClient.NewPawnsId[i]; int id; if (!ThingsIDDicRev.TryGetValue(hostid, out id)) { continue; } Thing thing; if (!ThingsObjDic.TryGetValue(id, out thing)) { continue; } if (thing == null) { continue; } Loger.Log("Client AttackUpdate 3 DestroyPawnForUpdate " + hostid.ToString() + " pawn=" + thing.Label + " ID=" + thing.thingIDNumber); DestroyThing(thing, hostid); } //создаем список пешек toClient.NewPawns GameUtils.SpawnList(GameMap, toClient.NewPawns, false , (p) => p.TransportID == 0 //если без нашего ID, то у нас как пират , (th, te) => { var p = th as Pawn; //Loger.Log("Client AttackUpdate 3. NewPawn " + (p.IsColonist ? "IsColonist" : "NotColonist")); //Дополнить словарь сопоставления ID (их из OriginalID, наш ID, а TransportID уже никому не нужен, т.к. пешки дропнуты и переозданы) if (te.OriginalID != 0 && th.thingIDNumber != 0) { ThingsIDDicRev[te.OriginalID] = th.thingIDNumber; ThingsIDDic[th.thingIDNumber] = te.OriginalID; ThingsObjDic[th.thingIDNumber] = th; //Наши пешки сохраняем отдельно if (te.TransportID != 0) { AttackerPawns[p] = te.OriginalID; p.playerSettings.hostilityResponse = HostilityResponseMode.Ignore; p.jobs.StartJob(new Job(JobDefOf.Wait_Combat) { playerForced = true, expiryInterval = int.MaxValue, checkOverrideOnExpire = false, } , JobCondition.InterruptForced); } } else { Loger.Log("Client AttackUpdate SpawnListPawn NotOrigID! " + " thing=" + th.Label + " ID=" + th.thingIDNumber); } }); } Loger.Log("Client AttackUpdate 3. NewThings=" + toClient.NewThings.Count); if (toClient.NewThings.Count > 0) { GameUtils.SpawnList(GameMap, toClient.NewThings, false, (p) => false , (th, te) => { var p = th as Pawn; //Loger.Log("Client AttackUpdate 3. NewPawn " + (p.IsColonist ? "IsColonist" : "NotColonist")); //Дополнить словарь сопоставления ID (их из OriginalID, наш ID, а TransportID уже никому не нужен, т.к. пешки дропнуты и переозданы) if (te.OriginalID != 0 && th.thingIDNumber != 0) { ThingsIDDicRev[te.OriginalID] = th.thingIDNumber; ThingsIDDic[th.thingIDNumber] = te.OriginalID; ThingsObjDic[th.thingIDNumber] = th; } else { Loger.Log("Client AttackUpdate SpawnListThings NotOrigID! " + " thing=" + th.Label + " ID=" + th.thingIDNumber); } }); } actUpdateState(); Loger.Log("Client AttackUpdate 5"); //после первого массового спавна всех пешек if (AttackUpdateTick == 1) { //проверка обзора и переключение на карту FloodFillerFog.DebugRefogMap(GameMap); CameraJumper.TryJump(GameMap.Center, GameMap); GameAttackTrigger_Patch.ActiveAttacker.Add(GameMap, this); } } catch (Exception ext) { Loger.Log("Client AttackUpdate SpawnListEvent Exception " + ext.ToString()); } InTimer = false; }, "", false, null); //".." } else { actUpdateState(); InTimer = false; } } catch (Exception ext) { InTimer = false; Loger.Log("Client AttackUpdate SpawnList Exception " + ext.ToString()); } }); } catch (Exception ext) { Loger.Log("AttackUpdate Exception " + ext.ToString()); } if (!inTimerEvent) { InTimer = false; } }