private void OnStatusChanged(object sender, StatusChangedEventArgs args)
        {
            Debugger.WriteLine($"Changed status for property {EnumHelper.GetName(args.Tag)}");
            MaidInfo maid = SelectedMaid;

            if (maid == null)
            {
                Debugger.WriteLine(LogLevel.Warning, "Maid is NULL!");
                return;
            }

            if (maid.Maid != args.CallerMaid)
            {
                Debugger.WriteLine(LogLevel.Warning, "Caller maid is not the selected one! Aborting...");
                return;
            }

            if (!valueUpdateQueue[currentQueue].ContainsKey(args.Tag))
            {
                valueUpdateQueue[currentQueue].Add(args.Tag, () => maid.UpdateField(args.Tag, args.ID, args.Value));
            }
            else
            {
                Debugger.WriteLine(LogLevel.Warning, $"Tag already in update queue {currentQueue}! Aborting...");
            }
        }
        private void UpdateMaid_YotogiClassValue <T>(DataGridView table, int col, int row)
        {
            MaidInfo maid = SelectedMaid;

            if (maid == null)
            {
                return;
            }

            object val = table[col, row].Value;

            if (val is bool)
            {
                val = !((bool)val);
            }

            if (table == dataGridView_maid_classes)
            {
                if (!updateMaidClassField)
                {
                    if (val is T)
                    {
                        maid.SetMaidClassValue(row, col, val);
                    }
                    else
                    {
                        maid.UpdateField(MaidChangeType.MaidClassType, row);
                    }
                }
                updateMaidClassField = false;
            }
            else if (table == dataGridView_yotogi_classes)
            {
                if (!updateYotogiClassField)
                {
                    if (val is T)
                    {
                        maid.SetYotogiClassValue(EnumHelper.EnabledYotogiClasses[row], col, val);
                    }
                    else
                    {
                        maid.UpdateField(MaidChangeType.YotogiClassType, EnumHelper.EnabledYotogiClasses[row]);
                    }
                }
                updateYotogiClassField = false;
            }
        }
        private void OnStatusChanged(object sender, StatusEventArgs args)
        {
            Debugger.WriteLine($"Changed status for property {EnumHelper.GetName(args.Tag)}");
            Debugger.WriteLine(
                $"Called maid: {args.CallerMaid.Param.status.first_name} {args.CallerMaid.Param.status.last_name}");

            if (!IsMaidLoaded(args.CallerMaid))
            {
                Debugger.WriteLine(LogLevel.Error, "Maid not in the list! Aborting!");
                return;
            }

            MaidInfo maid = GetMaidInfo(args.CallerMaid);

            if (maid.IsLocked(args.Tag))
            {
                Debugger.WriteLine(LogLevel.Info, "Value locked! Aborting changes...");
                args.BlockAssignment = true;
                return;
            }

            if (SelectedMaid != null && SelectedMaid.Maid != maid.Maid)
            {
                Debugger.WriteLine(LogLevel.Warning, "Selected maids are different!");
                return;
            }

            if (!valueUpdateQueue[currentQueue].ContainsKey(args.Tag))
            {
                Debugger.WriteLine(LogLevel.Info, "Adding to update queue");
                valueUpdateQueue[currentQueue].Add(args.Tag, () => maid.UpdateField(args.Tag));
            }
            else
            {
                Debugger.WriteLine(
                    LogLevel.Warning,
                    $"Already in update queue {currentQueue}! Queue length: {valueUpdateQueue[currentQueue].Count}");
            }
        }
        private void OnCellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            if (clearingTables || e.ColumnIndex == PARAMS_COLUMN_LOCK)
            {
                return;
            }
            DataGridView table = (DataGridView)sender;
            MaidInfo     maid  = SelectedMaid;

            if (SelectedMaid == null)
            {
                return;
            }

            MaidChangeType?type = null;

            if (table == dataGridView_params)
            {
                type = maidParamsTableDic[e.RowIndex];
            }
            else if (table == dataGridView_ero_zones)
            {
                type = maidEroTableDic[e.RowIndex];
            }
            else if (table == dataGridView_maid_params_bonus)
            {
                type = maidBonusStatsTableDic[e.RowIndex];
            }
            else if (table == dataGridView_statistics)
            {
                type = maidStatsTableDic[e.RowIndex];
            }
            if (type == null)
            {
                return;
            }

            if (valueUpdate[type.Value])
            {
                valueUpdate[type.Value] = false;
                return;
            }

            object val = table[e.ColumnIndex, e.RowIndex].Value;

            if (!(val is int) && !(val is long))
            {
                maid.UpdateField(type.Value);
                return;
            }

            if (maid.IsHardLocked(type.Value))
            {
                Debugger.WriteLine(
                    LogLevel.Info,
                    $"Value {EnumHelper.GetName(type.Value)} is locked! Unlocking temporarily...");
                maid.UnlockTemp(type.Value);
            }

            maid.SetValue(type.Value, val);
        }