Beispiel #1
0
        void AddShipFate(Ship rpShip, Fate rpFate, long rpTimestamp = 0)
        {
            using (var rTransaction = Connection.BeginTransaction())
            {
                var rTimestamp = rpTimestamp == 0 ? DateTimeOffset.Now.ToUnixTime() : rpTimestamp;

                using (var rCommand = Connection.CreateCommand())
                {
                    rCommand.CommandText = "INSERT OR IGNORE INTO ship_fate(id, ship, level, time, fate) VALUES(@id, @ship, @level, @timestamp, @fate);";
                    rCommand.Parameters.AddWithValue("@id", rpShip.ID);
                    rCommand.Parameters.AddWithValue("@ship", rpShip.Info.ID);
                    rCommand.Parameters.AddWithValue("@level", rpShip.Level);
                    rCommand.Parameters.AddWithValue("@timestamp", rTimestamp);
                    rCommand.Parameters.AddWithValue("@fate", (int)rpFate);

                    rCommand.ExecuteNonQuery();
                }

                if (rpShip.EquipedEquipment.Count > 0)
                {
                    AddEquipmentFate(rpShip.EquipedEquipment, rpFate, rTimestamp);
                }

                rTransaction.Commit();
            }
        }
Beispiel #2
0
        void Disconnect()
        {
            Resources?.Dispose();
            Experience?.Dispose();
            Expedition?.Dispose();
            Construction?.Dispose();
            Development?.Dispose();
            Sortie?.Dispose();
            Battle?.Dispose();
            Fate?.Dispose();
            r_RankingPoints?.Dispose();
            r_SortieConsumption?.Dispose();
            QuestProgress?.Dispose();
            BattleDetail?.Dispose();

            if (r_Connection != null)
            {
                r_Connection.Update -= OnDatabaseUpdate;

                r_Connection.Dispose();
            }

            foreach (var rCustomGroup in r_CustomRecordsGroups.Values)
            {
                rCustomGroup.Dispose();
            }

            IsConnected = false;
        }
Beispiel #3
0
        internal static bool IsFateTypeEnabled(Fate oracleFate)
        {
            switch (oracleFate.Type)
            {
            case FateType.Kill:
                return(FateSettings.Instance.KillFatesEnabled);

            case FateType.Collect:
                return(FateSettings.Instance.CollectFatesEnabled);

            case FateType.Escort:
                return(FateSettings.Instance.EscortFatesEnabled);

            case FateType.Defence:
                return(FateSettings.Instance.DefenceFatesEnabled);

            case FateType.Boss:
                return(FateSettings.Instance.BossFatesEnabled);

            case FateType.MegaBoss:
                return(FateSettings.Instance.MegaBossFatesEnabled);

            case FateType.Null:
                return(true);
            }

            return(true);
        }
Beispiel #4
0
        void AddShipFate(IEnumerable <Ship> rpShips, Fate rpFate, long rpTimestamp = 0)
        {
            if (!rpShips.Any())
            {
                return;
            }

            using (var rTransaction = Connection.BeginTransaction())
            {
                var rTimestamp = rpTimestamp == 0 ? DateTimeOffset.Now.ToUnixTime() : rpTimestamp;

                using (var rCommand = Connection.CreateCommand())
                {
                    rCommand.CommandText = "INSERT OR IGNORE INTO ship_fate(id, ship, level, time, fate) VALUES" + rpShips.Select(r => $"({r.ID}, {r.Info.ID}, {r.Level}, @timestamp, @fate)").Join(", ") + ";";
                    rCommand.Parameters.AddWithValue("@timestamp", rTimestamp);
                    rCommand.Parameters.AddWithValue("@fate", (int)rpFate);

                    rCommand.ExecuteNonQuery();
                }

                AddEquipmentFate(rpShips.SelectMany(r => r.EquipedEquipment), rpFate, rTimestamp);

                rTransaction.Commit();
            }
        }
Beispiel #5
0
        public Fate GetFateFromId(uint id)
        {
            Fate fate;

            try
            {
                if (FateDictionary.TryGetValue(id, out fate))
                {
                    return(fate);
                }
            }
            catch (ArgumentNullException exception)
            {
                Logger.SendErrorLog("Error looking up FATE in the database.");
                Logger.SendDebugLog("ArgumentNullException thrown:\n\n" + exception + "\n");
            }

            // Create a null fate with Unsupported flag if we can't find it.
            fate = new Fate
            {
                SupportLevel = FateSupportLevel.Unsupported
            };
            Logger.SendDebugLog("Fate with id: '" + id + "' not found, flagging as unsupported.");

            return(fate);
        }
        private static double GetWeight(BattleCharacter battleCharacter)
        {
            var weight      = 1800f;
            var currentFate = OracleFateManager.GetCurrentFateData();
            var oracleFate  = new Fate();

            if (currentFate != null)
            {
                oracleFate = OracleFateManager.FateDatabase.GetFateFromFateData(currentFate);
            }

            // If FATE has a preferred target, prioritise it if we're out of combat.
            if (oracleFate.PreferredTargetId != null && oracleFate.PreferredTargetId.Contains(battleCharacter.NpcId) && !Core.Player.InCombat)
            {
                weight += 20000;
            }

            if (battleCharacter.Pointer == Core.Player.PrimaryTargetPtr)
            {
                weight += 150;
            }

            if (battleCharacter.HasTarget && battleCharacter.CurrentTargetId == Core.Player.ObjectId)
            {
                weight += 750;
            }

            if (ChocoboManager.Object != null && battleCharacter.HasTarget && battleCharacter.CurrentTargetId == ChocoboManager.Object.ObjectId)
            {
                weight += 400;
            }

            if (!battleCharacter.TappedByOther)
            {
                weight += 200;
            }

            if (battleCharacter.CurrentTargetId == Core.Player.ObjectId)
            {
                weight += 1000 / Convert.ToSingle(battleCharacter.CurrentHealth) * 3000;
            }

            if (!battleCharacter.InCombat)
            {
                weight += 130;
            }

            // Prefer nearer targets in combat if melee, and always out of combat.
            if (OracleClassManager.IsMeleeDpsClassJob(Core.Player.CurrentJob) || OracleClassManager.IsTankClassJob(Core.Player.CurrentJob) ||
                !Core.Player.InCombat)
            {
                weight -= battleCharacter.Distance(Core.Player) * 30;
            }

            return(weight);
        }
 public static FateViewModel ToFateVM(this Fate f)
 {
     return(new FateViewModel
     {
         Id = f.Id,
         Name = f.Name,
         Order = f.Order.GetValueOrDefault(),
         Label = f.Label
     });
 }
Beispiel #8
0
        public ActionResult Create(Fate fate)
        {
            if (ModelState.IsValid)
            {
                fate.Order   = m_repo.GetFates().Max(t => t.Order.GetValueOrDefault()) + 1;
                fate.Retired = false;
                m_repo.SaveFate(fate);
                return(RedirectToAction("Index"));
            }

            return(View(fate));
        }
Beispiel #9
0
        void AddEquipmentFate(Equipment rpEquipment, Fate rpFate)
        {
            using (var rCommand = Connection.CreateCommand())
            {
                rCommand.CommandText = "INSERT OR IGNORE INTO equipment_fate(id, equipment, level, proficiency, time, fate) VALUES(@id, @equipment, @level, @proficiency, strftime('%s', 'now'), @fate);";
                rCommand.Parameters.AddWithValue("@id", rpEquipment.ID);
                rCommand.Parameters.AddWithValue("@equipment", rpEquipment.Info.ID);
                rCommand.Parameters.AddWithValue("@level", rpEquipment.Level);
                rCommand.Parameters.AddWithValue("@proficiency", rpEquipment.Proficiency);
                rCommand.Parameters.AddWithValue("@fate", (int)rpFate);

                rCommand.ExecuteNonQuery();
            }
        }
Beispiel #10
0
        public ActionResult Edit(Fate fate)
        {
            if (fate == null)
            {
                return(new HttpStatusCodeResult(HttpStatusCode.BadRequest));
            }

            if (ModelState.IsValid)
            {
                m_repo.SaveFate(fate);
                return(RedirectToAction("Index"));
            }

            return(View(fate));
        }
Beispiel #11
0
        // GET: Fates/Edit/5
        public ActionResult Edit(int?id)
        {
            if (id == null)
            {
                return(new HttpStatusCodeResult(HttpStatusCode.BadRequest));
            }

            Fate fate = m_repo.GetFate(id.Value);

            if (fate == null)
            {
                return(HttpNotFound());
            }
            return(View(fate));
        }
Beispiel #12
0
        /// <summary>
        /// La creatura attacca un'altra creatura
        /// Restituisce i dati relativi all'attacco cioè:
        /// Risultati, danno effettuati e danni subiti -> AttackResult struct
        /// </summary>
        public override AttackResult Attack(Creature other)
        {
            AttackResult result;

            if (base.IsDead || base.IsUnconscious || other.IsDead || other.IsUnconscious)
            {
                result = new AttackResult(Results.Failed, 0, 0);
            }
            else
            {
                int res = other.Parry(Fate.Next(0, Strenght + 1), CriticalHit(), this);
                if (res > 0)
                {
                    result = new AttackResult(Results.Success, res, 0);

                    //se il guerriero uccide la creatura nemica aumenta l'esperienza
                    //e riceve la metà dei soldi che possedeva l'altra creatura (li ruba in fretta)
                    if (other.IsDead || other.IsUnconscious)
                    {
                        _level.GainExperience(10 * other.Level);
                        if (_level.LevelUp())
                        {
                            LevelUpCharacteristic();
                        }

                        _money += (other.Money / 2);
                    }
                }
                else if (res < 0)
                {
                    result = new AttackResult(Results.ParryAndRiposte, 0, res * (-1));
                }
                else
                {
                    result = new AttackResult(Results.Parry, 0, 0);
                }

                _weapon.ReduceIntegrity();
                if (_weapon.Integrity <= (int)(0.15f * _weapon.InitialIntegrity) &&
                    _money >= _weapon.CostForRepair)
                {
                    _money -= _weapon.CostForRepair;
                    _weapon.Repair();
                }
            }

            return(result);
        }
Beispiel #13
0
        public void RefreshFate(Fate value)
        {
            _txtTitle.text = value.title;
            _txtNnum.text  = "1";
            if (null != _imgPic)
            {
                WebManager.Instance.LoadWebItem(value.cardPath, item => {
                    using (item)
                    {
                        _imgPic.sprite = item.sprite;
                    }
                });
            }

            fate = value;
        }
Beispiel #14
0
        void AddEquipmentFate(IEnumerable <Equipment> rpEquipment, Fate rpFate, long rpTimestamp = 0)
        {
            if (!rpEquipment.Any())
            {
                return;
            }

            using (var rCommand = Connection.CreateCommand())
            {
                rCommand.CommandText = "INSERT OR IGNORE INTO equipment_fate(id, equipment, level, proficiency, time, fate) VALUES" + rpEquipment.Select(r => $"({r.ID}, {r.Info.ID}, {r.Level}, {r.Proficiency}, @timestamp, @fate)").Join(", ") + ";";
                rCommand.Parameters.AddWithValue("@timestamp", rpTimestamp == 0 ? DateTimeOffset.Now.ToUnixTime() : rpTimestamp);
                rCommand.Parameters.AddWithValue("@fate", (int)rpFate);

                rCommand.ExecuteNonQuery();
            }
        }
Beispiel #15
0
        public ActionResult Retire(int?id)
        {
            if (!id.HasValue)
            {
                return(new HttpStatusCodeResult(HttpStatusCode.BadRequest));
            }
            Fate fate = m_repo.GetFate(id.Value);

            if (fate == null)
            {
                return(HttpNotFound());
            }
            fate.Retired = !fate.Retired;
            m_repo.SaveFate(fate);
            return(RedirectToAction("Index"));
        }
        internal FateRecord(SQLiteDataReader rpReader)
        {
            ID = rpReader.GetInt64("time");

            var rMasterInfo = KanColleGame.Current.MasterInfo;
            var rMasterID = rpReader.GetInt32("master_id");
            IsEquipment = rpReader.GetBoolean("is_equipment");
            if (!IsEquipment)
                Ship = rMasterInfo.Ships[rMasterID];
            else
                Equipment = rMasterInfo.Equipment[rMasterID];

            Level = rpReader.GetInt32("level");
            Proficiency = rpReader.GetInt32("proficiency");

            Fate = (Fate)rpReader.GetInt32("fate");
        }
Beispiel #17
0
 public void AddFateToDatabase(Fate fate)
 {
     try
     {
         FateDictionary.Add(fate.Id, fate);
     }
     catch (ArgumentNullException exception)
     {
         Logger.SendErrorLog("Error adding FATE to the database.");
         Logger.SendDebugLog("ArgumentNullException thrown:\n\n" + exception + "\n");
     }
     catch (ArgumentException exception)
     {
         Logger.SendErrorLog("Error adding FATE to the database.");
         Logger.SendDebugLog("ArgumentException thrown:\n\n" + exception + "\n");
     }
 }
        internal FateRecord(SQLiteDataReader rpReader)
        {
            Time = DateTimeUtil.FromUnixTime(Convert.ToUInt64(rpReader["time"])).LocalDateTime.ToString();

            var rMasterInfo = KanColleGame.Current.MasterInfo;
            var rMasterID = Convert.ToInt32(rpReader["master_id"]);
            IsEquipment = Convert.ToBoolean(rpReader["is_equipment"]);
            if (!IsEquipment)
                Ship = rMasterInfo.Ships[rMasterID];
            else
                Equipment = rMasterInfo.Equipment[rMasterID];

            Level = Convert.ToInt32(rpReader["level"]);
            Proficiency = Convert.ToInt32(rpReader["proficiency"]);

            Fate = (Fate)Convert.ToInt32(rpReader["fate"]);
        }
Beispiel #19
0
        private static Fate CreateFate()
        {
            var fate = new Fate
            {
                ChainId           = fateChainId,
                Id                = fateId,
                ItemId            = fateCollectItemId,
                LandingRadius     = fateLandingRadius,
                Level             = fateLevel,
                Name              = fateName,
                NpcId             = fateNpcId,
                PreferredTargetId = fatePreferredTargetId,
                SupportLevel      = fateSupportLevel,
                Type              = fateType
            };

            return(fate);
        }
Beispiel #20
0
        public void SetContent(Fate value)
        {
            _txtLbcardname.text = value.title;



            var str  = value.cardIntroduce;
            var str1 = str.Replace("\\u3000", "\u3000");
            var str2 = str1.Replace("\\n", "\n");

            _txtDesc.text = str2;


            WebManager.Instance.LoadWebItem(value.cardPath, item => {
                using (item)
                {
                    _imgShowImage.sprite = item.sprite;
                }
            });
        }
        internal FateRecord(SQLiteDataReader rpReader)
        {
            Time = DateTimeUtil.FromUnixTime(Convert.ToInt64(rpReader["time"])).LocalDateTime.ToString();

            var rMasterInfo = KanColleGame.Current.MasterInfo;
            var rMasterID   = Convert.ToInt32(rpReader["master_id"]);

            IsEquipment = Convert.ToBoolean(rpReader["is_equipment"]);
            if (!IsEquipment)
            {
                Ship = rMasterInfo.Ships[rMasterID];
            }
            else
            {
                Equipment = rMasterInfo.Equipment[rMasterID];
            }

            Level       = Convert.ToInt32(rpReader["level"]);
            Proficiency = Convert.ToInt32(rpReader["proficiency"]);

            Fate = (Fate)Convert.ToInt32(rpReader["fate"]);
        }
        internal FateRecord(SQLiteDataReader rpReader)
        {
            ID = rpReader.GetInt64("time");

            var rMasterInfo = KanColleGame.Current.MasterInfo;
            var rMasterID   = rpReader.GetInt32("master_id");

            IsEquipment = rpReader.GetBoolean("is_equipment");
            if (!IsEquipment)
            {
                Ship = rMasterInfo.Ships[rMasterID];
            }
            else
            {
                Equipment = rMasterInfo.Equipment[rMasterID];
            }

            Level       = rpReader.GetInt32("level");
            Proficiency = rpReader.GetInt32("proficiency");

            Fate = (Fate)rpReader.GetInt32("fate");
        }
Beispiel #23
0
        /// <summary>
        /// La creatura attacca un'altra creatura
        /// Restituisce i dati relativi all'attacco cioè:
        /// Risultati, danno effettuati e danni subiti -> AttackResult struct
        /// </summary>
        public override AttackResult Attack(Creature other)
        {
            AttackResult result;

            if (base.IsDead || base.IsUnconscious || other.IsDead || other.IsUnconscious)
            {
                result = new AttackResult(Results.Failed, 0, 0);
            }
            else
            {
                int res = other.Parry(Fate.Next(0, Strenght + 1), CriticalHit(), this);
                if (res > 0)
                {
                    result = new AttackResult(Results.Success, res, 0);
                    //se il goblin uccide la creatura nemica aumenta l'esperienza
                    //e ruba tutti i soldi che possedeva l'altra creatura
                    if (other.IsDead || other.IsUnconscious)
                    {
                        _level.GainExperience(10 * other.Level);
                        if (_level.LevelUp())
                        {
                            LevelUpCharacteristic();
                        }

                        _money += (other.Money);
                    }
                }
                else if (res < 0)
                {
                    result = new AttackResult(Results.ParryAndRiposte, 0, res * (-1));
                }
                else
                {
                    result = new AttackResult(Results.Parry, 0, 0);
                }
            }

            return(result);
        }
        public void HurrayDwarfFate(Fate fate, NPCdata npcdata, MT19337 rng)
        {
            if (fate == Fate.Spare)
            {
                // Protect Hurray Dwarf from NPC guillotine
                npcdata.SetRoutine(ObjectId.DwarfcaveDwarfHurray, newTalkRoutines.Talk_norm);
            }
            else
            {
                // Whether NPC guillotine is on or not, kill Hurray Dwarf
                npcdata.SetRoutine(ObjectId.DwarfcaveDwarfHurray, newTalkRoutines.Talk_kill);

                // Change the dialogue
                var dialogueStrings = new List <string>
                {
                    "No! I'm gonna disappear.\nYou'll never see\nme again. Please,\nI don't want to die.",
                    "If you strike me down,\nI shall become more\npowerful than you can\npossibly imagine.",
                    "Freeeeedom!!",
                    "I've seen things you\npeople wouldn't believe.\nAll those moments will\nbe lost in time..\nlike tears in rain..\nTime to die.",
                    "Become vengeance, David.\nBecome wrath.",
                    "My only regret..\nis that I have boneitis.",
                    "No, not the bees!\nNOT THE BEES!\nAAAAAAAAGH!\nTHEY'RE IN MY EYES!\nMY EYES! AAAAAAAAAAGH!",
                    "This is blasphemy!\nThis is madness!",
                    "Not like this..\nnot like this..",
                    "Suicide squad, attack!\n\n\n\nThat showed 'em, huh?",
                    "Well, what are you\nwaiting for?\nDo it. DO IT!!",
                    "The path you walk on has\nno end. Each step you\ntake is paved with the\ncorpses of your enemies.\nTheir souls will haunt\nyou forever. Hear me!\nMy spirit will be\nwatching you!",
                    "K-Kefka..!\nY-you're insane.."
                };

                //Put new dialogue to E6 since another Dwarf also says hurray
                InsertDialogs(0xE6, dialogueStrings.PickRandom(rng));
                npcdata.GetTalkArray(ObjectId.DwarfcaveDwarfHurray)[(int)TalkArrayPos.dialogue_1] = 0xE6;
                npcdata.GetTalkArray(ObjectId.DwarfcaveDwarfHurray)[(int)TalkArrayPos.dialogue_2] = 0xE6;
                npcdata.GetTalkArray(ObjectId.DwarfcaveDwarfHurray)[(int)TalkArrayPos.dialogue_3] = 0xE6;
            }
        }
        void AddEquipmentFate(Equipment rpEquipment, Fate rpFate)
        {
            using (var rCommand = Connection.CreateCommand())
            {
                rCommand.CommandText = "INSERT OR IGNORE INTO equipment_fate(id, equipment, level, proficiency, time, fate) VALUES(@id, @equipment, @level, @proficiency, strftime('%s', 'now'), @fate);";
                rCommand.Parameters.AddWithValue("@id", rpEquipment.ID);
                rCommand.Parameters.AddWithValue("@equipment", rpEquipment.Info.ID);
                rCommand.Parameters.AddWithValue("@level", rpEquipment.Level);
                rCommand.Parameters.AddWithValue("@proficiency", rpEquipment.Proficiency);
                rCommand.Parameters.AddWithValue("@fate", (int)rpFate);

                rCommand.ExecuteNonQuery();
            }
        }
Beispiel #26
0
 /// <summary>
 /// Metodo per controllare se si verifica un colpo critico oppure no,
 /// Di default un goblin ha il 2% di chance di effettuare un colpo critico
 /// </summary>
 protected override int CriticalHit( )
 {
     return(Fate.Next(0, 101) < _criticalHitChances ? 2 : 1);
 }
        void Connect(int rpUserID)
        {
            if (r_UserID == rpUserID)
            {
                return;
            }

            Resources?.Dispose();
            Ships?.Dispose();
            Experience?.Dispose();
            Expedition?.Dispose();
            Construction?.Dispose();
            Development?.Dispose();
            Sortie?.Dispose();
            Battle?.Dispose();
            RankingPoints?.Dispose();
            Fate?.Dispose();
            QuestProgress?.Dispose();
            BattleDetail?.Dispose();

            if (r_Connection != null)
            {
                r_Connection.Update -= OnDatabaseUpdate;

                r_Connection.Dispose();
            }

            foreach (var rCustomGroup in r_CustomRecordsGroups.Values)
            {
                rCustomGroup.Dispose();
            }

            IsConnected = false;

            r_UserID = rpUserID;

            r_Connection = new SQLiteConnection($@"Data Source=Records\{r_UserID}.db;Page Size=8192").OpenAndReturn();

            if (IsReadOnlyMode)
            {
                using (var rSourceConnection = r_Connection)
                {
                    r_Connection = new SQLiteConnection("Data Source=:memory:;Page Size=8192").OpenAndReturn();
                    rSourceConnection.BackupDatabase(r_Connection, "main", "main", -1, null, 0);
                }
            }

            using (var rTransaction = r_Connection.BeginTransaction())
            {
                CheckVersion();

                Resources     = new ResourcesRecords(r_Connection).ConnectAndReturn();
                Ships         = new ShipsRecords(r_Connection).ConnectAndReturn();
                Experience    = new ExperienceRecords(r_Connection).ConnectAndReturn();
                Expedition    = new ExpeditionRecords(r_Connection).ConnectAndReturn();
                Construction  = new ConstructionRecords(r_Connection).ConnectAndReturn();
                Development   = new DevelopmentRecords(r_Connection).ConnectAndReturn();
                Sortie        = new SortieRecords(r_Connection).ConnectAndReturn();
                Battle        = new BattleRecords(r_Connection).ConnectAndReturn();
                RankingPoints = new RankingPointsRecords(r_Connection).ConnectAndReturn();
                Fate          = new FateRecords(r_Connection).ConnectAndReturn();

                QuestProgress = new QuestProgressRecords(r_Connection).ConnectAndReturn();

                foreach (var rProvider in r_CustomRecordsGroupProviders)
                {
                    var rGroup = rProvider.Create(r_Connection).ConnectAndReturn();
                    r_CustomRecordsGroups[rGroup.GroupName] = rGroup;
                }

                rTransaction.Commit();
            }

            BattleDetail = new BattleDetailRecords(r_Connection, r_UserID).ConnectAndReturn();

            r_Connection.Update += OnDatabaseUpdate;

            IsConnected = true;
        }
Beispiel #28
0
 public void setFate(Fate value)
 {
     fate = value;
 }
Beispiel #29
0
        public static void CallMenu()
        {
            Fate = MainMenu.AddMenu("Twisted Fate", "twistedfate");
            Fate.AddGroupLabel("Twisted Fate by mztikk");

            Combo = Fate.AddSubMenu("Combo", "combo");
            Combo.Add("useQinCombo", new CheckBox("Use Q in combo"));
            Combo.Add("qAAReset", new CheckBox("Only use Q after AA to reset", false));
            Combo.Add("useWinCombo", new CheckBox("Use W in Combo"));
            Combo.Add("yellowIntoQ", new CheckBox("Q after Yellow Card", false));
            Combo.Add("wModeC", new ComboBox("W Mode", 0, "Smart Mode", "Always Yellow", "Always Blue", "Always Red"));
            Combo.Add("disableAAselectingC", new CheckBox("Disable AA while selecting a card", false));

            Harass = Fate.AddSubMenu("Harass", "harass");
            Harass.AddGroupLabel("Harass");
            Harass.Add("useQinHarass", new CheckBox("Use Q in Harass"));
            Harass.Add("useWinHarass", new CheckBox("Use W in Harass"));
            Harass.Add("wModeH", new ComboBox("W Mode", 0, "Smart Mode", "Always Yellow", "Always Blue", "Always Red"));
            Harass.Add("disableAAselectingH", new CheckBox("Disable AA while selecting a card", false));
            Harass.Add("manaToHarass", new Slider("Min Mana % to Harass", 50));
            Harass.AddGroupLabel("Auto Harass");
            Harass.Add("autoQ", new CheckBox("Auto Q Harass"));
            Harass.Add("manaToAHarass", new Slider("Min Mana % to Auto Harass", 50));

            LaneClear = Fate.AddSubMenu("LaneClear", "laneclear");
            LaneClear.Add("useQinLC", new CheckBox("Use Q in LaneClear"));
            LaneClear.Add("qTargetsLC", new Slider("Min Targets to hit for Q", 3, 1, 10));
            LaneClear.Add("useWinLC", new CheckBox("Use W in LaneClear"));
            LaneClear.Add(
                "wModeLC",
                new ComboBox("W Mode", 0, "Smart Mode", "Always Yellow", "Always Blue", "Always Red"));
            LaneClear.Add("disableAAselectingLC", new CheckBox("Disable AA while selecting a card", false));
            LaneClear.Add("manaToLC", new Slider("Min Mana % to LaneClear", 30));

            JungleClear = Fate.AddSubMenu("JungleClear", "jungleclear");
            JungleClear.Add("useQinJC", new CheckBox("Use Q in JungleClear"));
            JungleClear.Add("useWinJC", new CheckBox("Use W in JungleClear"));
            JungleClear.Add(
                "wModeJC",
                new ComboBox("W Mode", 0, "Smart Mode", "Always Yellow", "Always Blue", "Always Red"));
            JungleClear.Add("disableAAselectingJC", new CheckBox("Disable AA while selecting a card", false));
            JungleClear.Add("manaToJC", new Slider("Min Mana % to JungleClear", 10));

            CardSelectorMenu = Fate.AddSubMenu("CardSelector", "cardselector");
            CardSelectorMenu.Add(
                "csYellow",
                new KeyBind("Select Yellow Card", false, KeyBind.BindTypes.HoldActive, 'W'));
            CardSelectorMenu.Add("csBlue", new KeyBind("Select Blue Card", false, KeyBind.BindTypes.HoldActive, 'E'));
            CardSelectorMenu.Add("csRed", new KeyBind("Select Red Card", false, KeyBind.BindTypes.HoldActive, 'T'));

            Misc = Fate.AddSubMenu("Misc", "misc");
            Misc.Add("AutoYAG", new CheckBox("Auto Yellow on R teleport"));
            Misc.Add("qKillsteal", new CheckBox("Killsteal with Q"));
            Misc.Add("autoYellowIntoQ", new CheckBox("Auto Q after Yellow Card", false));
            Misc.Add("autoQonCC", new CheckBox("Auto Q on immobile targets", false));
            Misc.Add("cancelAApicking", new CheckBox("Cancel AA right before card pick", false));
            Misc.Add("drawRrange", new CheckBox("Draw R range", false));
            Misc.Add("humanizePicks", new CheckBox("Humanize Card Picks"));
            Misc.Add("humanizeInt", new Slider("Humanize", 50, 10, 250));
            Misc.AddSeparator(10);
            Misc.Add("useSkin", new CheckBox("Use Skinchanger", false)).OnValueChange += Tf.OnUseSkinChange;
            Misc.Add("skinId", new Slider("Skin ID", 0, 0, 9)).OnValueChange          += Tf.OnSkinSliderChange;
        }
        void AddEquipmentFate(IEnumerable<Equipment> rpEquipment, Fate rpFate, long rpTimestamp = 0)
        {
            if (!rpEquipment.Any())
                return;

            using (var rCommand = Connection.CreateCommand())
            {
                rCommand.CommandText = "INSERT OR IGNORE INTO equipment_fate(id, equipment, level, proficiency, time, fate) VALUES" + rpEquipment.Select(r => $"({r.ID}, {r.Info.ID}, {r.Level}, {r.Proficiency}, @timestamp, @fate)").Join(", ") + ";";
                rCommand.Parameters.AddWithValue("@timestamp", rpTimestamp == 0 ? DateTimeOffset.Now.ToUnixTime() : rpTimestamp);
                rCommand.Parameters.AddWithValue("@fate", (int)rpFate);

                rCommand.ExecuteNonQuery();
            }
        }
        void AddShipFate(Ship rpShip, Fate rpFate, long rpTimestamp = 0)
        {
            using (var rTransaction = Connection.BeginTransaction())
            {
                var rTimestamp = rpTimestamp == 0 ? DateTimeOffset.Now.ToUnixTime() : rpTimestamp;

                using (var rCommand = Connection.CreateCommand())
                {
                    rCommand.CommandText = "INSERT OR IGNORE INTO ship_fate(id, ship, level, time, fate) VALUES(@id, @ship, @level, @timestamp, @fate);";
                    rCommand.Parameters.AddWithValue("@id", rpShip.ID);
                    rCommand.Parameters.AddWithValue("@ship", rpShip.Info.ID);
                    rCommand.Parameters.AddWithValue("@level", rpShip.Level);
                    rCommand.Parameters.AddWithValue("@timestamp", rTimestamp);
                    rCommand.Parameters.AddWithValue("@fate", (int)rpFate);

                    rCommand.ExecuteNonQuery();
                }

                if (rpShip.EquipedEquipment.Count > 0)
                    AddEquipmentFate(rpShip.EquipedEquipment, rpFate, rTimestamp);

                rTransaction.Commit();
            }
        }
        void AddShipFate(IEnumerable<Ship> rpShips, Fate rpFate, long rpTimestamp = 0)
        {
            if (!rpShips.Any())
                return;

            using (var rTransaction = Connection.BeginTransaction())
            {
                var rTimestamp = rpTimestamp == 0 ? DateTimeOffset.Now.ToUnixTime() : rpTimestamp;

                using (var rCommand = Connection.CreateCommand())
                {
                    rCommand.CommandText = "INSERT OR IGNORE INTO ship_fate(id, ship, level, time, fate) VALUES" + rpShips.Select(r => $"({r.ID}, {r.Info.ID}, {r.Level}, @timestamp, @fate)").Join(", ") + ";";
                    rCommand.Parameters.AddWithValue("@timestamp", rTimestamp);
                    rCommand.Parameters.AddWithValue("@fate", (int)rpFate);

                    rCommand.ExecuteNonQuery();
                }

                AddEquipmentFate(rpShips.SelectMany(r => r.EquipedEquipment), rpFate, rTimestamp);

                rTransaction.Commit();
            }
        }