/// <summary> /// Clears all lists and reloads files from the disk /// </summary> public void Reload() { Crafts.Clear(); Saves.Clear(); GetAllCraftFromSaves(); GetAllCraftFromHangar(); }
public ActionResult UpdateCraft(int?id) { if (Session["RoleID"] != null) { int craftToUpdate = ConvertToInt(id); Crafts craft = _craftMapper.MapCraft(_craftBusinessLogic.GetCraftByCraftId(craftToUpdate)); if ((int)Session["UserId"] == craft.User_ID && (int)Session["RoleID"] != 1 || (int)Session["RoleID"] == 3) { ViewModel craftViewModel = new ViewModel { SingleCraft = _craftMapper.MapCraft(_craftBusinessLogic.GetCraftByCraftId(craftToUpdate)) }; craftViewModel.SingleCraft.User_ID = craft.User_ID; return(View(craftViewModel)); } else { return(RedirectToAction("PageError", "Error", new { area = "" })); } } else { return(RedirectToAction("Login", "Users", new { area = "" })); } } //update craft for power user and admin
private void ButtonLoadSingleMod_MouseClick(object sender, MouseEventArgs e) { //create and setup an open file dialog OpenFileDialog ofd = new OpenFileDialog(); ofd.Multiselect = false; DialogResult rep = ofd.ShowDialog(); if (rep == DialogResult.OK) { string FilePath = ofd.FileName; try { //load the mod object oMod NewMod = new oMod(FilePath); //mods load faster when the tab container does have to refresh while the process. this.TabContainer.Visible = false; Crafts.AddMod(NewMod); this.TabContainer.Visible = true; this.Editer.RefreshImage(); } catch { MessageBox.Show("An error occurred"); } } }
private void CreateNewButtonBoth(oItem i) { Bitmap img = Crafts.GetAssociatedIcon(i); this.CreateNewButtonBelt(img, i); this.CreateNewButtonMachine(img, i); }
public Crafts MapCraft(BusinessLogicCrafts bCraft) { Crafts craft = new Crafts(); craft.Craft_ID = bCraft.Craft_ID; craft.CraftName = bCraft.CraftName; craft.Description = bCraft.Description; craft.User_ID = bCraft.User_ID; return(craft); }
public BusinessLogicCrafts MapCraft(Crafts craft) { BusinessLogicCrafts bCraft = new BusinessLogicCrafts(); bCraft.Craft_ID = craft.Craft_ID; bCraft.CraftName = craft.CraftName; bCraft.Description = craft.Description; bCraft.User_ID = craft.User_ID; return(bCraft); }
public bool NeedCoal = true; //if this is a furnace, indicate if this need coal //// si this est une furnace, indique si this a besoin de coal //i guess that some mods require other things than coal to make things so, in the future, we might have to replace NeedCoal by NeededCombustibles which will be an array of sItem and a static list of arrays in Crafts who describe every combustibles options to toggle. //we can also make the change of NeedCoal to NeededCombustibles only if any mods were loaded. if no mod loaded, we stay with NeedCoal. //or a lazy and less user friendly option is to remove NeedCoal and possibly IsFurnace and make one recipe for every combination of for what would be every combinaison of NeededCombustibles. //another preferable solution we be leave it like that. current vanilla items won't be affected. modded items will have one recipe for every combinaisons of what represented NeededCombustibles in the other solution. public Bitmap GetImage() { if (this.MapType == MOType.Belt) { return(Crafts.GetAssociatedIcon(this.BeltOutput)); } if (this.MapType == MOType.Machine) { return(Crafts.GetAssociatedIcon(this.TheRecipe)); } return(FactorioOrganizer.Properties.Resources.fish); }
public ActionResult CreateCraft(ViewModel craftToAdd) { if (Session["RoleID"] != null) { if ((int)Session["RoleID"] != 1) { if (ModelState.IsValid) { Crafts craft = new Crafts(); craft = _craftMapper.MapCraft(_craftBusinessLogic.GetCraftByCraftName(craftToAdd.SingleCraft.CraftName)); if (craft.CraftName == null) { _craftBusinessLogic.AddCraft(_craftMapper.MapCraft(craftToAdd.SingleCraft)); _houseController.AddPoints(50, (int)Session["House_ID"]); if ((int)Session["House_ID"] == 1) { TempData["CraftSuccess"] = "50 points to GRYFFINDOR!"; } else if ((int)Session["House_ID"] == 2) { TempData["CraftSuccess"] = "50 points to SLYTHERIN!"; } else if ((int)Session["House_ID"] == 3) { TempData["CraftSuccess"] = "50 points to RAVENCLAW!"; } else if ((int)Session["House_ID"] == 4) { TempData["CraftSuccess"] = "50 points to HUFFLEPUFF!"; } return(RedirectToAction("ViewAllCrafts", "Crafts", new { area = "" })); } else { TempData["CraftError"] = "Craft name already exists"; return(View()); } } else { return(View()); } } else { return(RedirectToAction("PageError", "Errors", new { area = "" })); } } else { return(RedirectToAction("Login", "Users", new { area = "" })); } } //create craft for power user and admin
public BusinessLogicCrafts MapCraft(Crafts craft) { if (craft == null) { return(null); } BusinessLogicCrafts bCraft = new BusinessLogicCrafts { Craft_ID = craft.Craft_ID, CraftName = craft.CraftName, Description = craft.Description, User_ID = craft.User_ID }; return(bCraft); }
public Crafts MapCraft(BusinessLogicCrafts bCraft) { if (bCraft == null) { return(null); } Crafts craft = new Crafts { Craft_ID = bCraft.Craft_ID, CraftName = bCraft.CraftName, Description = bCraft.Description, User_ID = bCraft.User_ID, Username = bCraft.Username }; return(craft); }
internal void LoadCraftingOperations() { if (_savedData?.AutoCraftData != null && !_craftSaveDataInit) { foreach (OperationSaveData operationSaveData in _savedData.AutoCraftData) { Crafts.Add(new FCSOperation { TechType = operationSaveData.TechType, IsCraftable = operationSaveData.IsCraftable, Manager = FindManager(operationSaveData.ManagerID) }); } _craftSaveDataInit = true; RefreshOperators(); } }
private void ButtonUnloadMods_Click(object sender, EventArgs e) { bool canceled = this.AutoAskUserToSaveCurrent(); if (!canceled) { Crafts.UnloadEveryMods(); Program.ActualNextForm = Program.NextFormToShow.Form1; this.EditsWereMade = false; this.Close(); this.DestroyCraftsEvents(); } else { //we change the focus to a button that won't react with the space bar this.ButtonSave.Focus(); } }
public ActionResult UpdateCraft(ViewModel craftToUpdate) { if (Session["RoleID"] != null) { if (ModelState.IsValid) { if ((int)Session["UserId"] == craftToUpdate.SingleCraft.User_ID || (int)Session["RoleID"] == 3) { Crafts craft = new Crafts(); craft = _craftMapper.MapCraft(_craftBusinessLogic.GetCraftByCraftName(craftToUpdate.SingleCraft.CraftName)); if (craft.CraftName == null || craft.CraftName == craftToUpdate.SingleCraft.CraftName) { if (craft.User_ID == (int)Session["UserId"] || (int)Session["RoleId"] == 3) { _craftBusinessLogic.UpdateCraft(craftToUpdate.SingleCraft.Craft_ID, _craftMapper.MapCraft(craftToUpdate.SingleCraft)); TempData["CraftSuccess"] = "Craft successfully updated."; return(RedirectToAction("ViewAllCrafts", "Crafts", new { area = "" })); } else { return(RedirectToAction("PageError", "Error", new { area = "" })); } } else { TempData["CraftError"] = "Craft name already exists"; return(View()); } } else { return(RedirectToAction("PageError", "Error", new { area = "" })); } } else { return(View()); } } else { return(RedirectToAction("Login", "Users", new { area = "" })); } } //update craft for power user and admin
//탭의 메뉴를 클릭할 때 public void TabClick(Crafts _crafts) { //탭을 누를 때 마다, 그 크래프트의 정보를 가져와서 //슬롯에 보여지는 크래프트의 이미지, 이름, 설명, 프리팹 정보를 해당 크래프트에 맞게 바꾼다. craftName.text = _crafts.craftName; craftDescription.text = _crafts.craftDescription; craftImage.sprite = _crafts.craftImage; if (craftName.text == "FireCamp") { craftsArrayNum = 0; //FireCamp; return; } else if (craftName.text == "Stair") { craftsArrayNum = 1; //Stair; return; } }
public void OnCraftDelete() { var result = MessageBox.Show("Are you sure you want to delete this craft?\n\nALL JOBS TIED TO THIS CRAFT WILL BE DELETED AND THEIR CONFIGURATION LOST!", "Warning", MessageBoxButton.YesNo, MessageBoxImage.Warning); if (result == MessageBoxResult.Yes) { SelectedCraft.Jobs.Clear(); Crafts.Remove(SelectedCraft); } Globals.ChangesMade = true; // Jobs will have been deleted, so make sure joblist is updated LoadJobs(); // Reload documents without deleted craft ImportDocuments(); }
public void SetRecipe(oItem Recipe) { if (this.MapType == MOType.Belt) { this.BeltOutput = Recipe; } if (this.MapType == MOType.Machine) { this.TheRecipe = Recipe; oCraft c = Crafts.GetCraftFromRecipe(Recipe); //gets the craft this.TheCraft = c; //if (c != null) //{ // this.Outputs = c.Outputs; // this.Inputs = c.Inputs; // this.IsFurnace = c.IsMadeInFurnace; //} } }
} //update craft for power user and admin #endregion #region Delete public ActionResult DeleteCraft(int?id) { if (Session["RoleID"] != null) { if ((int)Session["RoleID"] != 1) { int craftToDelete = ConvertToInt(id); Crafts craft = _craftMapper.MapCraft(_craftBusinessLogic.GetCraftByCraftId(craftToDelete)); if ((int)Session["UserId"] == craft.User_ID && (int)Session["RoleID"] != 3) { _craftBusinessLogic.DeleteCraft(craftToDelete); _houseController.AddPoints(-50, (int)Session["House_ID"]); TempData["DeleteSuccess"] = "Craft successfully deleted."; return(RedirectToAction("ViewAllCrafts", "Crafts", new { area = "" })); } else { ViewModel user = new ViewModel { SingleUser = _userMapper.MapUser(_userBusinessLogic.GetUserByUserId(craft.User_ID)) }; if (craft.User_ID == user.SingleUser.User_ID) { _houseController.AddPoints(-50, user.SingleUser.House_ID); } _craftBusinessLogic.DeleteCraft(craftToDelete); TempData["DeleteSuccess"] = "Craft successfully deleted."; return(RedirectToAction("ViewAllCrafts", "Crafts", new { area = "" })); } } else { return(RedirectToAction("PageError", "Error", new { area = "" })); } } else { return(RedirectToAction("Login", "Users", new { area = "" })); } } //delete craft for power user and admin
public static void AddCraft(FCSOperation operation) { Crafts.Add(operation); operation.Manager.RefreshOperators(); }
/// <summary> /// Removes a craft and its related info /// </summary> /// <param name="craft"></param> private void RemoveCraft(CraftInfo craft) { Crafts.Remove(craft); //olvCraftList.SmallImageList.Images.Remove(craft.Thumb); //olvCraftList.LargeImageList.Images.Remove(craft.Thumb); }
/// <summary> /// Adds thumbnail images for each craft to the imageLists and adds the craft to the crafts list. /// </summary> /// <param name="craft"></param> private void AddCraft(CraftInfo craft) { Crafts.Add(craft); SmallImageList.Images.Add(craft.ThumbName, craft.Thumb); LargeImageList.Images.Add(craft.ThumbName, craft.Thumb); }
public static void DeleteAutoCraft(FCSOperation craft) { Crafts.Remove(craft); }
/// <summary> /// Returns a list of CraftInfo from the given save /// </summary> /// <param name="saveName"></param> /// <returns></returns> public List <CraftInfo> GetCraftInfosFromSave(string saveName) { return(Crafts.Where(craft => craft.SaveName.Equals(saveName)).ToList()); }
void Awake() { instance = this; Crafts.Add(items.items[6].craftCode, items.items[6]); Crafts.Add(items.items[7].craftCode, items.items[7]); }
public oMap(string filepath) { this.EveryItemWhereLoadedCorrectly = true; //will becomes false if there is at least one item that wasn't found in the item list of the static class Crafts. List <string> alll = System.IO.File.ReadAllLines(filepath).ToList(); SaveReader sr = new SaveReader(alll); //first line is save file format version string strVersion = sr.ReadLine(); while (true) { //first step is read the next object to add to the map. //second step is read the properties of that object. we knows in which order properties are written string newitem = sr.ReadLine(); if (newitem == "exit") { break; } if (newitem == "belt") { string strBeltOutput = sr.ReadLine(); MapObject mo = new MapObject(MOType.Belt, Crafts.GetItemFromName(strBeltOutput)); mo.vpos.X = Convert.ToSingle(sr.ReadLine().Replace(".", ",")); mo.vpos.Y = Convert.ToSingle(sr.ReadLine().Replace(".", ",")); this.listMO.Add(mo); //check if the item was found when Crafts.GetItemFromName if (mo.BeltOutput != null) { if (mo.BeltOutput.Name == "none") { this.EveryItemWhereLoadedCorrectly = false; } } else { this.EveryItemWhereLoadedCorrectly = false; } } if (newitem == "machine") { string strRecipe = sr.ReadLine(); MapObject mo = new MapObject(MOType.Machine, Crafts.GetItemFromName(strRecipe)); mo.NeedCoal = sr.ReadLine() == "true"; mo.vpos.X = Convert.ToSingle(sr.ReadLine().Replace(".", ",")); mo.vpos.Y = Convert.ToSingle(sr.ReadLine().Replace(".", ",")); this.listMO.Add(mo); //check if the item was found when Crafts.GetItemFromName if (mo.TheRecipe != null) { if (mo.TheRecipe.Name == "none") { this.EveryItemWhereLoadedCorrectly = false; } } else { this.EveryItemWhereLoadedCorrectly = false; } } if (newitem == "mod") { string modname = sr.ReadLine(); //get the mod name this.listModNames.Add(modname); } } }
//load, in the correct order, every mods (identified by the file extension) found inside a folder. private void LoadModsInFolder(string FolderPath) { //generate a list of every extensions associated to a fomod file. //System.IO.Path.GetExtension return the . and the text file path after that dot. for this reason, everything put into this list begins with a . List <string> extensions = new List <string>(); extensions.Add(".fomod"); for (int i = 1; i <= 9; i++) { extensions.Add(".fomod" + i.ToString()); extensions.Add(".fomod" + i.ToString().PadLeft(2, "0".ToCharArray()[0])); } for (int i = 10; i <= 99; i++) { extensions.Add(".fomod" + i.ToString().PadLeft(2, "0".ToCharArray()[0])); } //get every file in this path List <string> EveryFilePath = System.IO.Directory.GetFiles(FolderPath).ToList(); ////filter for fomod files. //this list contain, in the appropriate loading order, every mod file's path to load. List <string> EveryModPath = new List <string>(); //because extension array is our first loop, the mod files will be added according to mod load order foreach (string ext in extensions) { //we search every file with this extension int index = EveryFilePath.Count - 1; while (index >= 0) { //the actual file path string FilePath = EveryFilePath[index]; try { //get this file's extension string FileExt = System.IO.Path.GetExtension(FilePath); //check if this file's extension is the extension we are actually looking for. if (FileExt == ext) { //because this file's extension is the extension we are actually looking for, we add it to the EveryModPath list EveryModPath.Add(FilePath); //we remove this file from the list, because we know we won't have to analyse it anymore. EveryFilePath.RemoveAt(index); } } catch { } //next iteration index--; } //if there's no file left in the EveryFilePath list, we can stop because there's nothing left. if (EveryFilePath.Count <= 0) { break; } } ////create the mod objects for every file List <oMod> listMods = new List <oMod>(); //we create a mod for every file foreach (string ModFilePath in EveryModPath) { try { //generate the mod for this file oMod newmod = new oMod(ModFilePath); //add the mod to the list of mod to load listMods.Add(newmod); } catch { MessageBox.Show("An error occurred when loading " + ModFilePath); } } ////load the mods //mods load faster when the tab container does have to refresh while the process. this.TabContainer.Visible = false; Crafts.AddMod(listMods); this.TabContainer.Visible = true; this.Editer.RefreshImage(); }
static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Crafts.CreateDefaultVanillaItems(); //defaults items are always the firsts to be loaded. after, it'll load the vanilla items from a .fomod file, who they'll all override the default items. if the user doesn't have that file, these default items are a kind of "emergency items" or something like that. //check the command line args string[] args = System.Environment.GetCommandLineArgs(); //we have arguments if this array is greater than 1 if (args.Length > 1) { try { /* * the help forms are on another process than the editer so the user can consult them even if they are in the middle of a dialog phase. * * * * command line args: * * -help1 show the help form of form1 * -helpmods show the help form of the mod editer * -h "help" of the command line. at the time of this comment, it just show possible arguments. * */ if (args.Length >= 2) { //MessageBox.Show(args[1]); string arg1 = args[1].Replace("-", string.Empty).Replace("/", string.Empty); //we check here the second arg if (arg1 == "h") { Program.ActualNextForm = NextFormToShow.none; MessageBox.Show("-h for this message\n-help1 for the help of the map editer\n-helpmods for the help of the mod editer"); } if (arg1 == "help1") { Program.ActualNextForm = NextFormToShow.FormHelp1; } if (arg1 == "helpmods") { Program.ActualNextForm = NextFormToShow.FormHelpMod; } } } catch { //if there's an error while reading arguments, we set it to form1 Program.ActualNextForm = NextFormToShow.Form1; } } while (Program.ActualNextForm != NextFormToShow.none) { Form f = null; if (Program.ActualNextForm == NextFormToShow.Form1) { Program.ActualNextForm = NextFormToShow.none; f = new Form1(); } if (Program.ActualNextForm == NextFormToShow.FormModEditerEmpty) { Program.ActualNextForm = NextFormToShow.none; f = new FormModEditer(); } if (Program.ActualNextForm == NextFormToShow.FormHelp1) { Program.ActualNextForm = NextFormToShow.none; f = new FormHelp(); f.TopMost = true; } if (Program.ActualNextForm == NextFormToShow.FormHelpMod) { Program.ActualNextForm = NextFormToShow.none; f = new FormHelpMod(); f.TopMost = true; } Application.Run(f); } }
private void AnyButton_MosueDown(object sender, MouseEventArgs e) { Button btn = (Button)sender; btn.Focus(); MOType mt = (MOType)(((object[])(btn.Tag))[0]); oItem i = (oItem)(((object[])(btn.Tag))[1]); if (e.Button == MouseButtons.Left) { if (mt == MOType.Belt) { if (i.IsBelt) //we set addmode only if the item can be a belt { MapObject newmo = new MapObject(MOType.Belt, i); this.Editer.StartAddMode(newmo); } } if (mt == MOType.Machine) { if (i.IsRecipe) //we set addmode only if the item can be a machine { MapObject newmo = new MapObject(MOType.Machine, i); this.Editer.StartAddMode(newmo); } } } if (e.Button == MouseButtons.Right) { //if this button is as machine, we show the user the inputs and outputs of the recipe if (mt == MOType.Machine) { //if this button is as machine, i represents the recipe oCraft c = Crafts.GetCraftFromRecipe(i); oRightClick3 rc = new oRightClick3(); rc.AddChoice(i.Name); if (c != null) { rc.AddSeparator(); rc.AddSeparator(); //add every outputs and inputs for the user rc.AddChoice("Outputs :"); foreach (oItem subi in c.Outputs) { rc.AddChoice("-" + subi.Name); } rc.AddChoice(""); rc.AddChoice("Inputs :"); foreach (oItem subi in c.Inputs) { rc.AddChoice("-" + subi.Name); } } string rep = rc.ShowDialog(); //it simply show to the user what the inputs and outputs are } //if this button is a belt, we show the user every crafts that require this item as input if (mt == MOType.Belt) { oRightClick3 rc = new oRightClick3(); rc.AddChoice(i.Name); rc.AddSeparator(); rc.AddChoice("Used In Recipe :"); //run through every crafts and check their inputs to see if the actual item is used in that craft foreach (oCraft c in Crafts.listCrafts) { //check the inputs and see if the item i is there foreach (oItem i2 in c.Inputs) { //check if this is the item we are searching if (i2.Name == i.Name) { //now that we have found the item in this craft, we add the craft recipe to the list and continue to the next item rc.AddChoice("-" + c.Recipe.Name); //now that we have found the item, we don't have to continue search in this craft break; } } } string rep = rc.ShowDialog(); //if the user clicked on a recipe, we set the editer to add mode and with a machine of that recipe. //we get the item from name oItem therecipe = Crafts.GetItemFromName(rep.Replace("-", string.Empty)); //the .Replace can be a little problem if - is truly part of the item name. //if rep is not an item, GetItemFromName will not return null, it will return the none item. if (therecipe.Name.ToLower() != "none") { MapObject newmo = new MapObject(MOType.Machine, therecipe); this.Editer.StartAddMode(newmo); } } } }
public void Fill(DataContext <HasIcon> context) { context.Set(Crafts.Cast <HasIcon>().ToArray()); }
public void RefreshImage() { //check are very usefull when minimizing the form. int imgWidth = this.Width; int imgHeight = this.Height; if (imgWidth < 100) { imgWidth = 100; } if (imgHeight < 100) { imgHeight = 100; } Bitmap img = new Bitmap(imgWidth, imgHeight); Graphics g = Graphics.FromImage(img); g.Clear(Color.FromArgb(32, 32, 32)); //if the grid is activated, we draw the grid if (this.ShowGrid) { //compute the graphical size of the cell. we make sure it's not too small. if it's too small, we don't draw them. float fUiGridCellSize = this.GridCellSize / this.VirtualWidth * (float)imgWidth; if (fUiGridCellSize >= 6f) { Pen GridPen = Pens.Black; //begins by converting the central pos into its closest grid coordinate float RoundedCX = this.GridRoundAxisValue(this.vpos.X); float RoundedCY = this.GridRoundAxisValue(this.vpos.Y); int index = 0; //just for "safety" purpose. to be really sure that there never will be infinite loop ////vertical line //draw the first vertical line int uiCX = this.ConvertVirtualToUi(RoundedCX, RoundedCY).X; g.DrawLine(GridPen, uiCX, 0, uiCX, imgHeight - 1); //vertical line to the right float ActualVX = RoundedCX; //actual virtual horizontal position while (true) { //move to the right ActualVX += this.GridCellSize; int uiLX = this.ConvertVirtualToUi(ActualVX, RoundedCY).X; //if we've finished to the right if (uiLX > imgWidth) { break; } //draw the line g.DrawLine(GridPen, uiLX, 0, uiLX, imgHeight - 1); //infinity loop check index++; if (index > 1000) { break; } } //vertical line to the left index = 0; ActualVX = RoundedCX; //we start again from the middle while (true) { //move to the left ActualVX -= this.GridCellSize; int uiLX = this.ConvertVirtualToUi(ActualVX, RoundedCY).X; //if we've finished the the left if (uiLX < 0) { break; } //draw the line g.DrawLine(GridPen, uiLX, 0, uiLX, imgHeight - 1); //infinity loop check index++; if (index > 1000) { break; } } ////horizontal line //draw the first horizontal line int uiCY = this.ConvertVirtualToUi(RoundedCX, RoundedCY).Y; g.DrawLine(GridPen, 0, uiCY, imgWidth - 1, uiCY); //horizontal line to the top index = 0; float ActualVY = RoundedCY; while (true) { //move to the top ActualVY += this.GridCellSize; int uiLY = this.ConvertVirtualToUi(RoundedCX, ActualVY).Y; //if we've finished to the top if (uiLY < 0) { break; } //draw the line g.DrawLine(GridPen, 0, uiLY, imgWidth - 1, uiLY); //infinity loop check index++; if (index > 1000) { break; } } //horizontal line to the bottom index = 0; ActualVY = RoundedCY; //we start again from the middle while (true) { //move down ActualVY -= this.GridCellSize; int uiLY = this.ConvertVirtualToUi(RoundedCX, ActualVY).Y; //if we've finished moving down if (uiLY > imgHeight) { break; } //draw the line g.DrawLine(GridPen, 0, uiLY, imgWidth - 1, uiLY); //infinity loop check index++; if (index > 1000) { break; } } } } //machine has the property IsAllInputPresent (belts too but it's only useful for machines). in the part of drawing the links, we "compute" is this property true or false. in the second part of refreshimage, this property defines the back color. //draw links between objects //// dessine les lien entre les object foreach (MapObject mo in this.Map.listMO) { Point mouipos = this.ConvertVirtualToUi(mo.vpos.X, mo.vpos.Y); try { if (mo.MapType == MOType.Belt) { MapObject[] twomo = this.Map.GetCompatible2BeltsCloseTo(mo); if (twomo[0] != null) { Point mouipos2 = this.ConvertVirtualToUi(twomo[0].vpos.X, twomo[0].vpos.Y); g.DrawLine(Pens.Silver, mouipos, mouipos2); } if (twomo[1] != null) { //i make sure the angle is not too small. it's just one of the check that makes the drawing of links not anoying. the purpose of the program is to draw somewhat useull links. i thought like 15 min about a program to help desing factories and i thought about how i would program the drawing of links and i come with these idea : 2 links per belt, angle not too small. //check the angle with the cosine law //// il doit checker l'angle avec la loi des cosinus float a = (float)(Math.Sqrt((twomo[1].vpos.X - mo.vpos.X) * (twomo[1].vpos.X - mo.vpos.X) + (twomo[1].vpos.Y - mo.vpos.Y) * (twomo[1].vpos.Y - mo.vpos.Y))); float b = (float)(Math.Sqrt((twomo[0].vpos.X - mo.vpos.X) * (twomo[0].vpos.X - mo.vpos.X) + (twomo[0].vpos.Y - mo.vpos.Y) * (twomo[0].vpos.Y - mo.vpos.Y))); float c = (float)(Math.Sqrt((twomo[1].vpos.X - twomo[0].vpos.X) * (twomo[1].vpos.X - twomo[0].vpos.X) + (twomo[1].vpos.Y - twomo[0].vpos.Y) * (twomo[1].vpos.Y - twomo[0].vpos.Y))); float angle = (float)(Math.Acos(((a * a) + (b * b) - (c * c)) / 2f / a / b)); if (angle > 1f) //i tried 1, i was satisfied { Point mouipos2 = this.ConvertVirtualToUi(twomo[1].vpos.X, twomo[1].vpos.Y); g.DrawLine(Pens.Silver, mouipos, mouipos2); } } } else if (mo.MapType == MOType.Machine) { //draw links of every output foreach (oItem i in mo.Outputs) { MapObject closest = this.Map.GetCompatibleBeltCloseTo(mo, i); //this.Map.FindClosestBeltWithInput(mo, i); if (closest != null) { Point mouipos2 = this.ConvertVirtualToUi(closest.vpos.X, closest.vpos.Y); g.DrawLine(Pens.Orchid, mouipos, mouipos2); // Orchid } } //draw links of every inputs mo.IsAllInputPresent = true; foreach (oItem i in mo.Inputs) { MapObject closest = this.Map.GetCompatibleBeltCloseTo(mo, i); //get the closest one //// obtien selui qui est le plus proche if (closest != null) { Point mouipos2 = this.ConvertVirtualToUi(closest.vpos.X, closest.vpos.Y); g.DrawLine(Pens.SkyBlue, mouipos, mouipos2); // SkyBlue } else { mo.IsAllInputPresent = false; } } //check if it's a furnace and if so, it draw coal if needed //// check le charbon des four if (mo.IsFurnace) { if (mo.NeedCoal) { MapObject close2 = this.Map.GetCompatibleBeltCloseTo(mo, Crafts.GetItemFromName("Coal")); //get the closest coal belt //// récupère la belt de charbon la plus près if (close2 != null) { Point mouipos2 = this.ConvertVirtualToUi(close2.vpos.X, close2.vpos.Y); g.DrawLine(Pens.SkyBlue, mouipos, mouipos2); } else { mo.IsAllInputPresent = false; } } } } } catch { } } Brush brushMachineBackBrush = new SolidBrush(Color.FromArgb(64, 64, 64)); //draw object foreach (MapObject mo in this.Map.listMO) { Point uipos = this.ConvertVirtualToUi(mo.vpos.X, mo.vpos.Y); //draw background int uiradius = (int)(mo.VirtualWidth * (float)(this.Width) / this.VirtualWidth / 2f + 0.5f); //graphical radius //// rayon graphique de l'objet if (mo.MapType == MOType.Belt) { Brush BackBrush = Brushes.DimGray; if (!mo.BeltOutput.IsBelt) { BackBrush = Brushes.Red; } g.FillEllipse(BackBrush, uipos.X - uiradius, uipos.Y - uiradius, 2 * uiradius, 2 * uiradius); } if (mo.MapType == MOType.Machine) { Brush moBackColor = brushMachineBackBrush; //Brushes.DimGray; Brush FurnaceLabelColor = Brushes.White; if (!mo.IsAllInputPresent) { moBackColor = Brushes.Crimson; FurnaceLabelColor = Brushes.White; } if (mo.TheCraft == null) { moBackColor = Brushes.Red; } //if it cannot be a recipe, we simlpy fill the background in pure and agressive red. when an item is not used as a recipe, no craft is found (obviously) so this property of the MapObject stay null and that's how we know that it's not a valid recipe. g.FillRectangle(moBackColor, uipos.X - uiradius, uipos.Y - uiradius, 2 * uiradius, 2 * uiradius); g.DrawRectangle(Pens.Silver, uipos.X - uiradius, uipos.Y - uiradius, 2 * uiradius, 2 * uiradius); if (mo.IsFurnace && uiradius >= 25) { Font fonte = new Font("consolas", 10f); g.DrawString("Furnace", fonte, FurnaceLabelColor, (float)(uipos.X - uiradius), (float)(uipos.Y - uiradius)); if (mo.NeedCoal) { g.DrawString("NeedCoal", fonte, FurnaceLabelColor, (float)(uipos.X - uiradius), (float)(uipos.Y - uiradius + 15)); } } } //get and draw image Bitmap moimg = mo.GetImage(); if (moimg != null) { //draw the image only if the image is not too big compared to the graphical size of the object //// dessine l'image seulement si elle n'est pas raisonnablement plus grande if (moimg.Width <= uiradius * 8) { try { g.DrawImage(moimg, uipos.X - (moimg.Width / 2), uipos.Y - (moimg.Height / 2)); } catch { } } } } g.Dispose(); if (this.ImageBox.Image != null) { this.ImageBox.Image.Dispose(); } this.ImageBox.Image = img; this.ImageBox.Refresh(); GC.Collect(); }