private void DestroyThing(Thing thing, int hostId = 0) { var id = thing.thingIDNumber; if (hostId != 0 || ThingsIDDic.TryGetValue(id, out hostId)) { ThingsIDDicRev.Remove(hostId); } ThingsIDDic.Remove(id); ThingsObjDic.Remove(id); thing.Destroy(); }
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; } }