diff --git a/scripts/base.js b/scripts/base.js index 972f668d..5e92b14f 100644 --- a/scripts/base.js +++ b/scripts/base.js @@ -156,16 +156,6 @@ Object.defineProperty(Object.prototype, 'hasOwn', { value: function(x) { return this.hasOwnProperty(x); } }); -Object.defineProperty(Object.prototype, 'array', { - value: function() { - var a = []; - for (var key in this) - a.push(this[key]); - - return a; - }, -}); - Object.defineProperty(Object.prototype, 'defn', { value: function(name, val) { Object.defineProperty(this, name, { value:val, writable:true, configurable:true }); @@ -221,12 +211,10 @@ Object.defineProperty(Object.prototype, 'deflock', { Object.defineProperty(Object.prototype, 'forEach', { value: function(fn) { - for (var key in this) - fn(this[key]); + Object.values(this).forEach(fn); } }); - Object.defineProperty(Object.prototype, 'empty', { get: function() { return Object.keys(this).empty; @@ -241,6 +229,36 @@ Object.defineProperty(Object.prototype, 'nth', { }, }); +Object.defineProperty(Object.prototype, 'filter', { + value: function(fn) { + return Object.values(this).filter(fn); + } +}); + +Object.defineProperty(Object.prototype, 'push', { + value: function(val) { + var str = val.toString(); + str = str.replaceAll('.', '_'); + var n = 1; + var t = str + n; + while (Object.hasOwn(this,t)) { + n++; + t = str + n; + } + this[t] = val; + return val; + } +}); + +Object.defineProperty(Object.prototype, 'remove', { + value: function(val) { + for (var e of this.entries()) { + if (e.value === val) + delete this[e.key] + } + } +}); + Object.defineProperty(Object.prototype, 'findIndex', { value: function(x) { var i = 0; @@ -651,6 +669,11 @@ Object.defineProperty(Array.prototype, 'lerp', { Math.lerp = function(s,f,t) { return (f-s)*t + s; }; +Number.prec = function(num) +{ + return num.toPrecision(3)/1; +} + Object.defineProperty(Object.prototype, 'lerp',{ value: function(to, t) { var self = this; diff --git a/scripts/components.js b/scripts/components.js index 5f01d3fd..502e48d1 100644 --- a/scripts/components.js +++ b/scripts/components.js @@ -76,7 +76,7 @@ component.sprite.maker = Object.copy(component, { cmd(12,this.id,x,this.rect); }, get path() { - return cmd(116,this.id); + return this.resavi(cmd(116,this.id)); }, get visible() { return this.enabled; }, set visible(x) { this.enabled = x; }, diff --git a/scripts/editor.js b/scripts/editor.js index 923304bd..a21478b3 100644 --- a/scripts/editor.js +++ b/scripts/editor.js @@ -352,7 +352,7 @@ var editor = { } this.edit_level = Primum.spawn(ur.arena); - this.edit_level.toString = function() { return "desktop"; }; +// this.edit_level.toString = function() { return "desktop"; }; editor.edit_level.selectable = false; }, @@ -388,13 +388,16 @@ var editor = { GUI.text("0,0", world2screen([0,0])); var clvl = this.edit_level; - var lvlcolorsample = 1; + var lvlcolorsample = 1; + var lvlcolor = ColorMap.Inferno.sample(lvlcolorsample); var ypos = 200; while (clvl) { + lvlcolor = ColorMap.Inferno.sample(lvlcolorsample); var lvlstr = clvl.toString(); if (clvl.dirty) lvlstr += "*"; - GUI.text(lvlstr, [0, ypos], 1, ColorMap.Inferno.sample(lvlcolorsample)); + GUI.text(lvlstr, [0, ypos], 1, lvlcolor); + lvlcolorsample -= 0.1; if (!clvl.level) break; @@ -405,44 +408,42 @@ var editor = { } ypos -= 5; } - - this.edit_level.objects.forEach(function(x) { - if ('ed_gizmo' in x) - x.ed_gizmo(); - }); - - if (Debug.phys_drawing) - this.edit_level.objects.forEach(function(x) { - Debug.point(world2screen(x.pos), 2, Color.teal); - }); + + /* Color selected objects with the next deeper color */ + lvlcolorsample -= 0.1; + lvlcolor = ColorMap.Inferno.sample(lvlcolorsample); this.selectlist.forEach(function(x) { - var color = x.color ? x.color : Color.white; var sname = x.ur.toString(); if (!x.json_obj().empty) x.dirty = true; else x.dirty = false; if (x.dirty) sname += "*"; - GUI.text(sname, world2screen(x.pos).add([0, 16]), 1, Color.purple); - for (var key in x.$) { - var o = x.$[key]; - GUI.text(o.ur.toString(), world2screen(o.pos).add([0,16]),1,Color.purple); - GUI.text(key, world2screen(o.pos), 1, Color.green); - } - - GUI.text(x.pos.map(function(x) { return Math.round(x); }), world2screen(x.pos), 1, color); + GUI.text(sname, world2screen(x.pos).add([0, 16]), 1, lvlcolor); + GUI.text(x.pos.map(function(x) { return Math.round(x); }), world2screen(x.pos), 1, Color.white); Debug.arrow(world2screen(x.pos), world2screen(x.pos.add(x.up().scale(40))), Color.yellow, 1); if ('gizmo' in x && typeof x['gizmo'] === 'function' ) x.gizmo(); - - if (x.hasOwn('file')) - x.objects.forEach(function(x) { - GUI.text(x.toString(), world2screen(x.pos).add([0,16]),1,Color.blue); - }); }); + if (this.selectlist.length === 0) + for (var key in this.edit_level.objects) { + var o = this.edit_level.objects[key]; + GUI.text(key, world2screen(o.pos), 1, lvlcolor); + } + else + this.selectlist.forEach(function(x) { + Object.entries(x.objects).forEach(function(x) { + GUI.text(x[0], world2screen(x[1].pos), 1, lvlcolor); + }); + }); + + this.edit_level.objects.forEach(function(x) { + if ('ed_gizmo' in x) + x.ed_gizmo(); + }); if (this.selectlist.length === 1) { var i = 1; @@ -565,8 +566,11 @@ var editor = { }, /* Checking to save an entity as a subtype. */ - saveas_check(sub) { + /* sub is the name of the type; obj is the object to save it as */ + saveas_check(sub, obj) { if (!sub) return; + obj ??= editor.selectlist[0]; + var curur = prototypes.get_ur(sub); if (curur) { @@ -574,13 +578,14 @@ var editor = { this.openpanel(gen_notify("Entity already exists with that name. Overwrite?", this.saveas.bind(this, sub))); } else { var path = sub.replaceAll('.', '/') + ".json"; - IO.slurpwrite(JSON.stringify(editor.selectlist[0],null,1), path); - var t = editor.selectlist[0].transform(); - editor.selectlist[0].kill(); + var saveobj = obj.level_obj(); + IO.slurpwrite(JSON.stringify(saveobj,null,1), path); + var t = obj.transform(); + obj.kill(); editor.unselect(); editor.load(sub); - editor.selectlist[0].pos = t.pos; - editor.selectlist[0].angle = t.angle; + obj.pos = t.pos; + obj.angle = t.angle; } }, } @@ -676,13 +681,12 @@ editor.inputs['C-f'] = function() { editor.inputs['C-f'].doc = "Tunnel into the selected level object to edit it."; editor.inputs['C-F'] = function() { - if (!editor.edit_level.level) return; + if (editor.edit_level.level === Primum) return; editor.edit_level = editor.edit_level.level; editor.unselect(); editor.reset_undos(); editor.curlvl = editor.edit_level.save(); - editor.edit_level.filejson = editor.edit_level.save(); editor.edit_level.check_dirty(); }; editor.inputs['C-F'].doc = "Tunnel out of the level you are editing, saving it in the process."; @@ -769,6 +773,12 @@ editor.inputs.escape = function() { editor.openpanel(quitpanel); } editor.inputs.escape.doc = "Quit editor."; editor.inputs['C-s'] = function() { + if (editor.selectlist.length === 0) { + saveaspanel.stem = editor.edit_level.toString(); + saveaspanel.obj = editor.edit_level; + editor.openpanel(saveaspanel); + return; + }; if (editor.selectlist.length !== 1 || !editor.selectlist[0].dirty) return; Log.warn(JSON.stringify(editor.selectlist[0],null,1)); Log.warn(JSON.stringify(editor.selectlist[0].ur,null,1)); @@ -826,14 +836,6 @@ editor.inputs['C-n'] = function() { editor.inputs['C-n'].doc = "Open a new level."; editor.inputs['C-o'] = function() { -/* if (editor.edit_level.dirty) { - editor.openpanel(gen_notify("Level is changed. Are you sure you want to close it?", function() { - editor.clear_level(); - editor.openpanel(openlevelpanel); - }.bind(editor))); - return; - } -*/ editor.openpanel(openlevelpanel); }; editor.inputs['C-o'].doc = "Open a level."; @@ -1399,15 +1401,19 @@ var replpanel = Object.copy(inputpanel, { action() { var ecode = ""; - if (editor.selectlist.length === 1) - for (var key in editor.selectlist[0].$) - ecode += `var ${key} = editor.selectlist[0].$['${key}'];`; + if (editor.selectlist.length === 1) { + for (var key in editor.selectlist[0].objects) + ecode += `var ${key} = editor.selectlist[0].objects['${key}'];`; + } else { + for (var key in editor.edit_level.objects) + ecode += `var ${key} = editor.edit_level.objects['${key}'];`; + } ecode += this.value; Log.say(this.value); this.value = ""; var ret = function() {return eval(ecode);}.call(editor.selectlist[0]); - if (ret) Log.say(ret); + Log.say(ret); }, }); @@ -1613,7 +1619,9 @@ var openlevelpanel = Object.copy(inputpanel, { var saveaspanel = Object.copy(inputpanel, { title: "save level as", action() { - editor.saveas_check(this.stem + "." + this.value); + var savename = ""; + if (this.stem) savename += this.stem + "."; + editor.saveas_check(savename + this.value, this.obj); }, }); @@ -1622,13 +1630,6 @@ var groupsaveaspanel = Object.copy(inputpanel, { action() { editor.groupsaveas(editor.selectlist, this.value); } }); -var savetypeas = Object.copy(inputpanel, { - title: "save type as", - action() { - editor.save_type_as(this.value); - }, -}); - var quitpanel = Object.copy(inputpanel, { title: "really quit?", action() { diff --git a/scripts/engine.js b/scripts/engine.js index e3247b63..09fc9fae 100644 --- a/scripts/engine.js +++ b/scripts/engine.js @@ -546,7 +546,7 @@ var ur_json = function() var ret = {}; for (var key in from) { - if (!from[key] || !to[key]) continue; + if (typeof from[key] === 'undefined' || typeof to[key] === 'undefined') continue; if (typeof from[key] === 'function') continue; if (typeof to === 'object' && !(key in to)) continue; diff --git a/scripts/entity.js b/scripts/entity.js index be0748da..76cabe0e 100644 --- a/scripts/entity.js +++ b/scripts/entity.js @@ -39,8 +39,8 @@ var gameobject = { this.components[key].visible = x; } } - for (var key in this.$) - this.$[key].visible = x; + for (var key in this.objects) + this.objects[key].visible = x; }, phys_nuke() { @@ -71,8 +71,6 @@ var gameobject = { }, get_relpos() { - if (!this.level) return this.pos; - var offset = this.pos.sub(this.level.pos); return Vector.rotate(offset, -Math.deg2rad(this.level.angle)); }, @@ -250,8 +248,8 @@ var gameobject = { if ('boundingbox' in this.components[key]) boxes.push(this.components[key].boundingbox()); } - for (var key in this.$) - boxes.push(this.$[key].boundingbox()); + for (var key in this.objects) + boxes.push(this.objects[key].boundingbox()); if (boxes.empty) return cwh2bb([0,0], [0,0]); @@ -277,6 +275,21 @@ var gameobject = { json_obj() { return JSON.parse(JSON.stringify(this)); }, + + transform_obj() { + var t = this.json_obj(); + Object.assign(t, this.transform()); + return t; + }, + + level_obj() { + var json = this.json_obj(); + Object.entries(this.objects).forEach(function(x) { + json[x[0]] = x[1].transform_obj(); + json[x[0]].ur = x[1].ur.toString(); + }); + return json; + }, make_ur() { var thisur = this.json_obj(); @@ -287,8 +300,10 @@ var gameobject = { transform() { var t = {}; - t.pos = this.pos; - t.angle = this.angle; + t.pos = this.get_relpos(); + t.pos.x = Number.prec(t.pos.x); + t.pos.y = Number.prec(t.pos.y); + t.angle = Number.prec(this.get_relangle()); return t; }, @@ -346,13 +361,13 @@ var gameobject = { var obj = Object.create(gameobject); obj.body = make_gameobject(); obj.components = {}; - obj.objects = []; + obj.objects = {}; + obj.toString = function() { return obj.ur.toString(); }; Game.register_obj(obj); cmd(113, obj.body, obj); // set the internal obj reference to this obj - obj.$ = {}; obj.ur = ur; obj.reparent(level); @@ -363,16 +378,14 @@ var gameobject = { if ('ur' in p) { obj[prop] = obj.spawn(prototypes.get_ur(p.ur)); - obj.$[prop] = obj[prop]; } else if ('comp' in p) { - Log.warn(`spawning a ${p.comp}`); obj[prop] = component[p.comp].make(obj); obj.components[prop] = obj[prop]; } }; Object.totalmerge(obj,ur); - obj.$.forEach(function(x) { x.pos = obj.pos.add(x.pos); }); + obj.objects.forEach(function(x) { x.pos = obj.pos.add(x.pos); }); obj.components.forEach(function(x) { if ('sync' in x) x.sync(); }); obj.check_registers(obj); @@ -399,16 +412,16 @@ var gameobject = { gameobject.toJSON = ur_json; gameobject.ur = { - pos: [0,0], +// pos: [0,0], scale:1, flipx:false, flipy:false, - angle:0, +// angle:0, elasticity:0.5, friction:1, mass:1, - velocity:[0,0], - angularvelocity:0, +// velocity:[0,0], +// angularvelocity:0, layer: 0, };