#Observed object issue in client

3 messages · Page 1 of 1 (latest)

pine fossil
#

    public struct IngameObjectModel
    {
        public int CurrentHp;
        public int StatHp;
        public int StatArmor;
        public int StatAttack;
        public short ObjectState;
        public short DamageType;
        public int SoulLinkId;
        public bool IsLinked;

        public void SetStats(PlayerLevelUpModel model)
        {
            var stats = DataManager.PlayerLevelSetting.LevelUpCanUpStats;
            int length = stats.Length;

            for (int i = 0; i < length; i++)
            {
                var stat = stats[i];

                SetStatValue(stat, model.GetStatValue(stat));
            }
        }

        public int GetStatValue(StatType stat)
        {
            return stat switch
            {
                StatType.Hp => StatHp,
                StatType.Attack => StatAttack,
                StatType.Armor => StatArmor,
                _ => throw new Exception("Wrong stat enum")
            };
        }

        public void SetStatValue(StatType stat, int value)
        {
            switch (stat)
            {
                case StatType.Hp:
                {
                    StatHp = value;
                }
                    break;
                case StatType.Attack:
                {
                    StatAttack = value;
                }
                    break;
                case StatType.Armor:
                {
                    StatArmor = value;
                }
                    break;
                default:
                    throw new Exception("Wrong stat enum");
            }

            ;
        }

        public void DebugLog()
        {
#if ENABLE_LOG
            Debug.Log($"<color=red>Start IngameObjectModel Debugging</color>");
            Debug.Log($"<color=red>CurrentHp : {CurrentHp}</color>");
            Debug.Log($"<color=red>StatHp : {StatHp}</color>");
            Debug.Log($"<color=red>StatArmor : {StatArmor}</color>");
            Debug.Log($"<color=red>StatAttack : {StatAttack}</color>");
            Debug.Log($"<color=red>ObjectState : {ObjectState}</color>");
            Debug.Log($"<color=red>End IngameObjectModel Debugging</color>");
#endif
        }
    }
#
    public class SyncIngameObjectModel : SyncModelBase<IngameObjectModel, SyncIngameObjectModelOperation>, ICustomSync
    {
        /// <summary>
        /// Sets current values.
        /// </summary>
        /// <param name="reader"></param>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        protected override void Read(PooledReader reader, bool asServer)
        {
            /* When !asServer don't make changes if server is running.
             * This is because changes would have already been made on
             * the server side and doing so again would result in duplicates
             * and potentially overwrite data not yet sent. */
            bool asClientAndHost = (!asServer && InstanceFinder.NetworkManager.IsServerStarted);

            int changes = reader.ReadInt32();
            for (int i = 0; i < changes; i++)
            {
                SyncIngameObjectModelOperation operation = (SyncIngameObjectModelOperation)reader.ReadByte();
                IngameObjectModel prev = GetValue(asServer);
                IngameObjectModel next = prev;

                switch (operation)
                {
                    case SyncIngameObjectModelOperation.Full:
                    {
                        next = reader.Read<IngameObjectModel>();
                    }
                        break;
                    case SyncIngameObjectModelOperation.CurrentHp:
                    {
                        next.CurrentHp = reader.ReadInt32();
                        next.DamageType = reader.ReadInt16();
                    }
                        break;
                    case SyncIngameObjectModelOperation.ObjectState:
                    {
                        short state = reader.ReadInt16();
                        next.ObjectState = state;
                    }
                        break;
                    case SyncIngameObjectModelOperation.LevelUp:
                    {
                        next.StatHp = reader.ReadInt32();
                        next.StatAttack = reader.ReadInt32();
                        next.StatArmor = reader.ReadInt32();
                    }
                        break;
                    case SyncIngameObjectModelOperation.SetSoulLinkId:
                    {
                        next.StatHp = reader.ReadInt32();
                        next.CurrentHp = reader.ReadInt32();
                        next.SoulLinkId = reader.ReadInt32();
                        next.IsLinked = reader.ReadBoolean();
                    }
                        break;
                    case SyncIngameObjectModelOperation.SetHpStat:
                    {
                        next.StatHp = reader.ReadInt32();
                    }
                        break;
                }

                if (!asClientAndHost)
                    SetValue(asServer, next);
                InvokeOnChange(operation, prev, next, asServer);
            }
        }
#

        /// <summary>
        /// Writes all changed values.
        /// </summary>
        /// <param name="writer"></param>
        ///<param name="resetSyncTick">True to set the next time data may sync.</param>
        protected override void WriteDelta(PooledWriter writer, bool resetSyncTick = true)
        {
            base.WriteDelta(writer, resetSyncTick);
            writer.WriteInt32(_changed.Count);

            for (int i = 0; i < _changed.Count; i++)
            {
                ChangeData change = _changed[i];
                writer.WriteByte((byte)change.Operation);

                switch (change.Operation)
                {
                    case SyncIngameObjectModelOperation.CurrentHp:
                    {
                        writer.WriteInt32(change.Data.CurrentHp);
                        writer.WriteInt16((short)change.Data.DamageType);
                    }
                        break;
                    case SyncIngameObjectModelOperation.ObjectState:
                    {
                        var state = change.Data.ObjectState;
                        writer.WriteInt16((short)state);
                    }
                        break;
                    case SyncIngameObjectModelOperation.LevelUp:
                    {
                        writer.WriteInt32(change.Data.GetStatValue(StatType.Hp));
                        writer.WriteInt32(change.Data.GetStatValue(StatType.Attack));
                        writer.WriteInt32(change.Data.GetStatValue(StatType.Armor));
                    }
                        break;
                    case SyncIngameObjectModelOperation.SetSoulLinkId:
                    {
                        writer.WriteInt32(change.Data.StatHp);
                        writer.WriteInt32(change.Data.CurrentHp);
                        writer.WriteInt32(change.Data.SoulLinkId);
                        writer.WriteBoolean(change.Data.IsLinked);
                    }
                        break;
                    case SyncIngameObjectModelOperation.SetHpStat:
                    {
                        writer.WriteInt32(change.Data.StatHp);
                    }
                        break;
                }
            }

            _changed.Clear();
        }