From 2a79182cac168d9b176e77ca1b667a99ee3b2e5c Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Fri, 25 Aug 2023 06:30:39 +0000 Subject: [PATCH] Component, text editor, debug controls; editor modes; input blocking; cmdline docstring output to markdown [8d85349744c4d40a] --- source/engine/3d/model.c | 1 - source/engine/input.c | 4 +- source/engine/openglrender.c | 1 - source/engine/script.c | 2 - source/engine/yugine.c | 33 +- source/scripts/components.js | 330 ++++++++---------- source/scripts/editor.js | 658 ++++++++++++++++++----------------- source/scripts/engine.js | 90 +++-- 8 files changed, 565 insertions(+), 554 deletions(-) diff --git a/source/engine/3d/model.c b/source/engine/3d/model.c index 3fa6e12..30d5f34 100644 --- a/source/engine/3d/model.c +++ b/source/engine/3d/model.c @@ -37,7 +37,6 @@ static sg_shader model_shader; static sg_pipeline model_pipe; void model_init() { - YughWarn("Creating model"); model_shader = sg_compile_shader("shaders/diffuse_v.glsl", "shaders/diffuse_f.glsl", &(sg_shader_desc){ .vs.uniform_blocks[0] = { .size = sizeof(float) * 16 * 4, diff --git a/source/engine/input.c b/source/engine/input.c index 8d6bd99..7c5e561 100644 --- a/source/engine/input.c +++ b/source/engine/input.c @@ -376,7 +376,7 @@ const char *keyname_extd(int key, int scancode) { kkey = "minus"; break; case GLFW_KEY_GRAVE_ACCENT: - kkey = "backtick"; + kkey = "`"; break; case GLFW_KEY_LEFT_BRACKET: @@ -575,6 +575,6 @@ int want_quit() { } void quit() { - YughInfo("Exiting game."); + exit(0); mquit = 1; } diff --git a/source/engine/openglrender.c b/source/engine/openglrender.c index 6ee14fa..58173a4 100644 --- a/source/engine/openglrender.c +++ b/source/engine/openglrender.c @@ -266,7 +266,6 @@ void render_winsize() static cpBody *camera = NULL; void set_cam_body(cpBody *body) { - YughWarn("Camera body set to %p", body); camera = body; } diff --git a/source/engine/script.c b/source/engine/script.c index 816ad64..edccec5 100644 --- a/source/engine/script.c +++ b/source/engine/script.c @@ -94,8 +94,6 @@ void script_evalf(const char *format, ...) vsnprintf(fmtbuf, 4096, format, args); va_end(args); - YughWarn(fmtbuf); - JSValue obj = JS_Eval(js, fmtbuf, strlen(fmtbuf), "C eval", JS_EVAL_FLAGS); js_print_exception(obj); JS_FreeValue(js,obj); diff --git a/source/engine/yugine.c b/source/engine/yugine.c index 6b7d570..db52974 100644 --- a/source/engine/yugine.c +++ b/source/engine/yugine.c @@ -190,6 +190,22 @@ int main(int argc, char **args) { engine_init(); + int argsize = 0; + for (int i = 1; i < argc; i++) { + argsize += strlen(args[i]); + if (argc > i+1) argsize++; + } + + char cmdstr[argsize]; + cmdstr[0] = '\0'; + + for (int i = 0; i < argc; i++) { + strcat(cmdstr, args[i]); + if (argc > i+1) strcat(cmdstr, " "); + } + + script_evalf("cmd_args('%s');", cmdstr); + const GLFWvidmode *vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor()); YughInfo("Refresh rate is %d", vidmode->refreshRate); @@ -208,23 +224,6 @@ int main(int argc, char **args) { input_init(); openglInit(); - int argsize = 0; - for (int i = 1; i < argc; i++) { - argsize += strlen(args[i]); - if (argc > i+1) argsize++; - } - - char cmdstr[argsize]; - cmdstr[0] = '\0'; - - YughWarn("num is %d", argc); - - for (int i = 0; i < argc; i++) { - strcat(cmdstr, args[i]); - if (argc > i+1) strcat(cmdstr, " "); - } - - script_evalf("cmd_args('%s');", cmdstr); while (!want_quit()) { double elapsed = glfwGetTime() - lastTick; diff --git a/source/scripts/components.js b/source/scripts/components.js index c8ef3b9..db6dad7 100644 --- a/source/scripts/components.js +++ b/source/scripts/components.js @@ -228,18 +228,6 @@ var collider2d = clone(component, { name: "collider 2d", sensor: false, - input_s_pressed() { - if (!Keys.alt()) return; - - this.sensor = !this.sensor; - }, - - input_t_pressed() { - if (!Keys.alt()) return; - - this.enabled = !this.enabled; - }, - kill() {}, /* No killing is necessary - it is done through the gameobject's kill */ register_hit(fn, obj) { @@ -255,6 +243,13 @@ var collider2d = clone(component, { }); +collider2d.inputs = {}; +collider2d.inputs['M-s'] = function() { this.sensor = !this.sensor; } +collider2d.inputs['M-s'].doc = "Toggle if this collider is a sensor."; + +collider2d.inputs['M-t'] = function() { this.enabled = !this.enabled; } +collider2d.inputs['M-t'].doc = "Toggle if this collider is enabled."; + var sync_proxy = { set(t,p,v) { t[p] = v; @@ -266,8 +261,8 @@ var sync_proxy = { var polygon2d = clone(collider2d, { name: "polygon 2d", points: [], - mirrorx: false, - mirrory: false, + flipx: false, + flipy: false, clone(spec) { var obj = Object.create(this); @@ -304,24 +299,10 @@ var polygon2d = clone(collider2d, { }, /* EDITOR */ - help: "Ctrl-click Add a point\nShift-click Remove a point", - - input_f10_pressed() { - this.points = sortpointsccw(this.points); - }, - - input_b_pressed() { - if (!Keys.ctrl()) return; - - this.points = this.spoints; - this.mirrorx = false; - this.mirrory = false; - }, - get spoints() { var spoints = this.points.slice(); - if (this.mirrorx) { + if (this.flipx) { spoints.forEach(function(x) { var newpoint = x.slice(); newpoint.x = -newpoint.x; @@ -329,7 +310,7 @@ var polygon2d = clone(collider2d, { }); } - if (this.mirrory) { + if (this.flipy) { spoints.forEach(function(x) { var newpoint = x.slice(); newpoint.y = -newpoint.y; @@ -351,16 +332,6 @@ var polygon2d = clone(collider2d, { Debug.numbered_point(this.gameobject.this2world(x), i); }, this); }, - - input_lmouse_pressed() { - if (Keys.ctrl()) { - this.points.push(this.gameobject.world2this(Mouse.worldpos)); - } else if (Keys.shift()) { - var idx = grab_from_points(screen2world(Mouse.pos), this.points.map(this.gameobject.this2world,this.gameobject), 25); - if (idx === -1) return; - this.points.splice(idx, 1); - } - }, pick(pos) { return Gizmos.pick_gameobject_points(pos, this.gameobject, this.points); @@ -369,15 +340,33 @@ var polygon2d = clone(collider2d, { query() { return cmd(80, this.shape); }, - - input_m_pressed() { - if (Keys.ctrl()) - this.mirrory = !this.mirrory; - else - this.mirrorx = !this.mirrorx; - }, }); +polygon2d.inputs = {}; +polygon2d.inputs.f10 = function() { + this.points = sortpointsccw(this.points); +}; +polygon2d.inputs.f10.doc = "Sort all points to be CCW order."; + +polygon2d.inputs['C-lm'] = function() { + this.points.push(this.gameobject.world2this(Mouse.worldpos)); +}; +polygon2d.inputs['C-lm'].doc = "Add a point to location of mouse."; + +polygon2d.inputs['S-lm'] = function() { + var idx = grab_from_points(screen2world(Mouse.pos), this.points.map(this.gameobject.this2world,this.gameobject), 25); + if (idx === -1) return; + this.points.splice(idx, 1); +}; +polygon2d.inputs['S-lm'].doc = "Remove point under mouse."; + +polygon2d.inputs['C-b'] = function() { + this.points = this.spoints; + this.flipx = false; + this.flipy = false; +}; +polygon2d.inputs['C-b'].doc = "Freeze mirroring in place."; + var bucket = clone(collider2d, { name: "bucket", clone(spec) { @@ -403,8 +392,8 @@ var bucket = clone(collider2d, { looped: 3 }, - mirrorx: false, - mirrory: false, + flipx: false, + flipy: false, hollow: false, hollowt: 0, @@ -412,7 +401,7 @@ var bucket = clone(collider2d, { get spoints() { var spoints = this.cpoints.slice(); - if (this.mirrorx) { + if (this.flipx) { for (var i = spoints.length-1; i >= 0; i--) { var newpoint = spoints[i].slice(); newpoint.x = -newpoint.x; @@ -420,7 +409,7 @@ var bucket = clone(collider2d, { } } - if (this.mirrory) { + if (this.flipy) { for (var i = spoints.length-1; i >= 0; i--) { var newpoint = spoints[i].slice(); newpoint.y = -newpoint.y; @@ -521,139 +510,126 @@ var bucket = clone(collider2d, { }, this); }, - help: "Ctrl-click Add a point\nShift-click Remove a point\n+,- Increase/decrease spline segs\nCtrl-+,- Inc/dec spline degrees\nCtrl-b,v Inc/dec spline thickness", - - input_h_pressed() { - this.hollow = !this.hollow; - }, - - input_m_pressed() { - if (Keys.ctrl()) { - this.mirrory = !this.mirrory; - } else { - this.mirrorx = !this.mirrorx; - } - }, - - input_g_pressed() { - if (!Keys.ctrl()) return; - this.hollowt--; - if (this.hollowt < 0) this.hollowt = 0; - }, - - input_f_pressed() { - if (!Keys.ctrl()) return; - this.hollowt++; - }, - - input_v_pressrep() { - if (!Keys.alt()) return; - this.thickness--; - }, - - input_b_pressrep() { - if (Keys.alt()) { - this.thickness++; - } else if (Keys.ctrl()) { - this.cpoints = this.spoints; - this.mirrorx = false; - this.mirrory = false; - } - }, - finish_center(change) { this.cpoints = this.cpoints.map(function(x) { return x.sub(change); }); }, - input_plus_pressrep() { - if (Keys.ctrl()) - this.degrees++; - else - this.samples += 1; - }, - - input_minus_pressrep() { - if (Keys.ctrl()) - this.degrees--; - else { - this.samples -= 1; - if (this.samples < 1) this.samples = 1; - } - }, - - input_r_pressed() { - if (!Keys.ctrl()) return; - - this.cpoints = this.cpoints.reverse(); - }, - - input_l_pressed() { - if (!Keys.ctrl()) return; - this.type = 3; - }, - - input_c_pressed() { - if (!Keys.ctrl()) return; - this.type = 1; - }, - - input_o_pressed() { - if (!Keys.ctrl()) return; - this.type = 0; - }, - - input_lmouse_pressed() { - if (Keys.ctrl()) { - if (Keys.alt()) { - var idx = grab_from_points(Mouse.worldpos, this.cpoints.map(this.gameobject.world2this,this.gameobject), 25); - if (idx === -1) return; - - this.cpoints = this.cpoints.newfirst(idx); - return; - } - var idx = 0; - - if (this.cpoints.length >= 2) { - idx = cmd(59, screen2world(Mouse.pos).sub(this.gameobject.pos), this.cpoints, 1000); - if (idx === -1) return; - } - - if (idx === this.cpoints.length) - this.cpoints.push(this.gameobject.world2this(screen2world(Mouse.pos))); - else - this.cpoints.splice(idx, 0, this.gameobject.world2this(screen2world(Mouse.pos))); - return; - } else if (Keys.shift()) { - var idx = grab_from_points(screen2world(Mouse.pos), this.cpoints.map(function(x) {return x.add(this.gameobject.pos); }, this), 25); - if (idx === -1) return; - - this.cpoints.splice(idx, 1); - } - }, - pick(pos) { return Gizmos.pick_gameobject_points(pos, this.gameobject, this.cpoints); }, - - input_lbracket_pressrep() { - var np = []; - - this.cpoints.forEach(function(c) { - np.push(Vector.rotate(c, Math.deg2rad(-1))); - }); - - this.cpoints = np; - }, - - input_rbracket_pressrep() { - var np = []; - - this.cpoints.forEach(function(c) { - np.push(Vector.rotate(c, Math.deg2rad(1))); - }); - - this.cpoints = np; - }, }); +bucket.inputs = {}; +bucket.inputs.h = function() { this.hollow = !this.hollow; }; +bucket.inputs.h.doc = "Toggle hollow."; + +bucket.inputs['C-g'] = function() { + this.hollowt--; + if (this.hollowt < 0) this.hollowt = 0; +}; +bucket.inputs['C-g'].doc = "Thin the hollow thickness."; + +bucket.inputs['C-f'] = function() { this.hollowt++; }; +bucket.inputs['C-f'].doc = "Increase the hollow thickness."; + +bucket.inputs['M-v'] = function() { this.thickness--; }; +bucket.inputs['M-v'].doc = "Decrease spline thickness."; +bucket.inputs['M-v'].rep = true; + +bucket.inputs['C-b'] = function() { + this.cpoints = this.spoints; + this.flipx = false; + this.flipy = false; +}; +bucket.inputs['C-b'].doc = "Freeze mirroring,"; +bucket.inputs['M-b'] = function() { this.thickness++; }; +bucket.inputs['M-b'].doc = "Increase spline thickness."; +bucket.inputs['M-b'].rep = true; + +bucket.inputs['C-plus'] = function() { this.degrees++; }; +bucket.inputs['C-plus'].doc = "Increase the degrees of this spline."; +bucket.inputs['C-plus'].rep = true; + +bucket.inputs.plus = function() { this.samples++; }; +bucket.inputs.plus.doc = "Increase the number of samples of this spline."; +bucket.inputs.plus.rep = true; + +bucket.inputs.minus = function() { + this.samples--; + if (this.samples < 1) this.samples = 1; +}; +bucket.inputs.minus.doc = "Decrease the number of samples on this spline."; +bucket.inputs.minus.rep = true; + +bucket.inputs['C-minus'] = function() { this.degrees--; }; +bucket.inputs['C-minus'].doc = "Decrease the number of degrees of this spline."; +bucket.inputs['C-minus'].rep = true; + +bucket.inputs['C-r'] = function() { this.cpoints = this.cpoints.reverse(); }; +bucket.inputs['C-r'].doc = "Reverse the order of the spline's points."; + +bucket.inputs['C-l'] = function() { this.type = 3; }; +bucket.inputs['C-l'].doc = "Set type of spline to clamped."; + +bucket.inputs['C-c'] = function() { this.type = 1; }; +bucket.inputs['C-c'].doc = "Set type of spline to closed."; + +bucket.inputs['C-o'] = function() { this.type = 0; }; +bucket.inputs['C-o'].doc = "Set spline to open."; + +bucket.inputs['C-M-lm'] = function() { + var idx = grab_from_points(Mouse.worldpos, this.cpoints.map(this.gameobject.world2this,this.gameobject), 25); + if (idx === -1) return; + + this.cpoints = this.cpoints.newfirst(idx); +}; +bucket.inputs['C-M-lm'].doc = "Select the given point as the '0' of this spline."; + +bucket.inputs['C-lm'] = function() { + var idx = 0; + + if (this.cpoints.length >= 2) { + idx = cmd(59, screen2world(Mouse.pos).sub(this.gameobject.pos), this.cpoints, 1000); + if (idx === -1) return; + } + + if (idx === this.cpoints.length) + this.cpoints.push(this.gameobject.world2this(screen2world(Mouse.pos))); + else + this.cpoints.splice(idx, 0, this.gameobject.world2this(screen2world(Mouse.pos))); +}; +bucket.inputs['C-lm'].doc = "Add a point to the spline at the mouse position."; + +bucket.inputs['S-lm'] = function() { + var idx = grab_from_points(screen2world(Mouse.pos), this.cpoints.map(function(x) {return x.add(this.gameobject.pos); }, this), 25); + if (idx === -1) return; + + this.cpoints.splice(idx, 1); +}; +bucket.inputs['S-lm'].doc = "Remove point from the spline."; + +bucket.inputs.lb = function() { + var np = []; + + this.cpoints.forEach(function(c) { + np.push(Vector.rotate(c, Math.deg2rad(-1))); + }); + + this.cpoints = np; +}; +bucket.inputs.lb.doc = "Rotate the points CCW."; +bucket.inputs.lb.rep = true; + +bucket.inputs.rb = function() { + var np = []; + + this.cpoints.forEach(function(c) { + np.push(Vector.rotate(c, Math.deg2rad(1))); + }); + + this.cpoints = np; +}; +bucket.inputs.rb.doc = "Rotate the points CW."; +bucket.inputs.rb.rep = true; + var circle2d = clone(collider2d, { name: "circle 2d", radius: 10, diff --git a/source/scripts/editor.js b/source/scripts/editor.js index 6c5c137..caaae09 100644 --- a/source/scripts/editor.js +++ b/source/scripts/editor.js @@ -41,49 +41,6 @@ var editor = { cursor: null, edit_mode: "basic", - input_f1_pressed() { - if (Keys.ctrl()) { - this.edit_mode = "basic"; - return; - } - }, - - input_f2_pressed() { - if (Keys.ctrl()) { - this.edit_mode = "brush"; - return; - } - - objectexplorer.on_close = save_configs; - objectexplorer.obj = configs; - this.openpanel(objectexplorer); - }, - - input_j_pressed() { - if (Keys.alt()) { - var varmakes = this.selectlist.filter(function(x) { return x.hasOwn('varname'); }); - varmakes.forEach(function(x) { delete x.varname; }); - } else if (Keys.ctrl()) { - var varmakes = this.selectlist.filter(function(x) { return !x.hasOwn('varname'); }); - varmakes.forEach(function(x) { - var allvnames = []; - this.edit_level.objects.forEach(function(x) { - if (x.varname) - allvnames.push(x.varname); - }); - - var vname = x.from.replace(/ /g, '_').replace(/_object/g, '').replace(/\..*$/g, ''); - var tnum = 1; - var testname = vname + "_" + tnum; - while (allvnames.includes(testname)) { - tnum++; - testname = vname + "_" + tnum; - } - x.varname = testname; - },this); - } - }, - try_select() { /* nullify true if it should set selected to null if it doesn't find an object */ var go = physics.pos_query(screen2world(Mouse.pos)); return this.do_select(go); @@ -237,22 +194,6 @@ var editor = { sel_start: [], - input_lmouse_pressed() { - if (this.sel_comp) return; - - if (this.edit_mode === "brush") { - this.paste(); - return; - } - - if (this.selectlist.length === 1 && Keys.ctrl() && Keys.shift() && Keys.alt()) { - this.selectlist[0].set_center(screen2world(Mouse.pos)); - return; - } - - this.sel_start = screen2world(Mouse.pos); - }, - points2cwh(start, end) { var c = []; c[0] = (end[0] - start[0]) / 2; @@ -339,7 +280,6 @@ var editor = { this.edit_level.check_dirty(); }, - step_amt() { return Keys.shift() ? 10 : 1; }, on_grid(pos) { @@ -412,11 +352,6 @@ var editor = { } }, - input_delete_pressed() { - this.selectlist.forEach(x => x.kill()); - this.unselect(); - }, - unselect() { this.selectlist = []; this.grabselect = null; @@ -424,36 +359,8 @@ var editor = { }, sel_comp: null, - - input_u_pressed() { - if (Keys.ctrl()) { - this.selectlist.forEach(function(x) { - x.revert(); - }); - } - - if (Keys.alt()) { - this.selectlist.forEach(function(x) { - x.unique = true; - }); - } - }, - comp_info: false, - brush_obj: null, - - input_b_pressed() { - if (this.sel_comp) return; - if (this.brush_obj) { - this.brush_obj = null; - return; - } - - if (this.selectlist.length !== 1) return; - this.brush_obj = this.selectlist[0]; - this.unselect(); - }, camera_recalls: {}, @@ -629,36 +536,15 @@ var editor = { moveoffsets: [], - input_g_pressed() { - if (Keys.ctrl() && Keys.shift()) { - Log.info("Saving as level..."); - this.openpanel(groupsaveaspanel); - return; - } - - if (Keys.alt() && this.cursor) { - var com = find_com(this.selectlist); - this.selectlist.forEach(function(x) { - x.pos = x.pos.sub(com).add(this.cursor); - },this); - } - + // TODO: Unify so this works +/* input_g_pressed() { if (this.sel_comp) { if ('pos' in this.sel_comp) this.moveoffset = this.sel_comp.pos.sub(screen2world(Mouse.pos)); - return; } - - if (Keys.ctrl()) { - this.selectlist = this.dup_objects(this.selectlist); - } - - this.selectlist.forEach(function(x,i) { - this.moveoffsets[i] = x.pos.sub(screen2world(Mouse.pos)); - }, this); }, - +*/ input_g_down() { if (Keys.alt()) return; if (this.sel_comp) { @@ -673,10 +559,6 @@ var editor = { }, this); }, - input_g_released() { - this.moveoffsets = []; - }, - scaleoffset: 0, startscales: [], selected_com: [0,0], @@ -911,28 +793,9 @@ var editor = { } }, - input_tab_pressed() { - if (!this.selectlist.length === 1) return; - if (!this.selectlist[0].components) return; - - var sel = this.selectlist[0].components; - - if (!this.sel_comp) - this.sel_comp = sel.nth(0); - else { - var idx = sel.findIndex(this.sel_comp) + 1; - if (idx >= Object.keys(sel).length) - this.sel_comp = null; - else - this.sel_comp = sel.nth(idx); - } - - }, - time: 0, ed_gui() { - this.time = Date.now(); /* Clean out killed objects */ this.selectlist = this.selectlist.filter(function(x) { return x.alive; }); @@ -958,8 +821,8 @@ var editor = { }); } - if (this.comp_info && this.sel_comp && 'help' in this.sel_comp) { - GUI.text(this.sel_comp.help, [100,700],1); + if (this.comp_info && this.sel_comp) { + GUI.text(Input.print_pawn_kbm(this.sel_comp), [100,700],1); } GUI.text("0,0", world2screen([0,0])); @@ -1084,22 +947,6 @@ var editor = { }, - input_lbracket_pressed() { - if (!Keys.ctrl()) return; - editor_config.grid_size -= Keys.shift() ? 10 : 1; - if (editor_config.grid_size <= 0) editor_config.grid_size = 1; - }, - input_lbracket_rep() { this.input_lbracket_pressed(); }, - - input_rbracket_pressed() { - if (!Keys.ctrl()) return; - editor_config.grid_size += Keys.shift() ? 10 : 1; - }, - - input_rbracket_rep() { this.input_rbracket_pressed(); }, - - grid_size: 100, - ed_debug() { if (!Debug.phys_drawing) this.selectlist.forEach(function(x) { Debug.draw_obj_phys(x); }); @@ -1119,26 +966,6 @@ var editor = { killring: [], killcom: [], - input_c_pressed() { - if (this.sel_comp) return; - if (!Keys.ctrl()) return; - this.killring = []; - this.killcom = []; - - this.selectlist.forEach(function(x) { - this.killring.push(x); - },this); - - this.killcom = find_com(this.killring); - }, - - input_x_pressed() { - if (!Keys.ctrl()) return; - - this.input_c_pressed(); - this.killring.forEach(function(x) { x.kill(); }); - }, - paste() { this.selectlist = this.dup_objects(this.killring); @@ -1148,11 +975,6 @@ var editor = { },this); }, - input_v_pressed() { - if (!Keys.ctrl()) return; - this.paste(); - }, - lvl_history: [], load(file) { @@ -1241,8 +1063,8 @@ editor.inputs['C-a'] = function() { }; editor.inputs['C-a'].doc = "Select all objects."; -editor.inputs['backtick'] = function() { editor.repl = !editor.repl; }; -editor.inputs['backtick'].doc = "Open or close the repl."; +editor.inputs['`'] = function() { editor.repl = !editor.repl; }; +editor.inputs['`'].doc = "Open or close the repl."; /* Return if selected component. */ editor.inputs['h'] = function() { @@ -1293,11 +1115,27 @@ editor.inputs['C-d'] = function() { editor.inputs['C-d'].doc = "Duplicate all selected objects."; editor.inputs['C-m'] = function() { + if (editor.sel_comp) { + if (editor.sel_comp.flipy) + editor.sel_comp.flipy = !editor.sel_comp.flipy; + + return; + } + editor.selectlist.forEach(function(x) { x.flipy = !x.flipy; }); }; editor.inputs['C-m'].doc = "Mirror selected objects on the Y axis."; -editor.inputs.m = function() { editor.selectlist.forEach(function(x) { x.flipx = !x.flipx; }); }; +editor.inputs.m = function() { + if (editor.sel_comp) { + if (editor.sel_comp.flipx) + editor.sel_comp.flipx = !editor.sel_comp.flipx; + + return; + } + + editor.selectlist.forEach(function(x) { x.flipx = !x.flipx; }); +}; editor.inputs.m.doc = "Mirror selected objects on the X axis."; editor.inputs.q = function() { editor.comp_info = !editor.comp_info; }; @@ -1383,8 +1221,6 @@ editor.inputs.f7.doc = "Start game from the beginning."; editor.inputs.escape = function() { editor.openpanel(quitpanel); } editor.inputs.escape.doc = "Quit editor."; -editor.inputs.f12 = function() { Log.warn("Editor F12 pressed."); }; - editor.inputs['C-s'] = function() { if (editor.edit_level.level) { if (!editor.edit_level.unique) @@ -1515,6 +1351,169 @@ editor.inputs.plus = function() { editor.inputs.plus.doc = "Go up one working layer, or, move selected objects down one layer."; +editor.inputs['C-f1'] = function() { editor.edit_mode = "basic"; }; +editor.inputs['C-f1'].doc = "Enter basic edit mode."; +editor.inputs['C-f2'] = function() { editor.edit_mode = "brush"; }; +editor.inputs['C-f2'].doc = "Enter brush mode."; + +editor.inputs.f2 = function() { + objectexplorer.on_close = save_configs; + objectexplorer.obj = configs; + this.openpanel(objectexplorer); +}; +editor.inputs.f2.doc = "Open configurations object."; + +editor.inputs['C-j'] = function() { + var varmakes = this.selectlist.filter(function(x) { return !x.hasOwn('varname'); }); + varmakes.forEach(function(x) { + var allvnames = []; + this.edit_level.objects.forEach(function(x) { + if (x.varname) + allvnames.push(x.varname); + }); + + var vname = x.from.replace(/ /g, '_').replace(/_object/g, '').replace(/\..*$/g, ''); + var tnum = 1; + var testname = vname + "_" + tnum; + while (allvnames.includes(testname)) { + tnum++; + testname = vname + "_" + tnum; + } + x.varname = testname; + },this); +}; +editor.inputs['C-j'].doc = "Give selected objects a variable name."; + +editor.inputs['M-j'] = function() { + var varmakes = this.selectlist.filter(function(x) { return x.hasOwn('varname'); }); + varmakes.forEach(function(x) { delete x.varname; }); +}; +editor.inputs['M-j'].doc = "Remove variable names from selected objects."; + +editor.inputs.lm = function() { editor.sel_start = screen2world(Mouse.pos); }; +editor.inputs.lm.doc = "Selection box."; + +editor.inputs['C-M-S-lm'] = function() { editor.selectlist[0].set_center(screen2world(Mouse.pos)); }; +editor.inputs['C-M-S-lm'].doc = "Set world center to mouse position."; + +editor.inputs.delete = function() { + this.selectlist.forEach(x => x.kill()); + this.unselect(); +}; +editor.inputs.delete.doc = "Delete selected objects."; + +editor.inputs['C-u'] = function() { + this.selectlist.forEach(function(x) { + x.revert(); + }); +}; +editor.inputs['C-u'].doc = "Revert selected objects back to their prefab form."; + +editor.inputs['M-u'] = function() { + this.selectlist.forEach(function(x) { + x.unique = true; + }); +}; +editor.inputs['M-u'].doc = "Make selected objects unique."; + +editor.inputs['C-S-g'] = function() { editor.openpanel(groupsaveaspanel); }; +editor.inputs['C-S-g'].doc = "Save selected objects as a new level."; + +editor.inputs.g = function() { + this.selectlist.forEach(function(x,i) { + this.moveoffsets[i] = x.pos.sub(screen2world(Mouse.pos)); + }, this); +}; +editor.inputs.g.doc = "Move selected objects."; +editor.inputs.g.released = function() { editor.moveoffsets = []; }; + +editor.inputs.tab = function() { + if (!this.selectlist.length === 1) return; + if (!this.selectlist[0].components) return; + + var sel = this.selectlist[0].components; + + if (!this.sel_comp) + this.sel_comp = sel.nth(0); + else { + var idx = sel.findIndex(this.sel_comp) + 1; + if (idx >= Object.keys(sel).length) + this.sel_comp = null; + else + this.sel_comp = sel.nth(idx); + } +}; +editor.inputs.tab.doc = "Cycle through selected object's components."; + +editor.inputs['C-g'] = function() { + this.selectlist = this.dup_objects(this.selectlist); + editor.inputs.g(); +}; +editor.inputs['C-g'].doc = "Duplicate selected objects, then move them."; + +editor.inputs['C-lb'] = function() { + editor_config.grid_size -= Keys.shift() ? 10 : 1; + if (editor_config.grid_size <= 0) editor_config.grid_size = 1; +}; +editor.inputs['C-lb'].doc = "Decrease grid size. Hold shift to decrease it more."; +editor.inputs['C-lb'].rep = true; + +editor.inputs['C-rb'] = function() { editor_config.grid_size += Keys.shift() ? 10 : 1; }; +editor.inputs['C-rb'].doc = "Increase grid size. Hold shift to increase it more."; +editor.inputs['C-rb'].rep = true; + +editor.inputs['C-c'] = function() { + this.killring = []; + this.killcom = []; + + this.selectlist.forEach(function(x) { + this.killring.push(x); + },this); + + this.killcom = find_com(this.killring); +}; +editor.inputs['C-c'].doc = "Copy selected objects to killring."; + +editor.inputs['C-x'] = function() { + editor.inputs['C-c'](); + this.killring.forEach(function(x) { x.kill(); }); +}; +editor.inputs['C-x'].doc = "Cut objects to killring."; + +editor.inputs['C-v'] = function() { editor.paste(); }; +editor.inputs['C-v'].doc = "Pull objects from killring to world."; + +editor.inputs['M-g'] = function() { + if (this.cursor) return; + var com = find_com(this.selectlist); + this.selectlist.forEach(function(x) { + x.pos = x.pos.sub(com).add(this.cursor); + },this); +}; +editor.inputs['M-g'].doc = "Set cursor to the center of selected objects."; + +var brushmode = {}; +brushmode.inputs = {}; +brushmode.inputs.lm = function() { editor.paste(); }; +brushmode.inputs.lm.doc = "Paste selected brush."; + +brushmode.inputs.b = function() { + if (editor.brush_obj) { + editor.brush_obj = null; + return; + } + + if (editor.selectlist.length !== 1) return; + editor.brush_obj = editor.seliectlist[0]; + editor.unselect(); +}; +brushmode.inputs.b.doc = "Clear brush, or set a new one."; + +var compmode = {}; +compmode.inputs = {}; +compmode.inputs['C-c'] = function() {}; /* Simply a blocker */ +compmode.inputs['C-x'] = function() {}; + editor.inputs.s = function() { var offf = editor.cursor ? editor.cursor : editor.selected_com; editor.scaleoffset = Vector.length(Mouse.worldpos.sub(offf)); @@ -1699,35 +1698,10 @@ var texteditor = clone(inputpanel, { this.cursor = this.cursor; }, - input_s_pressed() { - if (!Keys.ctrl()) return; - Log.info("SAVING"); - editor.save_current(); - }, - - input_u_pressrep() { - if (!Keys.ctrl()) return; - this.popstate(); - }, - copy(start, end) { return this.value.slice(start,end); }, - input_q_pressed() { - if (!Keys.ctrl()) return; - - var ws = this.prev_word(this.cursor); - var we = this.end_of_word(this.cursor)+1; - var find = this.copy(ws, we); - var obj = editor.edit_level.varname2obj(find); - - if (obj) { - editor.unselect(); - editor.selectlist.push(obj); - } - }, - delete_line(p) { var ls = this.line_start(p); var le = this.line_end(p)+1; @@ -1745,20 +1719,6 @@ var texteditor = clone(inputpanel, { return false; }, - input_o_pressed() { - if (Keys.alt()) { - /* Delete all surrounding blank lines */ - while (this.line_blank(this.next_line(this.cursor))) - this.delete_line(this.next_line(this.cursor)); - - while (this.line_blank(this.prev_line(this.cursor))) - this.delete_line(this.prev_line(this.cursor)); - } else if (Keys.ctrl()) { - this.insert_char('\n'); - this.cursor--; - } - }, - get_line() { var line = 0; for (var i = 0; i < this.cursor; i++) @@ -1802,31 +1762,11 @@ var texteditor = clone(inputpanel, { this.keycb(); }, - input_d_pressrep() { - if (Keys.ctrl()) - this.value = this.value.slice(0,this.cursor) + this.value.slice(this.cursor+1); - else if (Keys.alt()) - this.cut_span(this.cursor, this.end_of_word(this.cursor)+1); - }, - input_backspace_pressrep() { this.value = this.value.slice(0,this.cursor-1) + this.value.slice(this.cursor); this.cursor--; }, - input_a_pressed() { - if (Keys.ctrl()) { - this.to_line_start(); - this.desired_inset = this.inset; - } - }, - - input_y_pressed() { - if (!Keys.ctrl()) return; - if (this.killring.length === 0) return; - this.insert_char(this.killring.pop()); - }, - line_starting_whitespace(p) { var white = 0; var l = this.line_start(p); @@ -1839,48 +1779,6 @@ var texteditor = clone(inputpanel, { return white; }, - input_e_pressed() { - if (Keys.ctrl()) { - this.to_line_end(); - this.desired_inset = this.inset; - } - }, - - input_k_pressrep() { - if (Keys.ctrl()) { - if (this.cursor === this.value.length-1) return; - var killamt = this.value.next('\n', this.cursor) - this.cursor; - var killed = this.cut_span(this.cursor-1, this.cursor+killamt); - this.killring.push(killed); - } else if (Keys.alt()) { - var prevn = this.value.prev('\n', this.cursor); - var killamt = this.cursor - prevn; - var killed = this.cut_span(prevn+1, prevn+killamt); - this.killring.push(killed); - this.to_line_start(); - } - }, - - input_b_pressrep() { - if (Keys.ctrl()) { - this.cursor--; - } else if (Keys.alt()) { - this.cursor = this.prev_word(this.cursor-2); - } - - this.desired_inset = this.inset; - }, - - input_f_pressrep() { - if (Keys.ctrl()) { - this.cursor++; - } else if (Keys.alt()) { - this.cursor = this.next_word(this.cursor); - } - - this.desired_inset = this.inset; - }, - cut_span(start, end) { if (end < start) return; this.savestate(); @@ -1957,46 +1855,152 @@ var texteditor = clone(inputpanel, { to_file_start() { this.cursor = 0; }, desired_inset: 0, - - input_p_pressrep() { - if (Keys.ctrl()) { - if (this.cursor === 0) return; - this.desired_inset = Math.max(this.desired_inset, this.inset); - this.cursor = this.prev_line(this.cursor); - var newlinew = this.line_width(this.cursor); - this.cursor += Math.min(this.desired_inset, newlinew); - } else if (Keys.alt()) { - while (this.line_blank(this.cursor)) - this.cursor = this.prev_line(this.cursor); - - while (!this.line_blank(this.cursor)) - this.cursor = this.prev_line(this.cursor); - } - }, - - input_n_pressrep() { - if (Keys.ctrl()) { - if (this.cursor === this.value.length-1) return; - if (this.value.next('\n', this.cursor) === -1) { - this.to_file_end(); - return; - } - - this.desired_inset = Math.max(this.desired_inset, this.inset); - this.cursor = this.next_line(this.cursor); - var newlinew = this.line_width(this.cursor); - this.cursor += Math.min(this.desired_inset, newlinew); - } else if (Keys.alt()) { - while (this.line_blank(this.cursor)) - this.cursor = this.next_line(this.cursor); - - while (!this.line_blank(this.cursor)) - this.cursor = this.next_line(this.cursor); - } - }, - }); +texteditor.inputs = {}; +texteditor.inputs['C-s'] = function() { editor.save_current(); }; +texteditor.inputs['C-s'].doc = "Save script to file."; + +texteditor.inputs['C-u'] = function() { this.popstate(); }; +texteditor.inputs['C-u'].doc = "Undo."; + +texteditor.inputs['C-q'] = function() { + var ws = this.prev_word(this.cursor); + var we = this.end_of_word(this.cursor)+1; + var find = this.copy(ws, we); + var obj = editor.edit_level.varname2obj(find); + + if (obj) { + editor.unselect(); + editor.selectlist.push(obj); + } +}; +texteditor.inputs['C-q'].doc = "Select object of selected word."; + +texteditor.inputs['C-o'] = function() { + this.insert_char('\n'); + this.cursor--; +}; +texteditor.inputs['C-o'].doc = "Insert newline."; +texteditor.inputs['C-o'].rep = true; + +texteditor.inputs['M-o'] = function() { + while (this.line_blank(this.next_line(this.cursor))) + this.delete_line(this.next_line(this.cursor)); + + while (this.line_blank(this.prev_line(this.cursor))) + this.delete_line(this.prev_line(this.cursor)); +}; +texteditor.inputs['M-o'].doc = "Delete surround blank lines."; + +texteditor.inputs['C-d'] = function () { this.value = this.value.slice(0,this.cursor) + this.value.slice(this.cursor+1); }; +texteditor.inputs['C-d'].doc = "Delete character."; + +texteditor.inputs['M-d'] = function() { this.cut_span(this.cursor, this.end_of_word(this.cursor)+1); }; +texteditor.inputs['M-d'].doc = "Delete word."; + +texteditor.inputs['C-a'] = function() { + this.to_line_start(); + this.desired_inset = this.inset; +}; +texteditor.inputs['C-a'].doc = "To start of line."; + +texteditor.inputs['C-y'] = function() { + if (this.killring.length === 0) return; + this.insert_char(this.killring.pop()); +}; +texteditor.inputs['C-y'].doc = "Insert from killring."; + +texteditor.inputs['C-e'] = function() { + this.to_line_end(); + this.desired_inset = this.inset; +}; +texteditor.inputs['C-e'].doc = "To line end."; + +texteditor.inputs['C-k'] = function() { + if (this.cursor === this.value.length-1) return; + var killamt = this.value.next('\n', this.cursor) - this.cursor; + var killed = this.cut_span(this.cursor-1, this.cursor+killamt); + this.killring.push(killed); +}; +texteditor.inputs['C-k'].doc = "Kill from cursor to end of line."; + +texteditor.inputs['M-k'] = function() { + var prevn = this.value.prev('\n', this.cursor); + var killamt = this.cursor - prevn; + var killed = this.cut_span(prevn+1, prevn+killamt); + this.killring.push(killed); + this.to_line_start(); +}; +texteditor.inputs['M-k'].doc = "Kill entire line the cursor is on."; + +texteditor.inputs['C-b'] = function() { + this.cursor--; + this.desired_inset = this.inset; +}; +texteditor.inputs['C-b'].rep = true; +texteditor.inputs['M-b'] = function() { + this.cursor = this.prev_word(this.cursor-2); + this.desired_inset = this.inset; +}; +texteditor.inputs['M-b'].rep = true; + +texteditor.inputs['C-f'] = function() { + this.cursor++; + this.desired_inset = this.inset; +}; +texteditor.inputs['C-f'].rep = true; +texteditor.inputs['M-f'] = function() { + this.cursor = this.next_word(this.cursor); + this.desired_inset = this.inset; +}; +texteditor.inputs['M-f'].rep = true; + +texteditor.inputs['C-p'] = function() { + if (this.cursor === 0) return; + this.desired_inset = Math.max(this.desired_inset, this.inset); + this.cursor = this.prev_line(this.cursor); + var newlinew = this.line_width(this.cursor); + this.cursor += Math.min(this.desired_inset, newlinew); +}; +texteditor.inputs['C-p'].rep = true; + +texteditor.inputs['M-p'] = function() { + while (this.line_blank(this.cursor)) + this.cursor = this.prev_line(this.cursor); + + while (!this.line_blank(this.cursor)) + this.cursor = this.prev_line(this.cursor); +}; +texteditor.inputs['M-p'].doc = "Go up to next line with text on it."; +texteditor.inputs['M-p'].rep = true; + +texteditor.inputs['C-n'] = function() { + if (this.cursor === this.value.length-1) return; + if (this.value.next('\n', this.cursor) === -1) { + this.to_file_end(); + return; + } + + this.desired_inset = Math.max(this.desired_inset, this.inset); + this.cursor = this.next_line(this.cursor); + var newlinew = this.line_width(this.cursor); + this.cursor += Math.min(this.desired_inset, newlinew); +}; +texteditor.inputs['C-n'].rep = true; + +texteditor.inputs['M-n'] = function() { + while (this.line_blank(this.cursor)) + this.cursor = this.next_line(this.cursor); + + while (!this.line_blank(this.cursor)) + this.cursor = this.next_line(this.cursor); +}; +texteditor.inputs['M-n'].doc = "Go down to next line with text on it."; +texteditor.inputs['M-n'].rep = true; + + + var protoexplorer = copy(inputpanel, { title: "prototype explorer", waitclose:false, diff --git a/source/scripts/engine.js b/source/scripts/engine.js index d70b788..4a9200e 100644 --- a/source/scripts/engine.js +++ b/source/scripts/engine.js @@ -32,8 +32,12 @@ function cmd_args(cmdargs) continue; var c = Cmdline.cmds.find(function(cmd) { return cmd.flag === cmds[i].slice(1); }); - if (c && c.fn) - c.fn(); + if (c && c.fn) { + if (cmds[i+1] && cmds[i+1][0] !== '-') + c.fn(cmds[i+1]); + else + c.fn(); + } } if (Cmdline.play) @@ -43,10 +47,19 @@ function cmd_args(cmdargs) } Cmdline.register_cmd("p", function() { Cmdline.play = true; }, "Launch engine in play mode."); -Cmdline.register_cmd("v", function() { Log.warn(cmd(120)); }, "Display engine info."); +Cmdline.register_cmd("v", function() { Log.say(cmd(120)); }, "Display engine info."); Cmdline.register_cmd("c", null, "Redirect logging to console."); Cmdline.register_cmd("l", null, "Set logging file name."); -Cmdline.register_cmd("h", function() { Log.warn("Helping."); exit();}, "Help."); +Cmdline.register_cmd("h", function() { + Game.quit(); +}, +"Help."); + +Cmdline.register_cmd("e", function(pawn) { + run("scripts/editor.js"); + eval(`Log.write(Input.print_md_kbm(${pawn}));`); + Game.quit(); +}, "Print input documentation for a given object." ); function run(file) { @@ -111,6 +124,10 @@ var Log = { cmd(91,msg); }, + say(msg) { + cmd(91, `${msg}\n`); + }, + stack(skip = 0) { var stack = (new Error()).stack; var n = stack.next('\n',0)+1; @@ -832,10 +849,25 @@ var Input = { Input.print_pawn_kbm = function(pawn) { if (!('inputs' in pawn)) return; + var str = ""; + for (var key in pawn.inputs) { + str += `${key} | ${pawn.inputs[key].doc}\n`; + } + return str; +}; + +Input.print_md_kbm = function(pawn) { + if (!('inputs' in pawn)) return; + + var str = ""; + str += "|control|description|\n|---|---|\n"; for (var key in pawn.inputs) { - Log.warn(`${key} :: ${pawn.inputs[key].doc}`); + str += `|${key}|${pawn.inputs[key].doc}|`; + str += "\n"; } + + return str; }; function screen2world(screenpos) { return Yugine.camera.view2world(screenpos); } @@ -883,24 +915,29 @@ var Player = { this.pawns.forEach(x => x[fn]?.(...args)); }, - raw_input(cmd, ...args) { + raw_input(cmd, state, ...args) { for (var pawn of this.pawns.reverse()) { - if (typeof pawn.inputs?.[cmd] === 'function') { - pawn.inputs[cmd](...args); - return; + if (!pawn.inputs?.[cmd]) continue; + + var fn = null; + + switch (state) { + case 'pressed': + fn = pawn.inputs[cmd]; + break; + case 'rep': + fn = pawn.inputs[cmd].rep ? pawn.inputs[cmd] : null; + break; + case 'released': + fn = pawn.inputs[cmd].released; + break; } + + if (typeof fn === 'function') + fn.call(pawn, ... args); } }, - - raw_release(cmd, ...args) { - for (var pawn of this.pawns.reverse()) { - if (typeof pawn.inputs?.[cmd]?.released === 'function') { - pawn.inputs[cmd].released(...args); - return; - } - } - }, - + control(pawn) { this.pawns.push_unique(pawn); }, @@ -969,15 +1006,17 @@ var Register = { var input = `${src}_${btn}_${state}`; Player.players[0].input(input, ...args); - if (!(state === "pressed" || state === "released")) return; + if (!(state === "pressed" || state === "released" || state === "rep")) return; + if (btn === 'lmouse') + btn = 'lm'; + + if (btn === 'rmouse') + btn = 'rm'; var e_str = ""; if (Keys.ctrl()) e_str += "C-"; if (Keys.alt()) e_str += "M-"; e_str += btn; - if (state === "pressed") - Player.players[0].raw_input(e_str, ...args); - else - Player.players[0].raw_release(e_str, ...args); + Player.players[0].raw_input(e_str, state, ...args); }, gamepad_playermap: [], @@ -1002,7 +1041,6 @@ var Register = { }, unregister_obj(obj) { - Log.warn(`Unregister ${JSON.stringify(obj.body)}`); this.updates = this.updates.filter(x => x[1] !== obj); this.guis = this.guis.filter(x => x[1] !== obj); this.nk_guis = this.nk_guis.filter(x => x[1] !== obj); @@ -2185,8 +2223,6 @@ var gameobject = { obj.sync(); obj.defn('components', {}); - Log.warn(`Made an object with ID ${obj.body}`); - cmd(113, obj.body, obj); complete_assign(obj, {