public void InitializeForm(GroupCalculatorResultDTO resultData) { InitializeComponent(resultData); LoadTexts(); ManageEvents(); this.Show(); this.BringToFront(); }
/// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent(GroupCalculatorResultDTO data) { var resources = new SingleAssemblyResourceManager(typeof(Language)); const int boxTableSeparator = 50; string textHeader, textIndividualProfit, textTotalValueObtained, textTotalWaste; switch (data.TotalBalance) { case Domain.Enums.TotalBalance.Profit: textHeader = String.Format(resources.GetString("TotalProfit"), data.TotalBalanceValue.ToString()); textIndividualProfit = String.Format(resources.GetString("IndividualProfit"), data.MemberBalanceValue.ToString()); break; case Domain.Enums.TotalBalance.Waste: textHeader = String.Format(resources.GetString("TotalWaste"), data.TotalBalanceValue.ToString()); textIndividualProfit = String.Format(resources.GetString("IndividualWaste"), data.MemberBalanceValue.ToString()); break; default: textHeader = resources.GetString("HuntPaid"); textIndividualProfit = string.Empty; break; } textTotalValueObtained = String.Format(resources.GetString("TotalValueObtained"), data.TotalValue); textTotalWaste = String.Format(resources.GetString("TotalValueSpent"), data.TotalWaste); var labelItem = new Label(); this.SuspendLayout(); labelItem.AutoSize = true; labelItem.Location = new Point(9, position + 14); position += 60; labelItem.Name = "Status"; labelItem.Size = new Size(30, 13); labelItem.TabIndex = 1; labelItem.Text = textHeader + "\r\n" + textIndividualProfit + "\r\n" + textTotalValueObtained + "\r\n" + textTotalWaste; this.Controls.Add(labelItem); foreach (var member in data.Members) { var groupBoxPlayer = new GroupBox(); groupBoxPlayer.SuspendLayout(); var tableWidth = 0; var table = new DataListView(); ((System.ComponentModel.ISupportInitialize)(table)).BeginInit(); var colImage = new OLVColumn(); var colName = new OLVColumn(); var colQuantity = new OLVColumn(); var colValue = new OLVColumn(); var imgRender = new ImageRenderer(); // // groupBoxPlayer // groupBoxPlayer.Anchor = ((AnchorStyles.Top | AnchorStyles.Left) | AnchorStyles.Right); groupBoxPlayer.Location = new Point(9, position + 20); groupBoxPlayer.Name = "groupBoxPlayer"; groupBoxPlayer.TabIndex = 20; groupBoxPlayer.TabStop = false; groupBoxPlayer.Text = String.Format(resources.GetString("ItensToPlayerWasted"), member.Waste.ToString()); groupBoxPlayer.Controls.Add(table); // // Table // table.AllColumns.Add(colImage); table.AllColumns.Add(colName); table.AllColumns.Add(colQuantity); table.AllColumns.Add(colValue); table.AllowColumnReorder = true; table.AllowDrop = true; table.Anchor = ((AnchorStyles.Top | AnchorStyles.Left) | AnchorStyles.Right); table.CellEditActivation = ObjectListView.CellEditActivateMode.SingleClick; table.CellEditUseWholeCell = false; table.Columns.AddRange(new ColumnHeader[] { colImage, colName, colQuantity, colValue }); table.Cursor = Cursors.Default; table.DataSource = null; table.EmptyListMsg = resources.GetString("EmptyPlayerItemList"); // todo: search for a better font lol table.EmptyListMsgFont = new Font("Comic Sans MS", 14.25F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(0))); table.FullRowSelect = true; table.GridLines = true; table.GroupWithItemCountFormat = resources.GetString("XItems"); table.GroupWithItemCountSingularFormat = resources.GetString("OneItem"); table.HideSelection = false; table.SelectedBackColor = Color.CornflowerBlue; table.SelectedForeColor = Color.MidnightBlue; table.Location = new Point(24, position + boxTableSeparator); table.Name = "olvData" + position; table.RowHeight = 32; table.SelectColumnsOnRightClickBehaviour = ObjectListView.ColumnSelectBehaviour.Submenu; table.ShowCommandMenuOnRightClick = true; table.ShowGroups = false; table.ShowImagesOnSubItems = true; table.ShowItemToolTips = true; table.TabIndex = 0; table.UseCellFormatEvents = true; table.UseCompatibleStateImageBehavior = false; table.UseFilterIndicator = true; table.UseFiltering = true; table.UseHotItem = true; table.UseTranslucentHotItem = true; table.View = View.Details; // // colImage // colImage.AspectName = "colImage"; colImage.ButtonPadding = new Size(10, 10); colImage.IsTileViewColumn = true; colImage.Text = String.Empty; colImage.UseInitialLetterForGroup = true; colImage.Width = 32; colImage.WordWrap = false; colImage.IsEditable = false; colImage.Searchable = false; colImage.Sortable = false; colImage.UseFiltering = false; colImage.Groupable = false; colImage.Renderer = imgRender; tableWidth += 32; // // colName // colName.AspectName = "colName"; colName.ButtonPadding = new Size(10, 10); colName.IsTileViewColumn = true; colName.Text = resources.GetString("Name"); colName.Width = 230; colName.IsEditable = false; tableWidth += 230; // // colQuantity // colQuantity.AspectName = "colQuantity"; colQuantity.ButtonPadding = new Size(10, 10); colQuantity.IsTileViewColumn = true; colQuantity.Text = resources.GetString("Quantity"); colQuantity.Width = 70; colQuantity.IsEditable = false; tableWidth += 70; // // colValue // colValue.AspectName = "colValue"; colValue.ButtonPadding = new Size(10, 10); colValue.IsTileViewColumn = true; colValue.Text = resources.GetString("Value"); colValue.Width = 80; colValue.IsEditable = false; tableWidth += 80; // // Fill member table // var memberDataTable = DataTableByMember(member); // unsplitted items if (data.ItemsUnsplited != null && data.ItemsUnsplited.Any() && member.MoneyRecived - member.Items.Select(y => y.Value * y.Quantity).Sum() > 0) { var value = member.MoneyRecived - member.Items.Select(y => y.Value * y.Quantity).Sum(); memberDataTable.Rows.Add( _pathHelper.DefaultImgPath, resources.GetString("AditionalValueByUnsplitedItems"), 1, value); } // if the waste is so large that a member needs to pay to another else if (data.Members.Any(x => x.MoneyRecived < 0)) { if (member.MoneyRecived < 0) { memberDataTable.Rows.Add( _pathHelper.DefaultImgPath, resources.GetString("ValueMemberNeedToPayToAnother"), 1, member.MoneyRecived); } else if (member.MoneyRecived - member.Items.Select(y => y.Value * y.Quantity).Sum() > 0) { var value = member.MoneyRecived - member.Items.Select(y => y.Value * y.Quantity).Sum(); memberDataTable.Rows.Add( _pathHelper.DefaultImgPath, resources.GetString("ValueMemberNeedToReciveAnother"), 1, value); } } table.DataSource = memberDataTable; // // Finally // var tableHeight = memberDataTable.Rows.Count > 0 ? ((memberDataTable.Rows.Count + 1) * 32) + 10 : 64 + 10; var groupBoxheight = tableHeight + 50; position += groupBoxheight + 10; groupBoxPlayer.Size = new Size(400 + boxTableSeparator, groupBoxheight); table.Size = new Size(tableWidth + 10, tableHeight); this.Controls.Add(groupBoxPlayer); this.Controls.Add(table); groupBoxPlayer.ResumeLayout(false); groupBoxPlayer.PerformLayout(); groupBoxPlayer.SendToBack(); ((System.ComponentModel.ISupportInitialize)(table)).EndInit(); } // // Unsplited Items // if (data.ItemsUnsplited != null && data.ItemsUnsplited.Any()) { var groupBoxPlayer = new GroupBox(); groupBoxPlayer.SuspendLayout(); var tableWidth = 0; var table = new DataListView(); ((System.ComponentModel.ISupportInitialize)(table)).BeginInit(); var colImage = new OLVColumn(); var colName = new OLVColumn(); var colQuantity = new OLVColumn(); var colValue = new OLVColumn(); var imgRender = new ImageRenderer(); // // groupBoxPlayer // groupBoxPlayer.Anchor = ((AnchorStyles.Top | AnchorStyles.Left) | AnchorStyles.Right); groupBoxPlayer.Location = new Point(9, position + 20); groupBoxPlayer.Name = "groupBoxPlayer"; groupBoxPlayer.TabIndex = 20; groupBoxPlayer.TabStop = false; groupBoxPlayer.Text = resources.GetString("ItemsUnsplited"); groupBoxPlayer.Controls.Add(table); // // Table // table.AllColumns.Add(colImage); table.AllColumns.Add(colName); table.AllColumns.Add(colQuantity); table.AllColumns.Add(colValue); table.AllowColumnReorder = true; table.AllowDrop = true; table.Anchor = ((AnchorStyles.Top | AnchorStyles.Left) | AnchorStyles.Right); table.CellEditActivation = ObjectListView.CellEditActivateMode.SingleClick; table.CellEditUseWholeCell = false; table.Columns.AddRange(new ColumnHeader[] { colImage, colName, colQuantity, colValue }); table.Cursor = Cursors.Default; table.DataSource = null; table.EmptyListMsg = resources.GetString("EmptyPlayerItemList"); // todo: search for a better font lol table.EmptyListMsgFont = new Font("Comic Sans MS", 14.25F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(0))); table.FullRowSelect = true; table.GridLines = true; table.GroupWithItemCountFormat = resources.GetString("XItems"); table.GroupWithItemCountSingularFormat = resources.GetString("OneItem"); table.HideSelection = false; table.SelectedBackColor = Color.CornflowerBlue; table.SelectedForeColor = Color.MidnightBlue; table.Location = new Point(24, position + boxTableSeparator); table.Name = "olvData" + position; table.RowHeight = 32; table.SelectColumnsOnRightClickBehaviour = ObjectListView.ColumnSelectBehaviour.Submenu; table.ShowCommandMenuOnRightClick = true; table.ShowGroups = false; table.ShowImagesOnSubItems = true; table.ShowItemToolTips = true; table.TabIndex = 0; table.UseCellFormatEvents = true; table.UseCompatibleStateImageBehavior = false; table.UseFilterIndicator = true; table.UseFiltering = true; table.UseHotItem = true; table.UseTranslucentHotItem = true; table.View = View.Details; // // colImage // colImage.AspectName = "colImage"; colImage.ButtonPadding = new Size(10, 10); colImage.IsTileViewColumn = true; colImage.Text = String.Empty; colImage.UseInitialLetterForGroup = true; colImage.Width = 32; colImage.WordWrap = false; colImage.IsEditable = false; colImage.Searchable = false; colImage.Sortable = false; colImage.UseFiltering = false; colImage.Groupable = false; colImage.Renderer = imgRender; tableWidth += 32; // // colName // colName.AspectName = "colName"; colName.ButtonPadding = new Size(10, 10); colName.IsTileViewColumn = true; colName.Text = resources.GetString("Name"); colName.Width = 230; colName.IsEditable = false; tableWidth += 230; // // colQuantity // colQuantity.AspectName = "colQuantity"; colQuantity.ButtonPadding = new Size(10, 10); colQuantity.IsTileViewColumn = true; colQuantity.Text = resources.GetString("Quantity"); colQuantity.Width = 70; colQuantity.IsEditable = false; tableWidth += 70; // // colValue // colValue.AspectName = "colValue"; colValue.ButtonPadding = new Size(10, 10); colValue.IsTileViewColumn = true; colValue.Text = resources.GetString("Value"); colValue.Width = 80; colValue.IsEditable = false; tableWidth += 80; // // Fill member table // var memberDataTable = DataTableByUnsplitted(data.ItemsUnsplited); table.DataSource = memberDataTable; // // Finally // var tableHeight = memberDataTable.Rows.Count > 0 ? ((memberDataTable.Rows.Count + 1) * 32) + 10 : 64 + 10; var groupBoxheight = tableHeight + 50; position += groupBoxheight + 10; groupBoxPlayer.Size = new Size(400 + boxTableSeparator, groupBoxheight); table.Size = new Size(tableWidth + 10, tableHeight); this.Controls.Add(groupBoxPlayer); this.Controls.Add(table); groupBoxPlayer.ResumeLayout(false); groupBoxPlayer.PerformLayout(); groupBoxPlayer.SendToBack(); ((System.ComponentModel.ISupportInitialize)(table)).EndInit(); } // // Close Btn // this.closeBtn = new Button(); this.closeBtn.Anchor = (AnchorStyles.Top | AnchorStyles.Right); this.closeBtn.Location = new Point(385, 30); this.closeBtn.Name = "closeBtn"; this.closeBtn.Size = new Size(75, 23); this.closeBtn.TabIndex = 1; this.closeBtn.Text = "Close"; this.closeBtn.UseVisualStyleBackColor = true; this.closeBtn.Click += new System.EventHandler(this.closeBtn_Click); // // Window // var YScreenSize = Math.Min(position + 10, 600); this.components = new System.ComponentModel.Container(); this.AutoScaleMode = AutoScaleMode.Font; this.Text = resources.GetString("LootSplitterResult"); this.Controls.Add(closeBtn); this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScroll = true; this.ClientSize = new System.Drawing.Size(470, YScreenSize); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Name = "LootSplitterResult"; this.ResumeLayout(false); this.PerformLayout(); }
/// <summary> /// Based a list of items result and a list of members (with each member spent money) /// Split all items to each member in a way to each member reicive the same profit or exp /// /// Example 1: memberA wasted 5k in supplies, memberB wasted 2k in supplies, total value loot was 10k /// In this case, the loot value needs to pay each member and, after split only the profit. /// memberA will reicive 5k + 1.5k profit, while memberB will reicive 2k + 1.5k profit /// /// Example 2: memberA wasted 5k in supplies, memberB wasted 2k in supplies, total value loot was 5k only /// In this case, the loot value is lower that supplies wasted, so the split need to balance the waste /// memberA will reicive 4k (total waste = 1k), while memberB will reicive 1k (total waste = 1k) /// /// Example 3: memberA wasted 5k in supplies, memberB wasted 2k in supplies, total value loot was 1k only /// In this case, the loot value is VERY F*****G low and impossible to balance the waste. /// So the member who wasted more in supplies will reicive the loot just to pay the most expansive waste /// memberA will reicive 1k (total waste = 4k), while memberB will reicive nothing (total waste = 2k) /// Others players can support paying the waste to memberst with higher waste in others methods /// </summary> /// <param name="itemsResult">Item list with value and quantity updated</param> /// <param name="members">List of members and updated wasted value</param> /// <returns>aAn object with a list of items that each member will reicive</returns> public GroupCalculatorResultDTO SplitItemsToMembers(List <ItemResultDTO> itemsResult, List <MemberDTO> members) { var model = new GroupCalculatorResultDTO { Members = new List <MemberDTO>(members), ItemsUnsplited = new List <ItemResultDTO>() }; // Money data var totalGold = itemsResult.Select(x => x.Value != null ? x.Value.Value * x.Quantity : 0).Sum(); var totalWaste = model.Members.Select(x => x.Waste).Sum(); var totalProfit = totalGold - totalWaste; itemsResult = itemsResult.OrderByDescending(x => x.Value).ToList(); // How much each member needs to reicive model.Members.ForEach(x => { x.Items = new List <ItemResultDTO>(); x.MoneyRecived = totalProfit > 0 ? totalProfit / model.Members.Count + x.Waste : x.Waste - (totalWaste - totalGold) / model.Members.Count; }); // Split items by values foreach (var member in model.Members) { // Each member recive item till gold limit (totalMemberGold) is reached foreach (var itemResult in itemsResult) { var value = itemResult.Value.HasValue ? itemResult.Value.Value : 0; var goldWithNewItem = value + member.Items.Select(x => x.Value != null ? x.Value.Value * x.Quantity : 0).Sum(); if (goldWithNewItem > member.MoneyRecived) { continue; } var quantityList = new List <int> { 1, 2, 5, 10, 20, itemResult.Quantity }; var quantityCount = quantityList.Count - 1; // -1 because "quantityCount is an list index do { // This split list using quantityList was designed this way to improve split performance if (Convert.ToInt32(itemResult.Quantity / quantityList[quantityCount]) > 0 && Convert.ToInt32(itemResult.Quantity / quantityList[quantityCount]) * itemResult.Value + member.Items.Select(x => x.Value != null ? x.Value.Value * x.Quantity : 0).Sum() <= member.MoneyRecived) { if (member.Items.All(x => x.Item.Name != itemResult.Item.Name)) { member.Items.Add(new ItemResultDTO(itemResult.Item) { Quantity = Convert.ToInt32(itemResult.Quantity / quantityList[quantityCount]), Value = itemResult.Value }); } else { member.Items.First(x => x.Item.Name == itemResult.Item.Name).Quantity += Convert.ToInt32(itemResult.Quantity / quantityList[quantityCount]); } itemResult.Quantity -= Convert.ToInt32(itemResult.Quantity / quantityList[quantityCount]); } else { quantityCount--; } } while (itemResult.Quantity > 0 && quantityCount >= 0 && itemResult.Value + member.Items.Select(x => x.Value * x.Quantity).Sum() <= member.MoneyRecived); } // Remove used items where the quantity was totally used itemsResult.RemoveAll(x => x.Quantity == 0); } // Items impossible to split. if (itemsResult.Count > 0) { model.ItemsUnsplited = itemsResult; } return(model); }