Beispiel #1
0
        public static void ApplyState(Thing thing, AttackThingState state, bool pawnHealthStateDead = false)
        {
            //полезное из игры: RecoverFromUnwalkablePositionOrKill
            if (state.StackCount > 0 && thing.stackCount != state.StackCount)
            {
                Loger.Log("Client ApplyState Set StackCount " + thing.stackCount.ToString() + " -> " + state.StackCount.ToString());
                thing.stackCount = state.StackCount;
            }

            if (thing.Position.x != state.Position.x || thing.Position.z != state.Position.z)
            {
                thing.Position = state.Position.Get();
                if (thing is Pawn)
                {
                    var pawn = (Pawn)thing;
                    try
                    {
                        pawn.Notify_Teleported(true, true);
                    }
                    catch (Exception ext)
                    {
                        Loger.Log("Client ApplyState Exception " + ext.ToString());
                    }
                    pawn.Drawer.DrawTrackerTick();
                }
            }

            if (thing is Fire)
            {
                (thing as Fire).fireSize = (float)state.HitPoints / 10000f;
            }
            else
            {
                if (thing.def.useHitPoints)
                {
                    Loger.Log("Client ApplyState Set HitPoints " + thing.HitPoints.ToString() + " -> " + state.HitPoints.ToString());
                    thing.HitPoints = state.HitPoints;
                }
            }

            if (thing is Pawn)
            {
                var pawn = thing as Pawn;
                if ((int)pawn.health.State != (int)state.DownState)
                {
                    if (pawn.health.State == PawnHealthState.Dead)
                    {
                        Loger.Log("Client ApplyState Set pawn state is Dead! Error to change on " + state.DownState.ToString());
                    }
                    else if (state.DownState == AttackThingState.PawnHealthState.Dead)
                    {
                        if (pawnHealthStateDead)
                        {
                            Loger.Log("Client ApplyState Set pawn state (1): " + pawn.health.State.ToString() + " -> " + state.DownState.ToString());
                            HealthUtility.DamageUntilDead(pawn);
                            //PawnKill(pawn);
                        }
                    }
                    else if (state.DownState == AttackThingState.PawnHealthState.Down)
                    {
                        Loger.Log("Client ApplyState Set pawn state (2): " + pawn.health.State.ToString() + " -> " + state.DownState.ToString());
                        //todo! Применяем наркоз?
                        HealthUtility.DamageUntilDowned(pawn, false);
                    }
                    else
                    {
                        Loger.Log("Client ApplyState Set pawn state (3): " + pawn.health.State.ToString() + " -> " + state.DownState.ToString());
                        //полное лечение
                        pawn.health.Notify_Resurrected();
                    }
                }
            }
        }
Beispiel #2
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;
            }
        }