Exemplo n.º 1
0
        private void ApplyAttackingPawnJob(Pawn pawn)
        {
            var pId = pawn.thingIDNumber;
            AttackPawnCommand comm = null;
            bool stopJob           = !AttackingPawnDic.ContainsKey(pId) ||
                                     !AttackingPawnJobDic.TryGetValue(pId, out comm);

            try
            {
                var   tick = (long)Find.TickManager.TicksGame;
                APJBT check;
                if (ApplyPawnJobByTick.TryGetValue(pId, out check))
                {
                    //Если в один тик мы второй раз пытаемся установить задачу, значит система её сразу отменяет
                    //В этом случае сбрасываем задачу, считаем что цель достигнута или недоступна
                    if (check.Comm == comm && check.Tick == tick)
                    {
                        if (MainHelper.DebugMode && pawn.Label == "Douglas, Клерк")
                        {
                            Loger.Log("HostAttackUpdate ApplyAttackingPawnJob stopJob(repeat) " + comm.TargetPos.Get().ToString());
                        }
                        stopJob = true;
                    }
                }

                //UIEventNewJobDisable = true;
                Thing target = null;
                if (!stopJob &&
                    (comm.Command == AttackPawnCommand.PawnCommand.Attack ||
                     comm.Command == AttackPawnCommand.PawnCommand.AttackMelee))
                {
                    var mapPawns = GameMap.mapPawns.AllPawnsSpawned;
                    target = mapPawns.Where(p => p.thingIDNumber == comm.TargetID).FirstOrDefault();
                    if (target == null)
                    {
                        target = GameMap.listerThings.AllThings.Where(p => p.thingIDNumber == comm.TargetID).FirstOrDefault();
                    }
                    if (target == null)
                    {
                        if (MainHelper.DebugMode && pawn.Label == "Douglas, Клерк")
                        {
                            Loger.Log("HostAttackUpdate ApplyAttackingPawnJob TargetThing == null " + comm.HostPawnID.ToString());
                        }
                        stopJob = true;
                    }
                }

                if (!stopJob)
                {
                    if (comm.Command == AttackPawnCommand.PawnCommand.Attack)
                    {
                        //задаем команду атаковать
                        if (MainHelper.DebugMode && pawn.Label == "Douglas, Клерк")
                        {
                            Loger.Log("HostAttackUpdate ApplyAttackingPawnJob StartJob Attack " + comm.TargetID.ToString());
                        }
                        pawn.jobs.StartJob(new Job(JobDefOf.AttackStatic, target)
                        {
                            playerForced          = true,
                            expiryInterval        = int.MaxValue,
                            checkOverrideOnExpire = false,
                        }
                                           , JobCondition.InterruptForced);
                    }
                    else if (comm.Command == AttackPawnCommand.PawnCommand.AttackMelee)
                    {
                        if (MainHelper.DebugMode && pawn.Label == "Douglas, Клерк")
                        {
                            Loger.Log("HostAttackUpdate ApplyAttackingPawnJob StartJob AttackMelee " + comm.TargetID.ToString());
                        }
                        pawn.jobs.StartJob(new Job(JobDefOf.AttackMelee, target)
                        {
                            playerForced          = true,
                            expiryInterval        = int.MaxValue,
                            checkOverrideOnExpire = false,
                        }
                                           , JobCondition.InterruptForced);
                    }
                    else if (comm.Command == AttackPawnCommand.PawnCommand.Goto)
                    {
                        //задаем команду идти
                        if (MainHelper.DebugMode && pawn.Label == "Douglas, Клерк")
                        {
                            Loger.Log("HostAttackUpdate ApplyAttackingPawnJob StartJob Goto " + comm.TargetPos.Get().ToString());
                        }
                        pawn.jobs.StartJob(new Job(JobDefOf.Goto, comm.TargetPos.Get())
                        {
                            playerForced          = true,
                            expiryInterval        = int.MaxValue,
                            checkOverrideOnExpire = false,
                        }
                                           , JobCondition.InterruptForced);
                    }
                    else
                    {
                        stopJob = true;
                    }
                }
                if (stopJob)
                {
                    if (AttackingPawnJobDic.ContainsKey(pId))
                    {
                        if (MainHelper.DebugMode && pawn.Label == "Douglas, Клерк")
                        {
                            Loger.Log("HostAttackUpdate ApplyAttackingPawnJob Remove Job " + comm.TargetPos.Get().ToString());
                        }
                        AttackingPawnJobDic.Remove(pId);
                    }
                    pawn.jobs.StartJob(new Job(JobDefOf.Wait_Combat)
                    {
                        playerForced          = true,
                        expiryInterval        = int.MaxValue,
                        checkOverrideOnExpire = false,
                    }
                                       , JobCondition.InterruptForced);
                }
                else
                {
                    ApplyPawnJobByTick[pId] = new APJBT()
                    {
                        Comm = comm, Tick = tick
                    };
                }
            }
            catch (Exception exp)
            {
                if (MainHelper.DebugMode && pawn.Label == "Douglas, Клерк")
                {
                    Loger.Log("HostAttackUpdate ApplyAttackingPawnJob " + exp.ToString());
                }
                if (AttackingPawnJobDic.ContainsKey(pId))
                {
                    AttackingPawnJobDic.Remove(pId);
                }
            }
            //UIEventNewJobDisable = false;
        }
Exemplo n.º 2
0
        public void UIEventNewJob(Pawn pawn, Job job) //если job == null значит команда стоять и не двигаться Wait_Combat
        {
            try
            {
                if (UIEventNewJobDisable)
                {
                    return;
                }
                var pawnId = pawn.thingIDNumber;

                //помимо главной обработки события изменения задания помечаем цель задачи для обновления её состояния позже, когда задача пешки завершиться
                //это всё для того, чтобы поймать, что кол-во какой-то вещи изменилось
                //добавляем тут намерение пешки взять вещь в новый словарь если Job не null,
                //а если null (когда джоб завершился) помещаем в предварительный массив к отправке
                //в момент отправки из предварительного массива данные переносятся в массив к отправке, а те что там были отправляются атакующиму с их текущим количеством стака
                Thing jobThing;
                if (ThingPrepareChange2.TryGetValue(pawnId, out jobThing) && !ThingPrepareChange1.Contains(jobThing))
                {
                    Loger.Log("HostAttackUpdate UIEventNewJob AddFromJob " + jobThing.Label);
                    ThingPrepareChange1.Add(jobThing);
                    ThingPrepareChange2.Remove(pawnId);
                }
                if (job != null && job.targetA.HasThing && !(job.targetA.Thing is Pawn))
                {
                    ThingPrepareChange2[pawnId] = job.targetA.Thing;
                }

                //у атакующих отменяем все команды и повторяем те, которые были переданы нам последний раз
                if (!AttackingPawnDic.ContainsKey(pawnId))
                {
                    if (MainHelper.DebugMode && pawn.Label == "Douglas, Клерк")
                    {
                        Loger.Log("HostAttackUpdate UIEventNewJob StartJob " + pawn.Label + " job=" + (job == null ? "null" : job.def.defName.ToString()) + " -> ignore");
                    }
                    return;
                }
                var stack = "";

                /*
                 * if (job == null || (job == null ? "null" : job.def.defName.ToString()) == "Wait_MaintainPosture")
                 * {
                 *  var stackTrace = new StackTrace();
                 *  var frames = stackTrace.GetFrames();
                 *  foreach (var frame in frames)
                 *  {
                 *      var methodDescription = frame.GetMethod();
                 *      stack += Environment.NewLine + methodDescription.Name;
                 *  }
                 * }
                 */
                UIEventNewJobDisable = true;
                if (MainHelper.DebugMode && pawn.Label == "Douglas, Клерк")
                {
                    Loger.Log("HostAttackUpdate UIEventNewJob StartJob " + pawn.Label + " job=" + (job == null ? "null" : job.def.defName.ToString()) + " -> <...> " + stack);
                }
                ApplyAttackingPawnJob(pawn);
            }
            catch (Exception exp)
            {
                if (MainHelper.DebugMode && pawn.Label == "Douglas, Клерк")
                {
                    Loger.Log("HostAttackUpdate UIEventNewJob " + exp.ToString());
                }
            }
            UIEventNewJobDisable = false;
        }
Exemplo n.º 3
0
        private void AttackUpdate()
        {
            bool inTimerEvent = false;

            try
            {
                if (InTimer)
                {
                    return;
                }
                InTimer = true;
                AttackUpdateTick++;
//                Loger.Log("Client HostAttackUpdate #" + AttackUpdateTick.ToString());

                SessionClientController.Command((connect) =>
                {
                    try
                    {
                        List <Pawn> mapPawns;
                        AttackHostFromSrv toClient;
                        lock (ToSendListsSync)
                        {
                            //                      Loger.Log("Client HostAttackUpdate 1");
                            //обновляем списки
                            mapPawns       = GameMap.mapPawns.AllPawnsSpawned;
                            var mapPawnsId = new HashSet <int>(mapPawns.Select(p => p.thingIDNumber));
                            mapPawnsId.SymmetricExceptWith(SendedPawnsId); //новые пешки + те что на сервере, но их уже нет на карте

                            if (mapPawnsId.Count > 0)
                            {
                                var toSendAddId = new HashSet <int>(mapPawnsId);
                                toSendAddId.ExceptWith(SendedPawnsId); //только новые пешки
                                if (toSendAddId.Count > 0)
                                {
                                    toSendAddId.ExceptWith(ToSendAddId); //исключаем те, которые уже есть в списке
                                    ToSendAddId.AddRange(toSendAddId);
                                }

                                var toSendDeleteId = new HashSet <int>(mapPawnsId);
                                toSendDeleteId.IntersectWith(SendedPawnsId); //только те, что на сервере но их уже нет на карте
                                if (toSendDeleteId.Count > 0)
                                {
                                    toSendDeleteId.ExceptWith(ToSendDeleteId); //исключаем те, которые уже есть в списке
                                    ToSendDeleteId.AddRange(toSendDeleteId);
                                }
                            }

                            //посылаем пакеты с данными
                            //                      Loger.Log("Client HostAttackUpdate 2");

                            var newPawns   = new List <ThingEntry>();
                            var newPawnsId = new List <int>();
                            int cnt        = ToSendAddId.Count < 3 || ToSendAddId.Count > 6 || AttackUpdateTick == 0
                                ? ToSendAddId.Count
                                : 3;
                            int i       = 0;
                            int[] added = new int[cnt];
                            foreach (int id in ToSendAddId)
                            {
                                if (i >= cnt)
                                {
                                    break;
                                }
                                added[i++] = id;

                                var thing = mapPawns.Where(p => p.thingIDNumber == id).FirstOrDefault();
                                var tt    = ThingEntry.CreateEntry(thing, 1);
                                //передаем те, что были исходные у атакуемого (хотя там используется только как признак TransportID != 0 - значит те кто атакует)
                                if (AttackingPawnDic.ContainsKey(tt.OriginalID))
                                {
                                    tt.TransportID = AttackingPawnDic[tt.OriginalID];
                                }
                                newPawns.Add(tt);
                                newPawnsId.Add(id);
                            }
                            for (i = 0; i < cnt; i++)
                            {
                                ToSendAddId.Remove(added[i]);
                                SendedPawnsId.Add(added[i]);
                            }

                            foreach (int id in ToSendDeleteId)
                            {
                                SendedPawnsId.Remove(id);
                            }

                            //вещи
                            var newThings = ToSendThingAdd
                                            .Where(thing => !ToSendDeleteId.Any(d => thing.thingIDNumber == d))
                                            .Select(thing => ThingEntry.CreateEntry(thing, thing.stackCount))
                                            .ToList();

                            //передаем изменение местоположения и пр. по ID хоста
                            var toSendState   = new List <AttackThingState>();
                            var toSendStateId = new List <int>();
                            for (int imp = 0; imp < mapPawns.Count; imp++)
                            {
                                var mp   = mapPawns[imp];
                                var mpID = mp.thingIDNumber;
                                if (ToUpdateStateId.Contains(mpID))
                                {
                                    continue;
                                }

                                var mpHash = AttackThingState.GetHash(mp);
                                int mpHS;
                                if (!SendedState.TryGetValue(mpID, out mpHS) || mpHS != mpHash)
                                {
                                    SendedState[mpID] = mpHash;
                                    toSendState.Add(new AttackThingState(mp));
                                }
                            }
                            for (int imp = 0; imp < ToUpdateState.Count; imp++)
                            {
                                var mp   = ToUpdateState[imp];
                                var mpID = mp.thingIDNumber;
                                if (ToSendDeleteId.Contains(mpID))
                                {
                                    continue;
                                }

                                if (mp is Pawn)
                                {
                                    var mpHash        = AttackThingState.GetHash(mp);
                                    SendedState[mpID] = mpHash; //заносим только для проверки выше
                                }
                                toSendState.Add(new AttackThingState(mp));
                            }

                            //обновляем поколения вещей учавствующих в Job и отправляем нужные
                            foreach (var mp in ThingPrepareChange0)
                            {
                                var mpID = mp.thingIDNumber;
                                if (ToSendDeleteId.Contains(mpID))
                                {
                                    continue;
                                }

                                toSendState.Add(new AttackThingState(mp));
                            }
                            Loger.Log("HostAttackUpdate UpdateCommand FromJob Count=" + ThingPrepareChange0.Count.ToString());
                            ThingPrepareChange0 = ThingPrepareChange1;
                            ThingPrepareChange1 = new HashSet <Thing>();

                            //Loger.Log("Client HostAttackUpdate 3");
                            toClient = connect.AttackOnlineHost(new AttackHostToSrv()
                            {
                                State       = 10,
                                NewPawns    = newPawns,
                                NewPawnsId  = newPawnsId,
                                NewThings   = newThings,
                                NewThingsId = newThings.Select(th => th.OriginalID).ToList(),
                                Delete      = ToSendDeleteId.ToList(),
                                UpdateState = toSendState
                            });
                            ToSendThingAdd.Clear();
                            ToSendDeleteId.Clear();
                            ToUpdateStateId.Clear();
                            ToUpdateState.Clear();
                        }

                        //принимаем обновление команд атакующих
                        if (toClient.UpdateCommand.Count > 0)
                        {
                            Loger.Log("HostAttackUpdate UpdateCommand Count=" + toClient.UpdateCommand.Count.ToString());
                            UIEventNewJobDisable = true;
                            for (int ii = 0; ii < toClient.UpdateCommand.Count; ii++)
                            {
                                var comm = toClient.UpdateCommand[ii];
                                var pawn = mapPawns.Where(p => p.thingIDNumber == comm.HostPawnID).FirstOrDefault() as Pawn;
                                if (pawn == null)
                                {
                                    Loger.Log("HostAttackUpdate UpdateCommand pawn == null " + comm.HostPawnID.ToString());
                                    continue;
                                }

                                AttackingPawnJobDic[comm.HostPawnID] = comm;
                                ApplyAttackingPawnJob(pawn);
                            }
                            UIEventNewJobDisable = false;
                        }

                        //                      Loger.Log("Client HostAttackUpdate 4");
                    }
                    catch (Exception ext)
                    {
                        InTimer = false;
                        Loger.Log("HostAttackUpdate Event Exception " + ext.ToString());
                    }
                    finally
                    {
                        InTimer = false;
                    }
                });
            }
            catch (Exception ext)
            {
                Loger.Log("HostAttackUpdate Exception " + ext.ToString());
            }
            if (!inTimerEvent)
            {
                InTimer = false;
            }
        }