public static Craft recalculatecollisionbox(Craft c) { float up = 0; float down = 0; float left = 0; float right = 0; foreach (Part p in c.partlist) { if (p.pos.Y < up) { up = p.pos.Y; } if (p.pos.Y + p.size.Y > down) { down = p.pos.Y + p.size.Y; } if (p.pos.X < left) { left = p.pos.X; } if (p.pos.X + p.size.X > right) { right = p.pos.X + p.size.X; } } c.posoffset = new Vector2(left, up); c.size = new Vector2(right, down); return(c); }
public static bool usefuelbroken(Craft c, int id, float f) { foreach (Part p in c.partlist) { //p=engine part if (p.id == id) { List <int> connectedparts = new List <int>(); List <int> usedparts = new List <int>(); foreach (int i in p.neibours) { connectedparts.Add(i); } //loop all connected parts for (int i = 0; i < connectedparts.Count(); i++) { bool used = false; foreach (int k in usedparts) { if (i == k) { used = true; } } //if part not used before if (!used) { foreach (Part p1 in c.partlist) { if (p1.id == i) { usedparts.Add(i); if (p1.type == "fueltank") { //add new neibours foreach (int j in p.neibours) { connectedparts.Add(j); } //remove fuel if (p1.fuel > f) { p1.fuel -= f; return(true); } else { f -= p1.fuel; p1.fuel = 0; } } } } } } } } return(false); }
public static Craft changecraftpositions(Craft c) { Vector2 ppos = c.partlist[0].pos; for (int i = 0; i < c.partlist.Count(); i++) { c.partlist[i].pos -= ppos; c.partlist[i].pos /= 1000; c.partlist[i].size /= 1000; c.needsrerendering = 2; } return(c); }
public static float getmass(Craft c) { float m = 0f; foreach (Part p in c.partlist) { if (!p.dontcalculatemymass) { m += p.mass; m += p.fuel; } } return(m); }
public static bool usefuel(Craft c, int id, float f) { foreach (Part p in c.partlist) { //p=engine part if (p.id == id) { List <int> connectedparts = new List <int>(); List <int> usedparts = new List <int>(); foreach (int i in p.neibours) { connectedparts.Add(i); } //loop all connected parts for (int i = 0; i < connectedparts.Count(); i++) { foreach (Part p1 in c.partlist) { if (p1.id == connectedparts[i]) { if (p1.type == "fueltank") { //remove fuel if (p1.fuel > f) { p1.fuel -= f; return(true); } else { f -= p1.fuel; p1.fuel = 0; } } } } } } } return(false); }
public static void edit(List <Craft> craftlist) { #region camera if (Play.mousestate.MiddleButton == ButtonState.Pressed) { Camera.pos -= (Play.mousestate.Position.ToVector2() - Play.oldmousestate.Position.ToVector2()) / Camera.zoom; } Camera.zoom *= 1 + (Play.mousestate.ScrollWheelValue - Play.oldmousestate.ScrollWheelValue) * 0.001f; #endregion #region stages if (craftlist.Count != 0) { for (int i = 0; i < stage.Length; i++) { stage[i] = new List <int>(); } foreach (Part p in craftlist[0].partlist) { if (p.type == "engine" || p.type == "separator") { stage[p.stage].Add(p.id); } } } Vector2 pos = new Vector2(Camera.screencenter.X * 2 - 60, Camera.screencenter.Y * 2 - 60); stageiconpositionditictionary.Clear(); for (int i = 0; i < 10; i++) { if (stage[i] != null) { int startheight = (int)pos.Y; foreach (int j in stage[i]) { stageiconpositionditictionary.Add(j, pos); pos.Y -= 50; } //empty stage if (pos.Y == startheight) { stagerec[i] = new Rectangle((int)pos.X - 70, (int)pos.Y + 40, 120, (int)(30)); } else { stagerec[i] = new Rectangle((int)pos.X - 70, (int)pos.Y + 40, 120, (int)(startheight - pos.Y + 20)); } } pos.Y -= 50; } stageitemhovered = 0; if (stage != null & craftlist.Count != 0) { foreach (Part p in craftlist[0].partlist) { if (p.type == "engine" || p.type == "separator") { if (Play.isinside(new Vector2(Play.mousestate.X, Play.mousestate.Y), new Vector2(stageiconpositionditictionary[p.id].X, stageiconpositionditictionary[p.id].Y), new Vector2(40, 40))) { stageitemhovered = p.id; } } } } #endregion #region leftbuttonpressed //leftbuttonpressed if (Play.mousestate.LeftButton == ButtonState.Pressed & Play.oldmousestate.LeftButton == ButtonState.Released) { #region dragstages if (stage != null & craftlist.Count != 0) { if (stageonhand == 0) { foreach (Part p in craftlist[0].partlist) { if (p.type == "engine" || p.type == "separator") { if (Play.isinside(new Vector2(Play.mousestate.X, Play.mousestate.Y), new Vector2(stageiconpositionditictionary[p.id].X, stageiconpositionditictionary[p.id].Y), new Vector2(40, 40))) { stageonhand = p.id; } } } } //stage on hand else { for (int i = 0; i < stage.Length; i++) { if (Play.isinside(new Vector2(Play.mousestate.X, Play.mousestate.Y), new Vector2(stagerec[i].X, stagerec[i].Y), new Vector2(stagerec[i].Width, stagerec[i].Height))) { foreach (Part p in craftlist[0].partlist) { if (p.id == stageonhand) { p.stage = i; stageonhand = 0; } } } } } } #endregion #region parteditor Vector2 mousepos = Play.mousestate.Position.ToVector2(); if (parteditor & Play.isinside(mousepos, new Vector2(0, Camera.screencenter.Y * 2 - 500), new Vector2(300, 500))) { foreach (Part p in craftlist[0].partlist) { if (p.id == Editor.parteditornumber) { #region delete part Vector2 v2 = new Vector2(0, Camera.screencenter.Y * 2 - 500); if (Play.isinside(mousepos, new Vector2(v2.X + 260, v2.Y + 10), new Vector2(30, 30))) { p.removeme = true; } #endregion #region change part size Vector2 sizedelta = new Vector2(0, 0); //if smaller width button pressed if (Play.isinside(mousepos, new Vector2(v2.X + 10, v2.Y + 50), new Vector2(30, 30))) { sizedelta.X -= 100; } //if larger width button pressed if (Play.isinside(mousepos, new Vector2(v2.X + 260, v2.Y + 50), new Vector2(30, 30))) { sizedelta.X += 100; } //if smaller height button pressed if (Play.isinside(mousepos, new Vector2(v2.X + 10, v2.Y + 100), new Vector2(30, 30))) { sizedelta.Y -= 100; } //if larher height button pressed if (Play.isinside(mousepos, new Vector2(v2.X + 260, v2.Y + 100), new Vector2(30, 30))) { sizedelta.Y += 100; } if (Play.state.IsKeyDown(Keys.LeftShift)) { sizedelta *= 0.1f; } if (Play.state.IsKeyDown(Keys.LeftControl)) { sizedelta *= 10; } if (p.parentdirection == "center") { p.pos.X -= sizedelta.X / 2; p.size.X += sizedelta.X; p.pos.Y -= sizedelta.Y / 2; p.size.Y += sizedelta.Y; } if (p.parentdirection == "up") { p.pos.X -= sizedelta.X / 2; p.size.X += sizedelta.X; p.size.Y += sizedelta.Y; } if (p.parentdirection == "down") { p.pos.X -= sizedelta.X / 2; p.size.X += sizedelta.X; p.pos.Y -= sizedelta.Y / 2; p.size.Y += sizedelta.Y / 2; } if (p.parentdirection == "left") { p.pos.Y -= sizedelta.Y / 2; p.size.Y += sizedelta.Y; p.size.X += sizedelta.X; } if (p.parentdirection == "right") { p.pos.Y -= sizedelta.Y / 2; p.size.Y += sizedelta.Y; p.pos.X -= sizedelta.X; p.size.X += sizedelta.X; } #endregion #region commandpod if (p.type == "commandpod") { p.mass = 10000; } #endregion #region fueltank if (p.type == "fueltank") { //change fueltype backward if (Play.isinside(mousepos, new Vector2(v2.X + 10, v2.Y + 250), new Vector2(30, 30))) { p.fueltype = changefueltype(p.fueltype, -1); } //change fueltype forward if (Play.isinside(mousepos, new Vector2(v2.X + 260, v2.Y + 250), new Vector2(30, 30))) { p.fueltype = changefueltype(p.fueltype, 1); } double volume = Math.PI * p.size.X / 1000 * p.size.X / 1000 * p.size.Y / 1000 * 1000; volume *= 0.8443f; p.mass = (float)volume * 0.1f; if (p.fueltype == "Methalox") { //fuel density*volume of tank p.fuel = (float)(0.8376 * volume); } else if (p.fueltype == "Kerlox") { //fuel density*volume of tank p.fuel = (float)(1.0112 * volume); } } #endregion #region engine if (p.type == "engine") { if (Play.isinside(mousepos, new Vector2(v2.X + 10, v2.Y + 250), new Vector2(30, 30))) { p.fueltype = changefueltype(p.fueltype, -1); } if (Play.isinside(mousepos, new Vector2(v2.X + 260, v2.Y + 250), new Vector2(30, 30))) { p.fueltype = changefueltype(p.fueltype, 1); } float thrustdelta = 0; //less thrust if (Play.isinside(mousepos, new Vector2(v2.X + 260, v2.Y + 300), new Vector2(30, 30))) { thrustdelta += 1; } //MOAR POWER if (Play.isinside(mousepos, new Vector2(v2.X + 10, v2.Y + 300), new Vector2(30, 30))) { thrustdelta -= 1; } thrustdelta *= 10000; if (Play.state.IsKeyDown(Keys.LeftShift)) { thrustdelta *= 0.1f; } if (Play.state.IsKeyDown(Keys.LeftControl)) { thrustdelta *= 10; } p.thrust += thrustdelta; p.mass = (p.thrust / (90 * 9.81f)); if (p.fueltype == "Methalox") { p.isp = 361; } else if (p.fueltype == "Kerlox") { p.isp = 305; } } #endregion #region separator if (p.type == "separator") { } #endregion } } for (int i = 0; i < craftlist[0].partlist.Count(); i++) { if (craftlist[0].partlist[i].removeme) { //remove deleted part int id = craftlist[0].partlist[i].id; craftlist[0].partlist.Remove(craftlist[0].partlist[i]); for (int j = 0; j < craftlist[0].partlist.Count(); j++) { for (int k = 0; k < craftlist[0].partlist[j].neibours.Count(); k++) { //and from other parts neibours if (craftlist[0].partlist[j].neibours[k] == id) { craftlist[0].partlist[j].neibours.Remove(craftlist[0].partlist[j].neibours[k]); } } } } } } #endregion #region menu buttons else if (Play.isinside(new Vector2(Play.mousestate.X, Play.mousestate.Y), new Vector2(10, 10), new Vector2(400, 30))) { handpart.type = "commandpod"; } else if (Play.isinside(new Vector2(Play.mousestate.X, Play.mousestate.Y), new Vector2(10, 50), new Vector2(400, 30))) { handpart.type = "fueltank"; } else if (Play.isinside(new Vector2(Play.mousestate.X, Play.mousestate.Y), new Vector2(10, 90), new Vector2(400, 30))) { handpart.type = "engine"; } else if (Play.isinside(new Vector2(Play.mousestate.X, Play.mousestate.Y), new Vector2(10, 130), new Vector2(400, 30))) { handpart.type = "separator"; } else if (Play.isinside(new Vector2(Play.mousestate.X, Play.mousestate.Y), new Vector2(500, 10), new Vector2(400, 30))) { craftlist.Clear(); } else if (Play.isinside(new Vector2(Play.mousestate.X, Play.mousestate.Y), new Vector2(1000, 10), new Vector2(400, 30))) { craftlist[0] = changecraftpositions(craftlist[0]); craftlist[0] = Flight.recalculatecollisionbox(craftlist[0]); Flight.startflight(); Play.editor = false; Play.flight = true; } #endregion #region place part else if (handpart.type != "none") { #region add first part //add firstpart if (craftlist.Count == 0) { Craft craft = new Craft(); Part part = new Part(); part.id = craft.partnumber; craft.partnumber++; part.pos = new Vector2((((Play.mousestate.X - Camera.screencenter.X) / Camera.zoom) + Camera.pos.X) * 1, ((((Play.mousestate.Y - Camera.screencenter.Y) / Camera.zoom) + Camera.pos.Y) * 1)); part.type = handpart.type; craft.partlist.Add(part); craftlist.Add(craft); } #endregion #region add part to craft //add part else { bool snapped = false; for (int i = 0; i < craftlist[0].partlist.Count() & !snapped; i++) { Part p = craftlist[0].partlist[i]; Vector2 v2 = new Vector2(((Play.mousestate.X - Camera.screencenter.X) / Camera.zoom) + Camera.pos.X, (((Play.mousestate.Y - Camera.screencenter.Y) / Camera.zoom) + Camera.pos.Y)); //snap below if (Play.isinside(v2, new Vector2(p.pos.X + (p.size.X / 2) - Editor.handpart.size.X / 2, (p.pos.Y + p.size.Y)), new Vector2(Editor.handpart.size.X, Editor.handpart.size.Y))) { handpart.pos = new Vector2(p.pos.X + (p.size.X / 2) - (Editor.handpart.size.X / 2), p.pos.Y + p.size.Y); handpart.parentdirection = "up"; snapped = true; } //snap above if (Play.isinside(v2, new Vector2((p.pos.X + (p.size.X / 2) - (Editor.handpart.size.X / 2)), (p.pos.Y - Editor.handpart.size.Y)), new Vector2(Editor.handpart.size.X, Editor.handpart.size.Y))) { handpart.pos = new Vector2(p.pos.X + (p.size.X / 2) - (Editor.handpart.size.X / 2), p.pos.Y - Editor.handpart.size.Y); handpart.parentdirection = "down"; snapped = true; } //snap left if (Play.isinside(v2, new Vector2((p.pos.X - Editor.handpart.size.X), (p.pos.Y + (p.size.Y / 2) - (Editor.handpart.size.Y / 2))), new Vector2(Editor.handpart.size.X, Editor.handpart.size.Y))) { handpart.pos = new Vector2(p.pos.X - Editor.handpart.size.X, p.pos.Y + (p.size.Y / 2) - (Editor.handpart.size.Y / 2)); handpart.parentdirection = "right"; snapped = true; } //snap right if (Play.isinside(v2, new Vector2((p.pos.X + p.size.X), (p.pos.Y + (p.size.Y / 2) - (Editor.handpart.size.Y / 2))), new Vector2(Editor.handpart.size.X, Editor.handpart.size.Y))) { handpart.pos = new Vector2(p.pos.X + p.size.X, p.pos.Y + (p.size.Y / 2) - (Editor.handpart.size.Y / 2)); handpart.parentdirection = "left"; snapped = true; } if (snapped) { Part prt = new Part(); prt.pos = handpart.pos; prt.parentdirection = handpart.parentdirection; prt.type = handpart.type; prt.id = craftlist[0].partnumber; prt.parent = p.id; prt.neibours.Add(p.id); p.neibours.Add(prt.id); craftlist[0].partnumber++; craftlist[0].partlist.Add(prt); } } } #endregion } #region remove part else { } #endregion #endregion } #endregion #region rightbuttonpressed //rightbuttonpressed else if (Play.mousestate.RightButton == ButtonState.Pressed & Play.oldmousestate.RightButton == ButtonState.Released) { handpart.type = "none"; stageonhand = 0; for (int i = 0; i < craftlist[0].partlist.Count(); i++) { Part p = craftlist[0].partlist[i]; Vector2 v2 = new Vector2(((Play.mousestate.X - Camera.screencenter.X) / Camera.zoom) + Camera.pos.X, (((Play.mousestate.Y - Camera.screencenter.Y) / Camera.zoom) + Camera.pos.Y)); if (Play.isinside(v2, new Vector2(p.pos.X, p.pos.Y), new Vector2(p.size.X, p.size.Y))) { parteditor = true; parteditornumber = p.id; } } } #endregion }
public static void draw(SpriteBatch sb, GraphicsDevice gd, Matrix matrix, GameTime gameTime, List <Craft> craftlist) { gd.Clear(Color.Black); #region rendertarget foreach (Craft c in craftlist) { if (c.needsrerendering > 0) { c.rendertarget = new RenderTarget2D(gd, (int)((c.size.X - c.posoffset.X) * 1000), (int)((c.size.Y - c.posoffset.Y) * 1000)); gd.SetRenderTarget(c.rendertarget); gd.Clear(Color.Transparent); sb.Begin(); foreach (Part p in c.partlist) { sb.Draw(Drawing.dictionary[p.type], new Rectangle((int)((p.pos.X - c.posoffset.X) * 1000), (int)((p.pos.Y - c.posoffset.Y) * 1000), (int)(p.size.X * 1000), (int)(p.size.Y * 1000)), Color.White); } sb.End(); c.needsrerendering--; gd.SetRenderTarget(null); } } #endregion #region draw world sb.Begin(SpriteSortMode.Immediate, null, null, null, null, null, Camera.matrix(gd.Viewport)); #region draw path if (Camera.zoom < 1.76313472) { //drawaccurateorbits(sb, gd, matrix, gameTime, craftlist); draworbits(sb, gd, matrix, gameTime, craftlist); sb.Draw(Drawing.arrow, craftlist[0].pos, null, Color.White, (float)craftlist[0].rotation, new Vector2(32, 32), (1 / Camera.zoom) * 0.25f, SpriteEffects.None, 1); } #endregion #region draw planets if (Flight.planet[0].hasatmosphere) { Rectangle arec = new Rectangle((int)((Flight.planet[0].posx - (Flight.planet[0].radius + Flight.planet[0].atmosphereradius)) * worldscale), (int)((Flight.planet[0].posy - (Flight.planet[0].radius + Flight.planet[0].atmosphereradius)) * worldscale), (int)((Flight.planet[0].radius + Flight.planet[0].atmosphereradius) * 2 * worldscale), (int)((Flight.planet[0].radius + Flight.planet[0].atmosphereradius) * 2 * worldscale)); sb.Draw(Drawing.atmosphere, arec, Color.White); } Rectangle rec = new Rectangle((int)((Flight.planet[0].posx - Flight.planet[0].radius * 1) * worldscale), (int)((Flight.planet[0].posy - Flight.planet[0].radius * 1) * worldscale), (int)(Flight.planet[0].radius * 2 * worldscale), (int)(Flight.planet[0].radius * 2 * worldscale)); sb.Draw(Flight.planet[0].texture, rec, Color.White); //sb.Draw(Drawing.white, new Rectangle((int)craftlist[0].pos.X,(int)craftlist[0].pos.Y,1,1), Color.Green); #endregion #region draw crafts sb.End(); sb.Begin(); foreach (Craft c in craftlist) { Rectangle srec = new Rectangle(0, 0, c.rendertarget.Width, c.rendertarget.Height); sb.Draw(c.rendertarget, Camera.screencenter + (c.pos * worldscale), srec, Color.White, c.rotation, new Vector2(0, 0), Camera.zoom / 1000, SpriteEffects.None, 1); } sb.End(); #endregion #endregion #region draw menus sb.Begin(); sb.DrawString(Drawing.font, "Throttle = " + (craftlist[0].throttle * 100).ToString(), new Vector2(0, 0), Color.White); sb.DrawString(Drawing.font, "vel = " + Drawing.getsiprefix(craftlist[0].vel.Length()) + "M/S", new Vector2(0, 20), Color.White); foreach (Part p in craftlist[0].partlist) { if (p.type == "engine" & p.on) { sb.DrawString(Drawing.font, "TWR = " + (craftlist[0].throttle * p.thrust / (craftlist[0].mass * 9.81f)), new Vector2(0, 40), Color.White); } } sb.DrawString(Drawing.font, "Timewarp = " + Flight.timewarp.ToString() + "* speed", new Vector2(0, 60), Color.White); sb.DrawString(Drawing.font, "Altitude = " + Drawing.getsiprefix((Flight.planet[0].pos - craftlist[0].pos).Length()) + "m", new Vector2(200, 0), Color.White); sb.DrawString(Drawing.font, "Alt surf = " + Drawing.getsiprefix((Flight.planet[0].pos - craftlist[0].pos).Length() - Flight.planet[0].radius) + "m", new Vector2(200, 20), Color.White); if (Camera.zoom < 1.76313472) { sb.DrawString(Drawing.font, "Apoapsis = " + Drawing.getsiprefix(apoapsis) + "m", new Vector2(500, 0), Color.White); sb.DrawString(Drawing.font, "Periapsis = " + Drawing.getsiprefix(periapsis) + "m", new Vector2(500, 20), Color.White); sb.DrawString(Drawing.font, "Time to apoapsis = " + Drawing.getsiprefix(timetoapoapsis) + "s", new Vector2(800, 0), Color.White); sb.DrawString(Drawing.font, "Time to periapsis = " + Drawing.getsiprefix(timetoperiapsis) + "s", new Vector2(800, 20), Color.White); sb.DrawString(Drawing.font, "Eccentricity = " + eccentricity.ToString(), new Vector2(1100, 0), Color.White); } #region deltavstats if (Editor.stage != null & craftlist.Count != 0 & true) { Craft c = new Craft(); int laststage = 10; c.partlist = new List <Part>(craftlist[0].partlist); foreach (Part p in c.partlist) { p.dontcalculatemymass = false; } float[] deltav = new float[10]; float[] twr = new float[10]; for (int s = 0; s < 10; s++) { if (Editor.stage[s] != null) { foreach (int i in Editor.stage[s]) { for (int j = 0; j < c.partlist.Count(); j++) { Part p = c.partlist[j]; if (c.partlist[j].id == i) { if (c.partlist[j].type == "separator") { //separator part List <Part> lista = new List <Part>(); List <int> used = new List <int>(); foreach (Part pa in c.partlist) { if (pa.id != p.parent) { foreach (int n in p.neibours) { if (n == pa.id) { lista.Add(pa); } } } } for (int k = 0; k < lista.Count(); k++) { bool partused = false; foreach (int l in used) { if (lista[k].id == l) { partused = true; } } if (!partused) { foreach (Part pa in c.partlist) { foreach (int n in lista[k].neibours) { if (n == pa.id) { lista.Add(pa); used.Add(pa.id); } } } } } foreach (Part pa in lista) { pa.dontcalculatemymass = true; } } } } } for (int i = 0; i < c.partlist.Count(); i++) { if (c.partlist[i].removeme) { c.partlist.Remove(c.partlist[i]); } } if (Editor.stage[s].Count == 0 & laststage == 10) { laststage = s; } foreach (int i in Editor.stage[s]) { for (int j = 0; j < c.partlist.Count(); j++) { if (c.partlist[j].id == i) { if (c.partlist[j].type == "engine") { //engine part foreach (int k in c.partlist[j].neibours) { for (int l = 0; l < c.partlist.Count(); l++) { if (c.partlist[l].id == k) { //neibour of the engine float mass = DrawEditor.getmass(c); deltav[s] += (float)(Math.Log(mass / (mass - c.partlist[l].fuel)) * c.partlist[j].isp * 9.81f); //why ar u lying to me??? twr[s] = c.partlist[j].thrust / (mass * 9.81f); } } } } } } } } else { laststage = s; } } //explanations here int ssep = 50; sb.Draw(Drawing.white, new Rectangle(0, (int)Camera.screencenter.Y * 2 + 10 - (laststage + 1) * ssep, 600, (laststage + 2) * ssep), Color.Gray); for (int i = 0; i < laststage; i++) { sb.Draw(Drawing.white, new Rectangle(10, (int)Camera.screencenter.Y * 2 - 50 - i * ssep, 90, ssep), Color.Black); sb.DrawString(Drawing.font, deltav[i].ToString(), new Vector2(10, Camera.screencenter.Y * 2 - 50 - i * ssep), Color.White); sb.Draw(Drawing.white, new Rectangle(110, (int)Camera.screencenter.Y * 2 - 50 - i * ssep, 90, ssep), Color.Black); sb.DrawString(Drawing.font, twr[i].ToString(), new Vector2(110, Camera.screencenter.Y * 2 - 50 - i * ssep), Color.White); } sb.DrawString(Drawing.font, "deltav", new Vector2(10, Camera.screencenter.Y * 2 + 10 - (laststage + 1) * ssep), Color.White); sb.DrawString(Drawing.font, "TWR", new Vector2(110, Camera.screencenter.Y * 2 + 10 - (laststage + 1) * ssep), Color.White); foreach (Part p in c.partlist) { p.dontcalculatemymass = false; } } sb.End(); #endregion #endregion }
public static void fly(List <Craft> craftlist) { #region controlls #region camera if (Play.mousestate != Play.oldmousestate) { Camera.zoom *= 1 + (Play.mousestate.ScrollWheelValue - Play.oldmousestate.ScrollWheelValue) * 0.001f; } #endregion if (Play.state.IsKeyDown(Keys.A)) { craftlist[0].rotation -= 0.01f; } if (Play.state.IsKeyDown(Keys.D)) { craftlist[0].rotation += 0.01f; } if (Play.state.IsKeyDown(Keys.Z)) { craftlist[0].throttle = 1; } if (Play.state.IsKeyDown(Keys.X)) { craftlist[0].throttle = 0; } if (Play.state.IsKeyDown(Keys.LeftShift)) { craftlist[0].throttle += 0.01f; } if (Play.state.IsKeyDown(Keys.LeftControl)) { craftlist[0].throttle -= 0.01f; } if (craftlist[0].throttle > 1) { craftlist[0].throttle = 1; } if (craftlist[0].throttle < 0) { craftlist[0].throttle = 0; } if (Play.state.IsKeyUp(Keys.OemPeriod) & Play.oldstate.IsKeyDown(Keys.OemPeriod)) { timewarp *= 2; } if (Play.state.IsKeyUp(Keys.OemComma) & Play.oldstate.IsKeyDown(Keys.OemComma)) { timewarp /= 2; } if (timewarp <= 0) { timewarp = 1; } #region next stage if (Play.state.IsKeyUp(Keys.Space) & Play.oldstate.IsKeyDown(Keys.Space)) { foreach (Part p in craftlist[0].partlist) { if (p.type == "engine" || p.type == "separator") { if (p.stage == craftlist[0].stage) { if (p.type == "engine") { p.on = true; } if (p.type == "separator") { List <Part> lista = new List <Part>(); List <int> used = new List <int>(); foreach (Part pa in craftlist[0].partlist) { if (pa.id != p.parent) { foreach (int n in p.neibours) { if (n == pa.id) { lista.Add(pa); } } } } for (int i = 0; i < lista.Count(); i++) { bool partused = false; foreach (int j in used) { if (lista[i].id == j) { partused = true; } } if (!partused) { foreach (Part pa in craftlist[0].partlist) { foreach (int n in lista[i].neibours) { if (n == pa.id) { lista.Add(pa); used.Add(pa.id); } } } } } //separate the stages Craft c = new Craft(); c.pos = craftlist[0].pos + Vector2.Transform(p.pos, Matrix.CreateRotationZ(craftlist[0].rotation)); c.rotation = craftlist[0].rotation; c.vel = craftlist[0].vel; c.needsrerendering = 2; foreach (Part pa in lista) { c.partlist.Add(pa); pa.removeme = true; } c = recalculatecollisionbox(c); craftlist.Add(c); craftlist[0] = recalculatecollisionbox(craftlist[0]); craftlist[0].needsrerendering = 2; } } } } craftlist[0].stage++; } //had to remove parts outside of the foreach loop for (int i = 0; i < craftlist[0].partlist.Count(); i++) { if (craftlist[0].partlist[i].removeme) { craftlist[0].partlist.Remove(craftlist[0].partlist[i]); } } #endregion #endregion #region movement for (int w = 0; w < timewarp; w++) { foreach (Craft c in craftlist) { if (craftlist[0].throttle > 0) { foreach (Part p in c.partlist) { if (p.type == "engine" & p.on) { float fuelusage = (p.thrust / (9.81f * p.isp)) / 60; p.running = usefuel(c, p.id, fuelusage); if (p.running) { c.mass = 0; foreach (Part p1 in c.partlist) { c.mass += p1.mass; c.mass += p1.fuel; } c.vel += (new Vector2((float)(((c.throttle * p.thrust) / c.mass) * Math.Sin(c.rotation)), -(float)(((c.throttle * p.thrust) / c.mass) * Math.Cos(c.rotation)))) / (60); } } } } } #region gravity foreach (Craft c in craftlist) { float r = (planet[0].pos - c.pos).Length(); Vector2 v = (planet[0].pos - c.pos); double a = Math.Atan2(v.Y, v.X); float G = (0.00000000006674f * (planet[0].mass) / (r * r)); c.vel.X += (float)(G * Math.Cos(a) / 60); c.vel.Y += (float)(G * Math.Sin(a) / 60); } #endregion #region collisions foreach (Craft c in craftlist) { Vector2 v = (planet[0].pos - c.pos); float a = (float)Math.Atan2(v.Y, v.X); double ang = Math.Atan2(planet[0].pos.Y, planet[0].pos.X) - Math.Atan2(c.vel.Y, c.vel.X); if ((planet[0].pos - c.pos).Length() <= planet[0].radius & (ang < Math.PI / 2)) { c.pos = planet[0].pos + Vector2.Normalize(c.pos - planet[0].pos) * (planet[0].radius); c.vel = new Vector2(0, 0); c.rotation = (float)(a - Math.PI / 2); } } #endregion foreach (Craft c in craftlist) { c.pos += c.vel / 60; } if (craftlist[0].pos != new Vector2(0, 0)) { Vector2 offset = craftlist[0].pos; foreach (Craft c in craftlist) { c.pos -= offset; } foreach (Planet p in Flight.planet) { p.posx -= offset.X; p.posy -= offset.Y; p.pos = new Vector2((float)p.posx, (float)p.posy); } } //move camera to the center of the craft Camera.pos = craftlist[0].pos * Drawflight.worldscale;// + Vector2.Transform((craftlist[0].size/2), Matrix.CreateRotationZ(craftlist[0].rotation)); #endregion } }
public static void draw(SpriteBatch sb, GraphicsDevice gd, Matrix matrix, GameTime gameTime, List <Craft> craftlist) { gd.Clear(Color.CornflowerBlue); sb.Begin(); sb.Draw(Drawing.white, new Rectangle(10, 10, 400, 30), Color.Green); sb.DrawString(Drawing.menufont, "Commandpod", new Vector2(50, 10), Color.White); sb.Draw(Drawing.white, new Rectangle(10, 50, 400, 30), Color.Green); sb.DrawString(Drawing.menufont, "Fueltank", new Vector2(50, 50), Color.White); sb.Draw(Drawing.white, new Rectangle(10, 90, 400, 30), Color.Green); sb.DrawString(Drawing.menufont, "Engine", new Vector2(50, 90), Color.White); sb.Draw(Drawing.white, new Rectangle(10, 130, 400, 30), Color.Green); sb.DrawString(Drawing.menufont, "Separator", new Vector2(50, 130), Color.White); sb.Draw(Drawing.white, new Rectangle(500, 10, 400, 30), Color.Red); sb.DrawString(Drawing.menufont, "Delete craft", new Vector2(550, 10), Color.White); sb.Draw(Drawing.white, new Rectangle(1000, 10, 400, 30), Color.Green); sb.DrawString(Drawing.menufont, "Fly", new Vector2(1050, 10), Color.White); #region part editor if (Editor.parteditor & craftlist.Count != 0) { foreach (Part p in craftlist[0].partlist) { if (p.id == Editor.parteditornumber) { //V2 is startpoint of the parteditor window Vector2 v2 = new Vector2(0, Camera.screencenter.Y * 2 - 500); //draw line from part to parteditorwindow //Drawflight.DrawLine(sb,v2+new Vector2(300,0), new Vector2((p.pos.X)* Camera.zoom + Camera.pos.X, ((p.pos.Y) * Camera.zoom + Camera.pos.Y))); //draw part editor borders sb.Draw(Drawing.white, new Rectangle((int)v2.X, (int)v2.Y, 300, 500), Color.Blue); //part type sb.Draw(Drawing.white, new Rectangle((int)v2.X + 10, (int)v2.Y + 10, 240, 30), Color.White); sb.DrawString(Drawing.menufont, p.type, new Vector2(v2.X + 10, v2.Y + 10), Color.Black); //delete part button sb.Draw(Drawing.redxbutton, new Rectangle((int)v2.X + 260, (int)v2.Y + 10, 30, 30), Color.White); //part width sb.Draw(Drawing.minusbutton, new Rectangle((int)v2.X + 10, (int)v2.Y + 50, 30, 30), Color.White); sb.Draw(Drawing.plusbutton, new Rectangle((int)v2.X + 260, (int)v2.Y + 50, 30, 30), Color.White); sb.Draw(Drawing.white, new Rectangle((int)v2.X + 50, (int)v2.Y + 50, 200, 30), Color.White); sb.DrawString(Drawing.font, "Width: " + (p.size.X / 1000).ToString() + " M", new Vector2(v2.X + 50, v2.Y + 50), Color.Black); //part height sb.Draw(Drawing.minusbutton, new Rectangle((int)v2.X + 10, (int)v2.Y + 100, 30, 30), Color.White); sb.Draw(Drawing.plusbutton, new Rectangle((int)v2.X + 260, (int)v2.Y + 100, 30, 30), Color.White); sb.Draw(Drawing.white, new Rectangle((int)v2.X + 50, (int)v2.Y + 100, 200, 30), Color.White); sb.DrawString(Drawing.font, "Height: " + (p.size.Y / 1000).ToString() + " M", new Vector2(v2.X + 50, v2.Y + 100), Color.Black); //part mass sb.Draw(Drawing.white, new Rectangle((int)v2.X + 10, (int)v2.Y + 150, 280, 30), Color.White); sb.DrawString(Drawing.font, "Mass: " + Drawing.getsiprefix(p.mass * 1000) + "g", new Vector2(v2.X + 50, v2.Y + 150), Color.Black); #region commandpod if (p.type == "commandpod") { } #endregion #region fueltank if (p.type == "fueltank") { //wet mass sb.Draw(Drawing.white, new Rectangle((int)v2.X + 10, (int)v2.Y + 200, 280, 30), Color.White); sb.DrawString(Drawing.font, "Wet mass: " + Drawing.getsiprefix((p.mass + p.fuel) * 1000) + "g", new Vector2(v2.X + 50, v2.Y + 200), Color.Black); //fueltype sb.Draw(Drawing.minusbutton, new Rectangle((int)v2.X + 10, (int)v2.Y + 250, 30, 30), Color.White); sb.Draw(Drawing.plusbutton, new Rectangle((int)v2.X + 260, (int)v2.Y + 250, 30, 30), Color.White); sb.Draw(Drawing.white, new Rectangle((int)v2.X + 50, (int)v2.Y + 250, 200, 30), Color.White); sb.DrawString(Drawing.font, "fueltype: " + p.fueltype, new Vector2(v2.X + 50, v2.Y + 250), Color.Black); } #endregion #region engine if (p.type == "engine") { sb.Draw(Drawing.white, new Rectangle((int)v2.X + 10, (int)v2.Y + 200, 280, 30), Color.White); sb.DrawString(Drawing.font, "ISP: " + p.isp + "S", new Vector2(v2.X + 50, v2.Y + 200), Color.Black); sb.Draw(Drawing.minusbutton, new Rectangle((int)v2.X + 10, (int)v2.Y + 250, 30, 30), Color.White); sb.Draw(Drawing.plusbutton, new Rectangle((int)v2.X + 260, (int)v2.Y + 250, 30, 30), Color.White); sb.Draw(Drawing.white, new Rectangle((int)v2.X + 50, (int)v2.Y + 250, 200, 30), Color.White); sb.DrawString(Drawing.font, "Fuel type: " + p.fueltype, new Vector2(v2.X + 50, v2.Y + 250), Color.Black); sb.Draw(Drawing.minusbutton, new Rectangle((int)v2.X + 10, (int)v2.Y + 300, 30, 30), Color.White); sb.Draw(Drawing.plusbutton, new Rectangle((int)v2.X + 260, (int)v2.Y + 300, 30, 30), Color.White); sb.Draw(Drawing.white, new Rectangle((int)v2.X + 50, (int)v2.Y + 300, 200, 30), Color.White); sb.DrawString(Drawing.font, "thrust: " + Drawing.getsiprefix(p.thrust) + "N", new Vector2(v2.X + 50, v2.Y + 300), Color.Black); } #endregion #region separator if (p.type == "separator") { } #endregion } } } #endregion #region stages if (Editor.stage != null & craftlist.Count != 0) { for (int s = 0; s < 10; s++) { if (Editor.stage[s] != null) { sb.Draw(Drawing.white, Editor.stagerec[s], Color.Red); sb.DrawString(Drawing.menufont, "S" + s.ToString(), new Vector2(Editor.stagerec[s].X + 5, Editor.stagerec[s].Y + (Editor.stagerec[s].Height / 2) - 20), Color.White); foreach (int i in Editor.stage[s]) { foreach (Part p in craftlist[0].partlist) { if (p.id == i) { if (p.id != Editor.stageonhand) { sb.Draw(Drawing.white, new Rectangle((int)Editor.stageiconpositionditictionary[i].X, (int)Editor.stageiconpositionditictionary[i].Y, 40, 40), Color.White); sb.Draw(Drawing.dictionary[p.type], new Rectangle((int)Editor.stageiconpositionditictionary[i].X, (int)Editor.stageiconpositionditictionary[i].Y, 40, 40), Color.White); } } } } } } if (Editor.stageonhand != 0) { foreach (Part p in craftlist[0].partlist) { if (p.id == Editor.stageonhand) { sb.Draw(Drawing.white, new Rectangle((int)Play.mousestate.X - 20, Play.mousestate.Y - 20, 40, 40), Color.White); sb.Draw(Drawing.dictionary[p.type], new Rectangle((int)Play.mousestate.X - 20, Play.mousestate.Y - 20, 40, 40), Color.White); } } } } #endregion #region deltavstats if (Editor.stage != null & craftlist.Count != 0 & true) { Craft c = new Craft(); int laststage = 10; c.partlist = new List <Part>(craftlist[0].partlist); foreach (Part p in c.partlist) { p.dontcalculatemymass = false; } float[] deltav = new float[10]; float[] twr = new float[10]; for (int s = 0; s < 10; s++) { if (Editor.stage[s] != null) { foreach (int i in Editor.stage[s]) { for (int j = 0; j < c.partlist.Count(); j++) { Part p = c.partlist[j]; if (c.partlist[j].id == i) { if (c.partlist[j].type == "separator") { //separator part List <Part> lista = new List <Part>(); List <int> used = new List <int>(); foreach (Part pa in c.partlist) { if (pa.id != p.parent) { foreach (int n in p.neibours) { if (n == pa.id) { lista.Add(pa); } } } } for (int k = 0; k < lista.Count(); k++) { bool partused = false; foreach (int l in used) { if (lista[k].id == l) { partused = true; } } if (!partused) { foreach (Part pa in c.partlist) { foreach (int n in lista[k].neibours) { if (n == pa.id) { lista.Add(pa); used.Add(pa.id); } } } } } foreach (Part pa in lista) { pa.dontcalculatemymass = true; } } } } } for (int i = 0; i < c.partlist.Count(); i++) { if (c.partlist[i].removeme) { c.partlist.Remove(c.partlist[i]); } } if (Editor.stage[s].Count == 0 & laststage == 10) { laststage = s; } foreach (int i in Editor.stage[s]) { for (int j = 0; j < c.partlist.Count(); j++) { if (c.partlist[j].id == i) { if (c.partlist[j].type == "engine") { //engine part foreach (int k in c.partlist[j].neibours) { for (int l = 0; l < c.partlist.Count(); l++) { if (c.partlist[l].id == k) { //neibour of the engine float mass = getmass(c); deltav[s] += (float)(Math.Log(mass / (mass - c.partlist[l].fuel)) * c.partlist[j].isp * 9.81f); //why ar u lying to me??? twr[s] = c.partlist[j].thrust / (mass * 9.81f); } } } } } } } } else { laststage = s; } } //explanations here int ssep = 50; sb.Draw(Drawing.white, new Rectangle(400, (int)Camera.screencenter.Y * 2 + 10 - (laststage + 1) * ssep, 600, (laststage + 2) * ssep), Color.Black); for (int i = 0; i < laststage; i++) { sb.Draw(Drawing.white, new Rectangle(400, (int)Camera.screencenter.Y * 2 - 50 - i * ssep, 90, ssep), Color.Gray); sb.DrawString(Drawing.font, deltav[i].ToString(), new Vector2(400, Camera.screencenter.Y * 2 - 50 - i * ssep), Color.White); sb.Draw(Drawing.white, new Rectangle(500, (int)Camera.screencenter.Y * 2 - 50 - i * ssep, 90, ssep), Color.Gray); sb.DrawString(Drawing.font, twr[i].ToString(), new Vector2(500, Camera.screencenter.Y * 2 - 50 - i * ssep), Color.White); } sb.DrawString(Drawing.font, "deltav", new Vector2(400, Camera.screencenter.Y * 2 + 10 - (laststage + 1) * ssep), Color.White); sb.DrawString(Drawing.font, "TWR", new Vector2(500, Camera.screencenter.Y * 2 + 10 - (laststage + 1) * ssep), Color.White); foreach (Part p in c.partlist) { p.dontcalculatemymass = false; } } sb.End(); #endregion sb.Begin(SpriteSortMode.Immediate, null, null, null, null, null, Camera.matrix(gd.Viewport)); Rectangle rec = new Rectangle((int)(((Play.mousestate.X - Camera.screencenter.X) / Camera.zoom) + Camera.pos.X), (int)(((Play.mousestate.Y - Camera.screencenter.Y) / Camera.zoom) + Camera.pos.Y), (int)Editor.handpart.size.X, (int)Editor.handpart.size.Y); if (Editor.handpart.type != "none") { sb.Draw(Drawing.dictionary[Editor.handpart.type], rec, Color.White); } if (craftlist.Count != 0) { #region drawparts foreach (Part p in craftlist[0].partlist) { sb.Draw(Drawing.dictionary[p.type], new Rectangle((int)p.pos.X * 1, (int)p.pos.Y, (int)p.size.X, (int)p.size.Y), Color.White); if (Editor.stageonhand != 0 & p.id == Editor.stageonhand || Editor.stageitemhovered != 0 & p.id == Editor.stageitemhovered) { Color c = Color.Green; c.A = 100; sb.Draw(Drawing.dictionary[p.type], new Rectangle((int)p.pos.X, (int)p.pos.Y, (int)p.size.X, (int)p.size.Y), c); } #region snap part if (Editor.handpart.type != "none") { //draw part that will snap Vector2 v2 = new Vector2(((Play.mousestate.X - Camera.screencenter.X) / Camera.zoom) + Camera.pos.X, (((Play.mousestate.Y - Camera.screencenter.Y) / Camera.zoom) + Camera.pos.Y)); //snap to bottom if (Play.isinside(v2, new Vector2(p.pos.X + (p.size.X / 2) - Editor.handpart.size.X / 2, (p.pos.Y + p.size.Y)), new Vector2(Editor.handpart.size.X, Editor.handpart.size.Y))) { sb.Draw(Drawing.dictionary[Editor.handpart.type], new Rectangle((int)(p.pos.X + (p.size.X / 2) - (Editor.handpart.size.X / 2)), (int)((p.pos.Y + p.size.Y)), (int)Editor.handpart.size.X, (int)Editor.handpart.size.Y), Color.White); } //snap to top if (Play.isinside(v2, new Vector2((p.pos.X + (p.size.X / 2) - (Editor.handpart.size.X / 2)), (p.pos.Y - Editor.handpart.size.Y)), new Vector2(Editor.handpart.size.X, Editor.handpart.size.Y))) { sb.Draw(Drawing.dictionary[Editor.handpart.type], new Rectangle((int)(p.pos.X + (p.size.X / 2) - (Editor.handpart.size.X / 2)), (int)(p.pos.Y - Editor.handpart.size.Y), (int)Editor.handpart.size.X, (int)Editor.handpart.size.Y), Color.White); } //snap to left if (Play.isinside(v2, new Vector2((p.pos.X - Editor.handpart.size.X), (p.pos.Y + (p.size.Y / 2) - (Editor.handpart.size.Y / 2))), new Vector2(Editor.handpart.size.X, Editor.handpart.size.Y))) { sb.Draw(Drawing.dictionary[Editor.handpart.type], new Rectangle((int)(p.pos.X - Editor.handpart.size.X), (int)(p.pos.Y + (p.size.Y / 2) - (Editor.handpart.size.Y / 2)), (int)Editor.handpart.size.X, (int)Editor.handpart.size.Y), Color.White); } //snap to right if (Play.isinside(v2, new Vector2((p.pos.X + p.size.X), (p.pos.Y + (p.size.Y / 2) - (Editor.handpart.size.Y / 2))), new Vector2(Editor.handpart.size.X, Editor.handpart.size.Y))) { sb.Draw(Drawing.dictionary[Editor.handpart.type], new Rectangle((int)(p.pos.X + p.size.X), (int)(p.pos.Y + (p.size.Y / 2) - (Editor.handpart.size.Y / 2)), (int)Editor.handpart.size.X, (int)Editor.handpart.size.Y), Color.White); } } } #endregion } sb.End(); #endregion }