private void trkColumnsRadius_Scroll(object sender, EventArgs e)
        {
            if (formationEditingMode == FormationEditingMode.None)
            {
                return;
            }

            EnsureFormationMode();

            if (formationEditingMode == FormationEditingMode.Radius)
            {
                lastRadius = trkColumnsRadius.Value;
            }
            else
            {
                lastColumnCount = trkColumnsRadius.Value;
                MiniGrouperScript?.ClearLastMemberLocationCache();
            }

            if (MiniGrouperScript != null)
            {
                MiniGrouperScript.Data.ColumnRadius = trkColumnsRadius.Value;
                MiniGrouperScript.DataChanged();
            }

            //ResetRotationToZero();
            UpdateColumnRadiusLabel();
            UpdateFormation();
        }
 private void btnDestroyGroup_Click(object sender, EventArgs e)
 {
     if (MessageBox.Show("Destroy ALL THE MINIS in the group? Are You Sure?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Stop) == DialogResult.Yes)
     {
         MiniGrouperScript?.DestroyAll();
     }
 }
        private void EnsureFormationMode()
        {
            if (MiniGrouperScript == null)
            {
                return;
            }

            changingInternally = true;
            try
            {
                rbFormation.Checked = true;
            }
            finally
            {
                changingInternally = false;
            }

            if (MiniGrouperScript.Data.Movement == GroupMovementMode.Formation)
            {
                return;
            }

            MiniGrouperScript.Data.Movement = GroupMovementMode.Formation;
            MiniGrouperScript.DataChanged();
        }
        void RefreshMemberList()
        {
            Talespire.Log.Indent();
            lstMembers.Items.Clear();

            if (Guard.IsNull(MiniGrouperScript, "Script"))
            {
                return;
            }

            List <string> notFoundCreatures = new List <string>();

            foreach (string member in MiniGrouperScript.Data.Members)
            {
                CreatureBoardAsset creatureBoardAsset = Talespire.Minis.GetCreatureBoardAsset(member);
                if (creatureBoardAsset != null)
                {
                    lstMembers.Items.Add(new GroupMember(creatureBoardAsset));
                }
                else
                {
                    notFoundCreatures.Add(member);
                }
            }

            MiniGrouperScript.RemoveMembers(notFoundCreatures);
            Talespire.Log.Unindent();
        }
        void UpdateLookSettings()
        {
            if (changingInternally || MiniGrouperScript == null)
            {
                return;
            }

            if (rbLookTowardLeader.Checked)
            {
                MiniGrouperScript.Data.Look = LookTowardMode.Leader;
            }
            else if (rbLookTowardMovement.Checked)
            {
                MiniGrouperScript.Data.Look = LookTowardMode.Movement;
            }
            else if (rbLookTowardNearestOutsider.Checked)
            {
                MiniGrouperScript.Data.Look = LookTowardMode.NearestOutsider;
            }
            else if (rbLookTowardNearestMember.Checked)
            {
                MiniGrouperScript.Data.Look = LookTowardMode.NearestMember;
            }
            else if (rbLookTowardSpecificCreature.Checked)
            {
                MiniGrouperScript.Data.Look = LookTowardMode.Creature;
            }

            MiniGrouperScript.DataChanged();
            MiniGrouperScript.UpdateLook();
        }
        public void InitializeInstance(MonoBehaviour script)
        {
            MiniGrouperScript = script as MiniGrouper;
            if (MiniGrouperScript != null)
            {
                MiniGrouperScript.StateChanged -= MiniGrouperScript_StateChanged;
                MiniGrouperScript.StateChanged += MiniGrouperScript_StateChanged;
            }
            else
            {
                Talespire.Log.Error($"InitializeInstance - MiniGrouperScript is null!");
            }

            RefreshMemberList();
            RefreshTrackHue();
            changingInternally = true;
            try
            {
                UpdateGroupControls();
                UpdateFormationControls();
                UpdateLookControls();
                UpdateFormationStyleControls();
                if (MiniGrouperScript != null)
                {
                    trkSpacing.Value     = MiniGrouperScript.Data.Spacing;
                    lblSpacingValue.Text = $"{MiniGrouperScript.Data.Spacing}ft";

                    trkArcAngle.Value     = MiniGrouperScript.Data.ArcAngle;
                    lblArcAngleValue.Text = $"{MiniGrouperScript.Data.ArcAngle}°";

                    trkColumnsRadius.Maximum = 1000;
                    trkColumnsRadius.Value   = MiniGrouperScript.Data.ColumnRadius;

                    lastColumnCount = MiniGrouperScript.Data.ColumnRadius;
                    lastRadius      = MiniGrouperScript.Data.ColumnRadius;

                    switch (MiniGrouperScript.Data.FormationStyle)
                    {
                    case FormationStyle.FreeForm:
                        EditingNeitherColumnsNorCircular();
                        break;

                    case FormationStyle.Gaggle:
                    case FormationStyle.Rectangle:
                        EditingColumns();
                        break;

                    case FormationStyle.Circle:
                        EditingCircular();
                        break;
                    }
                }
            }
            finally
            {
                changingInternally = false;
            }
            MiniGrouperScript?.RefreshIndicators();
        }
 private void trkHue_Scroll(object sender, EventArgs e)
 {
     if (MiniGrouperScript == null)
     {
         return;
     }
     MiniGrouperScript.UpdateRingHue(trkHue.Value);
 }
 private void ToggleGroupMembership(CreatureBoardAsset mini)
 {
     if (mini.CreatureId.ToString() != MiniGrouperScript.OwnerID)
     {
         MiniGrouperScript.ToggleMember(mini);
         RefreshMemberList();
     }
 }
        private void btnLookAt_Click(object sender, EventArgs e)
        {
            if (editing)
            {
                StopEditMode();
            }

            MiniGrouperScript?.SetLookTarget();
        }
 private void trkFormationRotation_Scroll(object sender, EventArgs e)
 {
     UpdateRotationValue();
     if (changingInternally)
     {
         return;
     }
     MiniGrouperScript?.RotateFormation(trkFormationRotation.Value);
 }
        private void rbFormation_CheckedChanged(object sender, EventArgs e)
        {
            if (changingInternally)
            {
                return;
            }

            if (rbFormation.Checked)
            {
                MiniGrouperScript?.ClearLastMemberLocationCache();
                UpdateMovementMode();
            }
        }
        private void rbFollowTheLeader_CheckedChanged(object sender, EventArgs e)
        {
            if (changingInternally)
            {
                return;
            }

            if (rbFollowTheLeader.Checked)
            {
                MiniGrouperScript?.ClearLeaderMovementCache();
                UpdateMovementMode();
            }
        }
        void InitializeNewlySpawnedCreatures()
        {
            Talespire.Log.Indent();
            UnityMainThreadDispatcher.ExecuteOnMainThread(() =>
            {
                RefreshMemberList();
                MiniGrouperScript.RefreshIndicators();
                UpdateFormation();
            });

            MiniGrouperScript.DataChanged();
            Talespire.Log.Unindent();
        }
        private void UpdateNewlySpawnedCreaturesTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            updateNewlySpawnedCreaturesTimer.Stop();

            if (MiniGrouperScript == null)
            {
                return;
            }

            List <string>             foundCreatureIds         = new List <string>();
            List <CreatureBoardAsset> foundCreatureBoardAssets = new List <CreatureBoardAsset>();

            bool readyToInitializePlayers = false;

            lock (newlySpawnedCreatureLock)
            {
                foreach (string newlySpawnedCreatureId in newlySpawnedCreatureIds)
                {
                    CreatureBoardAsset creatureBoardAsset = Talespire.Minis.GetCreatureBoardAsset(newlySpawnedCreatureId);
                    if (creatureBoardAsset != null)
                    {
                        foundCreatureIds.Add(newlySpawnedCreatureId);
                        foundCreatureBoardAssets.Add(creatureBoardAsset);
                    }
                }

                foreach (string foundCreatureId in foundCreatureIds)
                {
                    newlySpawnedCreatureIds.Remove(foundCreatureId);
                }

                readyToInitializePlayers = newlySpawnedCreatureIds.Count == 0;
            }

            foreach (CreatureBoardAsset creatureBoardAsset in foundCreatureBoardAssets)
            {
                MiniGrouperScript.AddMemberToGroup(creatureBoardAsset);
            }

            if (readyToInitializePlayers)
            {
                InitializeNewlySpawnedCreatures();
            }
            else
            {
                updateNewlySpawnedCreaturesTimer.Start();                  // Try again in a moment.
            }
        }
        private void SetFormationStyle(FormationStyle formationStyle)
        {
            if (formationStyle != FormationStyle.FreeForm && !rbFormation.Checked)
            {
                bool saveChangingInternally = changingInternally;
                changingInternally  = true;
                rbFormation.Checked = true;
                changingInternally  = saveChangingInternally;
            }

            if (MiniGrouperScript != null)
            {
                MiniGrouperScript.Data.FormationStyle = formationStyle;
                MiniGrouperScript.DataChanged();
            }
        }
 private void StopEditMode()
 {
     MiniGrouperScript?.StopEditing();
     btnMatchAltitude.Visible = true;
     PersistentEffectsManager.SuppressPersistentEffectUI = false;
     editing             = false;
     lbInstructions.Text = "<< Click to Edit the group.";
     btnEdit.Text        = "Edit";
     if (MiniGrouperScript != null)
     {
         MiniGrouperScript.UpdateMemberList();
     }
     btnEdit.BackColor = System.Drawing.Color.FromArgb(60, 60, 60);
     btnEdit.ForeColor = System.Drawing.Color.White;
     EnableControlsBasedOnMemberCount();
 }
        void UpdateMovementMode()
        {
            if (changingInternally || MiniGrouperScript == null)
            {
                return;
            }

            if (rbFormation.Checked)
            {
                MiniGrouperScript.Data.Movement = GroupMovementMode.Formation;
            }
            else
            {
                MiniGrouperScript.Data.Movement = GroupMovementMode.FollowTheLeader;
            }
            MiniGrouperScript.DataChanged();
        }
        private void StartEditMode()
        {
            MiniGrouperScript?.ClearLeaderMovementCache();
            MiniGrouperScript?.StartEditing();
            if (MiniGrouperScript != null && !alreadyShowedDiscoverabilityHint)
            {
                alreadyShowedDiscoverabilityHint = true;
                Talespire.Minis.Speak(MiniGrouperScript.OwnerID, "Click minis to include/exclude. Move me (to position the leader).");
            }

            btnMatchAltitude.Visible = false;
            editing = true;
            PersistentEffectsManager.SuppressPersistentEffectUI = true;              // So we no longer show or hide the PE UI when selecting minis.
            lbInstructions.Text = "Click a mini to add or remove it from the group.";
            btnEdit.Text        = "Done";
            btnEdit.BackColor   = System.Drawing.Color.DarkRed;
            btnEdit.ForeColor   = System.Drawing.Color.White;
        }
        private void btnAdd_Click(object sender, EventArgs e)
        {
            GroupMember  groupMember   = lstMembers.SelectedItem as GroupMember;
            List <NGuid> boardAssetIds = new List <NGuid>();

            if (groupMember != null)
            {
                boardAssetIds.Add(groupMember.CreatureBoardAsset.BoardAssetId);
            }
            else
            {
                foreach (GroupMember member in lstMembers.Items)
                {
                    boardAssetIds.Add(member.CreatureBoardAsset.BoardAssetId);
                }
            }

            if (!int.TryParse(tbxNumCreatures.Text, out int numCreaturesToSpawn))
            {
                numCreaturesToSpawn  = 1;
                tbxNumCreatures.Text = "1";
            }
            else
            {
                // TODO: Confirm with the user if this number is high.
                if (numCreaturesToSpawn > MaxCreaturesToSpawnAtOnce)
                {
                    Talespire.Log.Warning($"{numCreaturesToSpawn} is too many creatures to spawn at once. Dropping to {MaxCreaturesToSpawnAtOnce}.");
                    numCreaturesToSpawn = MaxCreaturesToSpawnAtOnce;
                }
                numCreaturesToSpawn = Math.Min(numCreaturesToSpawn, MaxCreaturesToSpawnAtOnce);
            }

            List <string> spawnedCreatureIds = MiniGrouperScript?.SpawnMoreMembers(numCreaturesToSpawn, boardAssetIds);

            lock (newlySpawnedCreatureLock)
                newlySpawnedCreatureIds.AddRange(spawnedCreatureIds);

            UpdateNewCreaturesSoon();
        }
        private void trkSpacing_Scroll(object sender, EventArgs e)
        {
            lblSpacingValue.Text = $"{trkSpacing.Value}ft";

            if (changingInternally || initializing)
            {
                return;
            }

            if (MiniGrouperScript != null)
            {
                MiniGrouperScript.Data.Spacing = trkSpacing.Value;
            }

            if (rbFormation.Checked)
            {
                UpdateFormation();
            }
            else
            {
                MiniGrouperScript?.RefreshFollowTheLeaderLine();
            }
        }
 private void btnRenameAll_Click(object sender, EventArgs e)
 {
     MiniGrouperScript?.RenameAll(txtNewName.Text);
     RefreshMemberListSoon();
 }
 private void UpdateGroupNameTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
 {
     updateGroupNameTimer.Stop();
     MiniGrouperScript?.SetGroupName(tbxGroupName.Text);
 }
 private void btnSetHp_Click(object sender, EventArgs e)
 {
     MiniGrouperScript?.SetHp(GetInt(tbxSetHp.Text), GetInt(tbxMaxHp.Text));
 }
 private void NewFormationSelected()
 {
     ResetRotationToZero();
     MiniGrouperScript?.ClearLastMemberLocationCache();
 }
 private void trkArcAngle_MouseUp(object sender, MouseEventArgs e)
 {
     MiniGrouperScript?.DataChanged();
 }
 private void trkHue_MouseUp(object sender, MouseEventArgs e)
 {
     MiniGrouperScript.CommitRingHue(trkHue.Value);
 }
 void ArrangeInCircle()
 {
     MiniGrouperScript?.ArrangeInCircle(trkColumnsRadius.Value, trkArcAngle.Value, trkSpacing.Value, trkFormationRotation.Value);
 }
 private void btnHeal_Click(object sender, EventArgs e)
 {
     MiniGrouperScript?.Heal(GetInt(tbxHealth.Text));
 }
 void ArrangeInRectangle(float percentVariance)
 {
     MiniGrouperScript?.ArrangeInRectangle(trkColumnsRadius.Value, trkSpacing.Value, percentVariance, trkFormationRotation.Value);
 }
 private void btnDamage_Click(object sender, EventArgs e)
 {
     MiniGrouperScript?.Damage(GetInt(tbxDamage.Text));
 }