2023-04-22 16:44:26 -05:00
|
|
|
/*
|
|
|
|
Editor-only variables on objects
|
|
|
|
selectable
|
|
|
|
*/
|
2023-09-11 02:46:12 -05:00
|
|
|
prototypes.generate_ur('.');
|
2023-04-28 12:49:18 -05:00
|
|
|
|
2023-11-29 12:40:13 -06:00
|
|
|
var editor = {
|
|
|
|
toString() { return "editor"; },
|
2023-04-22 16:44:26 -05:00
|
|
|
grid_size: 100,
|
2023-09-15 22:40:19 -05:00
|
|
|
ruler_mark_px: 100,
|
2023-11-06 07:05:27 -06:00
|
|
|
grid_color: Color.green.alpha(0.3),
|
|
|
|
|
2023-10-09 18:10:10 -05:00
|
|
|
dbg_ur: "arena.level1",
|
2023-11-08 01:39:10 -06:00
|
|
|
machine: undefined,
|
|
|
|
device_test: undefined,
|
2023-04-22 16:44:26 -05:00
|
|
|
selectlist: [],
|
2023-09-14 12:49:29 -05:00
|
|
|
grablist: [],
|
|
|
|
scalelist: [],
|
|
|
|
rotlist: [],
|
2023-09-13 16:49:22 -05:00
|
|
|
camera: undefined,
|
|
|
|
edit_level: undefined, /* The current level that is being edited */
|
2023-10-09 18:10:10 -05:00
|
|
|
desktop: undefined, /* The editor desktop, where all editing objects live */
|
2023-09-11 17:09:21 -05:00
|
|
|
working_layer: 0,
|
2023-09-14 12:49:29 -05:00
|
|
|
get cursor() {
|
|
|
|
if (this.selectlist.length === 0 ) return Mouse.worldpos;
|
2023-11-29 12:40:13 -06:00
|
|
|
return physics.com(this.selectlist.map(x => x.pos));
|
2023-09-14 12:49:29 -05:00
|
|
|
},
|
2023-04-22 16:44:26 -05:00
|
|
|
edit_mode: "basic",
|
|
|
|
|
2023-10-17 12:22:06 -05:00
|
|
|
get_this() {
|
|
|
|
return this.edit_level;
|
|
|
|
},
|
|
|
|
|
2023-10-26 11:48:02 -05:00
|
|
|
get_that() {
|
|
|
|
return this.selectlist.length === 1 ? this.selectlist[0] : this.get_this();
|
|
|
|
},
|
|
|
|
|
2023-04-22 16:44:26 -05:00
|
|
|
try_select() { /* nullify true if it should set selected to null if it doesn't find an object */
|
2023-09-14 12:49:29 -05:00
|
|
|
var go = physics.pos_query(Mouse.worldpos);
|
2023-04-22 16:44:26 -05:00
|
|
|
return this.do_select(go);
|
|
|
|
},
|
|
|
|
|
|
|
|
/* Tries to select id */
|
2023-11-29 12:40:13 -06:00
|
|
|
do_select(obj) {
|
|
|
|
if (!obj) return;
|
|
|
|
// if (!obj || !obj._ed.selectable) return undefined;
|
2023-09-21 12:50:39 -05:00
|
|
|
|
2023-04-22 16:44:26 -05:00
|
|
|
if (obj.level !== this.edit_level) {
|
|
|
|
var testlevel = obj.level;
|
|
|
|
while (testlevel && testlevel.level !== this.edit_level) {
|
|
|
|
testlevel = testlevel.level;
|
|
|
|
}
|
|
|
|
|
|
|
|
return testlevel;
|
|
|
|
}
|
2023-09-21 12:50:39 -05:00
|
|
|
|
|
|
|
return obj;
|
|
|
|
|
|
|
|
if (this.working_layer > -1 && obj.draw_layer !== this.working_layer) return undefined;
|
2023-04-22 16:44:26 -05:00
|
|
|
|
|
|
|
return obj;
|
|
|
|
},
|
|
|
|
|
2023-09-11 17:09:21 -05:00
|
|
|
curpanel: undefined,
|
2023-04-22 16:44:26 -05:00
|
|
|
|
|
|
|
check_level_nested() {
|
|
|
|
if (this.edit_level.level) {
|
|
|
|
this.openpanel(gen_notify("Can't close a nested level. Save up to the root before continuing."));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
},
|
|
|
|
|
|
|
|
programmode: false,
|
|
|
|
|
|
|
|
dup_objects(x) {
|
|
|
|
var objs = x.slice();
|
|
|
|
var duped = [];
|
|
|
|
|
2023-09-15 22:40:19 -05:00
|
|
|
objs.forEach(function(x) { duped.push(x.dup()); } );
|
|
|
|
return duped;
|
2023-04-22 16:44:26 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
sel_start: [],
|
|
|
|
|
|
|
|
mover(amt, snap) {
|
|
|
|
return function(go) { go.pos = go.pos.add(amt)};
|
|
|
|
},
|
|
|
|
|
|
|
|
step_amt() { return Keys.shift() ? 10 : 1; },
|
|
|
|
|
|
|
|
on_grid(pos) {
|
2023-11-29 12:40:13 -06:00
|
|
|
return pos.every(function(x) { return x % editor.grid_size === 0; });
|
2023-04-22 16:44:26 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
snapper(dir, grid) {
|
|
|
|
return function(go) {
|
|
|
|
go.pos = go.pos.add(dir.scale(grid/2));
|
|
|
|
go.pos = go.pos.map(function(x) { return Math.snap(x, grid) }, this);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
key_move(dir) {
|
2023-09-24 11:26:44 -05:00
|
|
|
if (!editor.grabselect) return;
|
2023-04-22 16:44:26 -05:00
|
|
|
if (Keys.ctrl())
|
2023-11-29 12:40:13 -06:00
|
|
|
this.selectlist.forEach(this.snapper(dir.scale(1.01), editor.grid_size));
|
2023-04-22 16:44:26 -05:00
|
|
|
else
|
|
|
|
this.selectlist.forEach(this.mover(dir.scale(this.step_amt())));
|
|
|
|
},
|
|
|
|
|
|
|
|
/* Snapmode
|
|
|
|
0 No snap
|
|
|
|
1 Pixel snap
|
|
|
|
2 Grid snap
|
|
|
|
*/
|
|
|
|
snapmode: 0,
|
|
|
|
|
|
|
|
snapped_pos(pos) {
|
|
|
|
switch (this.snapmode) {
|
|
|
|
case 0:
|
|
|
|
return pos;
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
return pos.map(function(x) { return Math.round(x); });
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
return pos.map
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
unselect() {
|
2023-08-27 21:57:19 -05:00
|
|
|
editor.selectlist = [];
|
2023-09-14 12:49:29 -05:00
|
|
|
this.grabselect = [];
|
|
|
|
this.scalelist = [];
|
|
|
|
this.rotlist = [];
|
2023-09-11 17:09:21 -05:00
|
|
|
this.sel_comp = undefined;
|
2023-04-22 16:44:26 -05:00
|
|
|
},
|
|
|
|
|
2023-09-11 17:09:21 -05:00
|
|
|
sel_comp: undefined,
|
2023-04-22 16:44:26 -05:00
|
|
|
comp_info: false,
|
2023-09-11 17:09:21 -05:00
|
|
|
brush_obj: undefined,
|
2023-04-22 16:44:26 -05:00
|
|
|
|
|
|
|
camera_recalls: {},
|
2023-08-27 21:57:19 -05:00
|
|
|
camera_recall_stack: [],
|
|
|
|
|
|
|
|
camera_recall_store() {
|
|
|
|
this.camera_recall_stack.push({
|
|
|
|
pos:this.camera.pos,
|
|
|
|
zoom:this.camera.zoom
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
camera_recall_pop() {
|
|
|
|
Object.assign(this.camera, this.camera_recalls.pop());
|
|
|
|
},
|
|
|
|
|
|
|
|
camera_recall_clear() {
|
|
|
|
this.camera_recall_stack = [];
|
|
|
|
},
|
2023-04-22 16:44:26 -05:00
|
|
|
|
|
|
|
input_num_pressed(num) {
|
|
|
|
if (Keys.ctrl()) {
|
|
|
|
this.camera_recalls[num] = {
|
|
|
|
pos:this.camera.pos,
|
|
|
|
zoom:this.camera.zoom
|
|
|
|
};
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (num in this.camera_recalls)
|
|
|
|
Object.assign(this.camera, this.camera_recalls[num]);
|
|
|
|
},
|
|
|
|
|
|
|
|
zoom_to_bb(bb) {
|
|
|
|
var cwh = bb2cwh(bb);
|
|
|
|
|
|
|
|
var xscale = cwh.wh.x / Window.width;
|
|
|
|
var yscale = cwh.wh.y / Window.height;
|
|
|
|
|
|
|
|
var zoom = yscale > xscale ? yscale : xscale;
|
|
|
|
|
|
|
|
this.camera.pos = cwh.c;
|
|
|
|
this.camera.zoom = zoom*1.3;
|
|
|
|
},
|
|
|
|
|
2023-09-12 17:19:46 -05:00
|
|
|
z_start: undefined,
|
2023-09-11 17:09:21 -05:00
|
|
|
grabselect: undefined,
|
2023-09-12 17:19:46 -05:00
|
|
|
mousejoy: undefined,
|
|
|
|
joystart: undefined,
|
2023-04-22 16:44:26 -05:00
|
|
|
|
2023-10-09 18:10:10 -05:00
|
|
|
stash: undefined,
|
2023-04-22 16:44:26 -05:00
|
|
|
|
|
|
|
start_play_ed() {
|
2023-10-11 17:22:41 -05:00
|
|
|
this.stash = this.desktop.instance_obj();
|
|
|
|
Primum.clear();
|
2023-10-17 12:22:06 -05:00
|
|
|
load("config.js");
|
2023-10-09 18:10:10 -05:00
|
|
|
Game.play();
|
|
|
|
Player.players[0].uncontrol(this);
|
|
|
|
Player.players[0].control(limited_editor);
|
|
|
|
Register.unregister_obj(this);
|
2023-11-16 09:27:04 -06:00
|
|
|
load("predbg.js");
|
2023-10-18 17:20:23 -05:00
|
|
|
editor.dbg_play = Primum.spawn(this.dbg_ur);
|
2023-11-06 07:05:27 -06:00
|
|
|
editor.dbg_play.pos = [0,0];
|
2023-10-18 17:20:23 -05:00
|
|
|
load("debug.js");
|
2023-10-09 18:10:10 -05:00
|
|
|
},
|
|
|
|
|
2023-11-20 15:57:23 -06:00
|
|
|
start_play() {
|
|
|
|
Primum.clear();
|
|
|
|
load("config.js");
|
|
|
|
Game.play();
|
|
|
|
Player.players[0].uncontrol(this);
|
|
|
|
Player.players[0].control(limited_editor);
|
|
|
|
Register.unregister_obj(this);
|
|
|
|
load("game.js");
|
|
|
|
},
|
|
|
|
|
2023-10-09 18:10:10 -05:00
|
|
|
enter_editor() {
|
|
|
|
Game.pause();
|
|
|
|
Player.players[0].control(this);
|
|
|
|
Player.players[0].uncontrol(limited_editor);
|
|
|
|
Register.gui.register(editor.ed_gui, editor);
|
2023-11-08 01:39:10 -06:00
|
|
|
Register.draw.register(editor.draw, editor);
|
2023-10-09 18:10:10 -05:00
|
|
|
Debug.register_call(editor.ed_debug, editor);
|
|
|
|
Register.update.register(gui_controls.update, gui_controls);
|
2023-10-11 17:22:41 -05:00
|
|
|
this.desktop = Primum.spawn(ur.arena);
|
2023-10-17 12:22:06 -05:00
|
|
|
Primum.rename_obj(this.desktop.toString(), "desktop");
|
2023-10-11 17:22:41 -05:00
|
|
|
this.edit_level = this.desktop;
|
|
|
|
editor.edit_level._ed.selectable = false;
|
|
|
|
if (this.stash) {
|
|
|
|
this.desktop.make_objs(this.stash.objects);
|
|
|
|
Object.dainty_assign(this.desktop, this.stash);
|
|
|
|
}
|
|
|
|
this.selectlist = [];
|
2023-10-16 19:59:58 -05:00
|
|
|
editor.camera = Primum.spawn(ur.camera2d);
|
|
|
|
Game.view_camera(editor.camera);
|
2023-10-09 18:10:10 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
end_debug() {
|
|
|
|
|
2023-04-22 16:44:26 -05:00
|
|
|
},
|
|
|
|
|
2023-10-16 19:59:58 -05:00
|
|
|
openpanel(panel) {
|
|
|
|
if (this.curpanel) {
|
2023-04-22 16:44:26 -05:00
|
|
|
this.curpanel.close();
|
2023-10-16 19:59:58 -05:00
|
|
|
Player.players[0].uncontrol(this.curpanel);
|
|
|
|
}
|
2023-04-22 16:44:26 -05:00
|
|
|
|
|
|
|
this.curpanel = panel;
|
2023-10-16 19:59:58 -05:00
|
|
|
Player.players[0].control(this.curpanel);
|
|
|
|
this.curpanel.open();
|
2023-04-22 16:44:26 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
curpanels: [],
|
|
|
|
addpanel(panel) {
|
|
|
|
this.curpanels.push(panel);
|
|
|
|
panel.open();
|
|
|
|
},
|
|
|
|
|
|
|
|
cleanpanels(panel) {
|
|
|
|
this.curpanels = this.curpanels.filter(function(x) { return x.on; });
|
|
|
|
},
|
|
|
|
|
|
|
|
snapshots: [],
|
|
|
|
curlvl: {}, /* What the level currently looks like on file */
|
|
|
|
|
|
|
|
reset_undos() {
|
|
|
|
this.snapshots = [];
|
|
|
|
this.backshots = [];
|
|
|
|
},
|
|
|
|
|
|
|
|
snapshot() {
|
2023-11-20 07:49:14 -06:00
|
|
|
var dif = this.edit_level.json_obj();
|
|
|
|
if (!dif) return;
|
|
|
|
|
|
|
|
if (this.snapshots.length !== 0) {
|
|
|
|
var ddif = ediff(dif, this.snapshots.last);
|
|
|
|
if (!ddif) return;
|
|
|
|
dif = ddif;
|
|
|
|
}
|
2023-04-22 16:44:26 -05:00
|
|
|
|
2023-11-20 07:49:14 -06:00
|
|
|
this.snapshots.push(dif);
|
2023-04-22 16:44:26 -05:00
|
|
|
this.backshots = [];
|
|
|
|
return;
|
|
|
|
|
|
|
|
this.snapshots.push(dif);
|
|
|
|
|
|
|
|
this.backshots = [];
|
|
|
|
this.backshots.push(diff(this.curlvl, cur));
|
|
|
|
this.curlvl = cur;
|
|
|
|
this.edit_level.check_dirty();
|
|
|
|
},
|
|
|
|
|
|
|
|
backshots: [], /* Redo snapshots */
|
|
|
|
|
|
|
|
restore_lvl(lvl) {
|
|
|
|
this.unselect();
|
|
|
|
this.edit_level.clear();
|
|
|
|
this.edit_level.load(lvl);
|
|
|
|
this.edit_level.check_dirty();
|
|
|
|
},
|
|
|
|
|
|
|
|
redo() {
|
|
|
|
if (this.backshots.empty) {
|
|
|
|
Log.info("Nothing to redo.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.snapshots.push(this.edit_level.save());
|
|
|
|
var dd = this.backshots.pop();
|
|
|
|
this.edit_level.clear();
|
|
|
|
this.edit_level.load(dd);
|
|
|
|
this.edit_level.check_dirty();
|
|
|
|
this.curlvl = dd;
|
|
|
|
},
|
|
|
|
|
|
|
|
undo() {
|
|
|
|
if (this.snapshots.empty) {
|
|
|
|
Log.info("Nothing to undo.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.unselect();
|
2023-11-20 07:49:14 -06:00
|
|
|
// this.backshots.push(this.edit_level.save());
|
2023-04-22 16:44:26 -05:00
|
|
|
var dd = this.snapshots.pop();
|
2023-11-20 07:49:14 -06:00
|
|
|
Object.dainty_assign(this.edit_level, dd);
|
|
|
|
this.edit_level._ed.check_dirty();
|
2023-04-22 16:44:26 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
restore_buffer() {
|
|
|
|
this.restore_level(this.filesnap);
|
|
|
|
},
|
|
|
|
|
|
|
|
save_current() {
|
|
|
|
if (!this.edit_level.file) {
|
|
|
|
this.openpanel(saveaspanel);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2023-10-09 18:10:10 -05:00
|
|
|
load_desktop(d) {
|
|
|
|
|
|
|
|
},
|
|
|
|
|
2023-10-17 12:22:06 -05:00
|
|
|
draw_objects_names(obj,root,depth){
|
|
|
|
if (!obj) return;
|
|
|
|
if (!obj.objects) return;
|
|
|
|
depth ??= 0;
|
|
|
|
root = root ? root + "." : root;
|
|
|
|
Object.entries(obj.objects).forEach(function(x) {
|
|
|
|
var p = root + x[0];
|
|
|
|
GUI.text(p, world2screen(x[1].worldpos()), 1, editor.color_depths[depth]);
|
|
|
|
editor.draw_objects_names(x[1], p, depth+1);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2023-09-11 17:09:21 -05:00
|
|
|
_sel_comp: undefined,
|
2023-04-22 16:44:26 -05:00
|
|
|
get sel_comp() { return this._sel_comp; },
|
|
|
|
set sel_comp(x) {
|
|
|
|
if (this._sel_comp)
|
2023-08-28 17:00:53 -05:00
|
|
|
Player.players[0].uncontrol(this._sel_comp);
|
2023-04-22 16:44:26 -05:00
|
|
|
|
|
|
|
this._sel_comp = x;
|
|
|
|
|
|
|
|
if (this._sel_comp) {
|
|
|
|
Log.info("sel comp is now " + this._sel_comp);
|
2023-08-28 17:00:53 -05:00
|
|
|
Player.players[0].control(this._sel_comp);
|
2023-04-22 16:44:26 -05:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
time: 0,
|
|
|
|
|
2023-10-17 12:22:06 -05:00
|
|
|
color_depths: [],
|
2023-11-08 01:39:10 -06:00
|
|
|
draw() {
|
|
|
|
Debug.line(bb2points(cwh2bb([0,0],[Game.native.x,Game.native.y])).wrapped(1), Color.yellow);
|
|
|
|
|
|
|
|
/* Draw selection box */
|
|
|
|
if (this.sel_start) {
|
|
|
|
var endpos = Mouse.worldpos;
|
|
|
|
var c = [];
|
|
|
|
c[0] = (endpos[0] - this.sel_start[0]) / 2;
|
|
|
|
c[0] += this.sel_start[0];
|
|
|
|
c[1] = (endpos[1] - this.sel_start[1]) / 2;
|
|
|
|
c[1] += this.sel_start[1];
|
|
|
|
var wh = [];
|
|
|
|
wh[0] = Math.abs(endpos[0] - this.sel_start[0]);
|
|
|
|
wh[1] = Math.abs(endpos[1] - this.sel_start[1]);
|
|
|
|
var bb = cwh2bb(c,wh);
|
|
|
|
Debug.boundingbox(bb, Color.Editor.select.alpha(0.1));
|
|
|
|
Debug.line(bb2points(bb).wrapped(1), Color.white);
|
|
|
|
}
|
|
|
|
},
|
2023-10-17 12:22:06 -05:00
|
|
|
|
2023-04-22 16:44:26 -05:00
|
|
|
ed_gui() {
|
|
|
|
/* Clean out killed objects */
|
|
|
|
this.selectlist = this.selectlist.filter(function(x) { return x.alive; });
|
|
|
|
|
2023-08-23 17:18:34 -05:00
|
|
|
GUI.text("WORKING LAYER: " + this.working_layer, [0,520]);
|
|
|
|
GUI.text("MODE: " + this.edit_mode, [0,500]);
|
2023-04-22 16:44:26 -05:00
|
|
|
|
2023-09-14 12:49:29 -05:00
|
|
|
Debug.point(world2screen(this.cursor), 2, Color.green);
|
2023-04-22 16:44:26 -05:00
|
|
|
|
2023-08-25 01:30:39 -05:00
|
|
|
if (this.comp_info && this.sel_comp) {
|
2023-09-22 09:44:58 -05:00
|
|
|
GUI.text(Input.print_pawn_kbm(this.sel_comp,false), [100,700],1);
|
2023-04-22 16:44:26 -05:00
|
|
|
}
|
|
|
|
|
2023-08-23 17:18:34 -05:00
|
|
|
GUI.text("0,0", world2screen([0,0]));
|
2023-10-18 17:20:23 -05:00
|
|
|
GUI.text(editor.edit_level.worldpos().map(function(x) { return Math.round(x); }), world2screen(editor.edit_level.worldpos()), 1, Color.red);
|
|
|
|
GUI.text("+", world2screen(editor.edit_level.worldpos()), 1, Color.blue);
|
2023-10-17 12:22:06 -05:00
|
|
|
|
|
|
|
var thiso = editor.get_this();
|
|
|
|
var clvl = thiso;
|
2023-04-22 16:44:26 -05:00
|
|
|
|
2023-10-02 17:03:01 -05:00
|
|
|
var lvlchain = [];
|
|
|
|
while (clvl !== Primum) {
|
|
|
|
lvlchain.push(clvl);
|
|
|
|
clvl = clvl.level;
|
|
|
|
}
|
|
|
|
lvlchain.push(clvl);
|
|
|
|
|
2023-10-17 12:22:06 -05:00
|
|
|
var colormap = ColorMap.Inferno;
|
|
|
|
editor.color_depths = [];
|
|
|
|
for (var i = 1; i > 0 ; i -= 0.1)
|
|
|
|
editor.color_depths.push(colormap.sample(i));
|
2023-10-02 17:03:01 -05:00
|
|
|
|
2023-10-17 12:22:06 -05:00
|
|
|
var ypos = 200;
|
|
|
|
var depth = 0;
|
2023-10-26 11:48:02 -05:00
|
|
|
var alldirty = false;
|
|
|
|
for (var lvl of lvlchain) {
|
|
|
|
if (alldirty)
|
|
|
|
lvl._ed.dirty = true;
|
|
|
|
else {
|
|
|
|
lvl._ed.check_dirty();
|
|
|
|
if (lvl._ed.dirty) alldirty = true;
|
|
|
|
}
|
|
|
|
}
|
2023-10-02 17:03:01 -05:00
|
|
|
lvlchain.reverse();
|
2023-10-03 17:16:38 -05:00
|
|
|
lvlchain.forEach(function(x,i) {
|
2023-10-17 12:22:06 -05:00
|
|
|
depth = i;
|
2023-10-26 11:48:02 -05:00
|
|
|
var lvlstr = x._ed.namestr();
|
2023-10-03 17:16:38 -05:00
|
|
|
if (i === lvlchain.length-1) lvlstr += "[this]";
|
2023-10-17 12:22:06 -05:00
|
|
|
GUI.text(lvlstr, [0, ypos], 1, editor.color_depths[depth]);
|
2023-09-29 13:16:59 -05:00
|
|
|
|
2023-10-02 17:03:01 -05:00
|
|
|
GUI.text("^^^^^^", [0,ypos+=5],1);
|
|
|
|
ypos += 15;
|
|
|
|
});
|
2023-04-22 16:44:26 -05:00
|
|
|
|
2023-10-17 12:22:06 -05:00
|
|
|
depth++;
|
|
|
|
GUI.text("$$$$$$", [0,ypos],1,editor.color_depths[depth]);
|
|
|
|
|
2023-04-22 16:44:26 -05:00
|
|
|
this.selectlist.forEach(function(x) {
|
2023-10-04 17:57:37 -05:00
|
|
|
var sname = x.__proto__.toString();
|
2023-10-16 19:59:58 -05:00
|
|
|
x._ed.check_dirty();
|
2023-10-05 08:02:12 -05:00
|
|
|
if (x._ed.dirty) sname += "*";
|
2023-10-02 17:03:01 -05:00
|
|
|
|
2023-11-20 07:49:14 -06:00
|
|
|
GUI.text(sname, world2screen(x.worldpos()).add([0, 32]), 1, Color.editor.ur);
|
2023-10-02 17:03:01 -05:00
|
|
|
GUI.text(x.worldpos().map(function(x) { return Math.round(x); }), world2screen(x.worldpos()), 1, Color.white);
|
2023-11-20 07:49:14 -06:00
|
|
|
// Debug.arrow(world2screen(x.worldpos()), world2screen(x.worldpos().add(x.up().scale(40))), Color.yellow, 1);
|
2023-09-19 17:37:54 -05:00
|
|
|
|
2023-04-22 16:44:26 -05:00
|
|
|
if ('gizmo' in x && typeof x['gizmo'] === 'function' )
|
|
|
|
x.gizmo();
|
|
|
|
});
|
|
|
|
|
2023-10-18 17:20:23 -05:00
|
|
|
Object.entries(thiso.objects).forEach(function(x) {
|
2023-10-26 11:48:02 -05:00
|
|
|
var p = x[1]._ed.namestr();
|
2023-11-20 07:49:14 -06:00
|
|
|
GUI.text(p, world2screen(x[1].worldpos().add([0,16])),1,editor.color_depths[depth]);
|
2023-10-18 17:20:23 -05:00
|
|
|
});
|
|
|
|
|
2023-11-29 12:40:13 -06:00
|
|
|
var mg = physics.pos_query(Mouse.worldpos);
|
2023-09-29 13:16:59 -05:00
|
|
|
|
2023-10-17 12:22:06 -05:00
|
|
|
if (mg) {
|
|
|
|
var p = mg.path_from(thiso);
|
|
|
|
GUI.text(p, world2screen(Mouse.worldpos),1,Color.teal);
|
|
|
|
}
|
2023-04-22 16:44:26 -05:00
|
|
|
|
|
|
|
if (this.selectlist.length === 1) {
|
|
|
|
var i = 1;
|
|
|
|
for (var key in this.selectlist[0].components) {
|
|
|
|
var selected = this.sel_comp === this.selectlist[0].components[key];
|
2023-10-10 17:37:58 -05:00
|
|
|
var str = (selected ? ">" : " ") + key + " [" + this.selectlist[0].components[key].toString() + "]";
|
2023-10-02 17:03:01 -05:00
|
|
|
GUI.text(str, world2screen(this.selectlist[0].worldpos()).add([0,-16*(i++)]));
|
2023-04-22 16:44:26 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if (this.sel_comp) {
|
|
|
|
if ('gizmo' in this.sel_comp) this.sel_comp.gizmo();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-13 16:49:22 -05:00
|
|
|
editor.edit_level.objects.forEach(function(obj) {
|
2023-10-06 12:38:49 -05:00
|
|
|
if (!obj._ed.selectable)
|
2023-10-02 17:03:01 -05:00
|
|
|
GUI.image("icons/icons8-lock-16.png", world2screen(obj.worldpos()));
|
2023-04-22 16:44:26 -05:00
|
|
|
});
|
|
|
|
|
2023-11-29 12:40:13 -06:00
|
|
|
Debug.draw_grid(1, editor.grid_size, Color.Editor.grid.alpha(0.3));
|
|
|
|
var startgrid = screen2world([-20,0]).map(function(x) { return Math.snap(x, editor.grid_size); });
|
2023-10-06 12:38:49 -05:00
|
|
|
var endgrid = screen2world([Window.width, Window.height]);
|
2023-04-22 16:44:26 -05:00
|
|
|
|
2023-11-29 12:40:13 -06:00
|
|
|
var w_step = Math.round(editor.ruler_mark_px/Window.width * (endgrid.x-startgrid.x)/editor.grid_size)*editor.grid_size;
|
|
|
|
if (w_step === 0) w_step = editor.grid_size;
|
2023-09-15 22:40:19 -05:00
|
|
|
|
2023-11-29 12:40:13 -06:00
|
|
|
var h_step = Math.round(editor.ruler_mark_px/Window.height * (endgrid.y-startgrid.y)/editor.grid_size)*editor.grid_size;
|
|
|
|
if (h_step === 0) h_step = editor.grid_size;
|
2023-09-15 22:40:19 -05:00
|
|
|
|
2023-04-22 16:44:26 -05:00
|
|
|
while(startgrid[0] <= endgrid[0]) {
|
2023-08-23 17:18:34 -05:00
|
|
|
GUI.text(startgrid[0], [world2screen([startgrid[0], 0])[0],0]);
|
2023-09-15 22:40:19 -05:00
|
|
|
startgrid[0] += w_step;
|
2023-04-22 16:44:26 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
while(startgrid[1] <= endgrid[1]) {
|
2023-08-23 17:18:34 -05:00
|
|
|
GUI.text(startgrid[1], [0, world2screen([0, startgrid[1]])[1]]);
|
2023-09-15 22:40:19 -05:00
|
|
|
startgrid[1] += h_step;
|
2023-04-22 16:44:26 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if (this.curpanel && this.curpanel.on)
|
|
|
|
this.curpanel.gui();
|
|
|
|
|
|
|
|
this.curpanels.forEach(function(x) {
|
|
|
|
if (x.on) x.gui();
|
|
|
|
});
|
2023-10-26 11:48:02 -05:00
|
|
|
/*
|
|
|
|
var o = editor.get_that();
|
|
|
|
|
|
|
|
var pos = [6,600];
|
|
|
|
var offset = [0,0];
|
|
|
|
var os = Object.entries(o.objects);
|
|
|
|
|
|
|
|
GUI.text(o.toString(), pos.add(offset));
|
|
|
|
offset = offset.add([5,-16]);
|
|
|
|
|
|
|
|
os.forEach(function(x) {
|
|
|
|
GUI.text(x.toString(), pos.add(offset));
|
|
|
|
offset = offset.add([0,-16]);
|
|
|
|
});
|
|
|
|
|
|
|
|
GUI.text(JSON.stringify(o._ed.urdiff,null,1), [500,500]);
|
|
|
|
*/
|
2023-10-29 16:39:45 -05:00
|
|
|
|
2023-04-22 16:44:26 -05:00
|
|
|
},
|
2023-09-13 16:49:22 -05:00
|
|
|
|
2023-04-22 16:44:26 -05:00
|
|
|
ed_debug() {
|
|
|
|
if (!Debug.phys_drawing)
|
|
|
|
this.selectlist.forEach(function(x) { Debug.draw_obj_phys(x); });
|
|
|
|
},
|
|
|
|
|
|
|
|
viewasset(path) {
|
|
|
|
Log.info(path);
|
|
|
|
var fn = function(x) { return path.endsWith(x); };
|
|
|
|
if (images.any(fn)) {
|
2023-09-20 17:58:18 -05:00
|
|
|
var newtex = Object.copy(texgui, { path: path });
|
2023-04-22 16:44:26 -05:00
|
|
|
this.addpanel(newtex);
|
|
|
|
}
|
|
|
|
else if (sounds.any(fn))
|
|
|
|
Log.info("selected a sound");
|
|
|
|
},
|
|
|
|
|
|
|
|
killring: [],
|
|
|
|
killcom: [],
|
|
|
|
|
|
|
|
lvl_history: [],
|
|
|
|
|
|
|
|
load(file) {
|
2023-10-06 12:38:49 -05:00
|
|
|
Log.warn("LOADING " + file);
|
2023-09-26 08:37:19 -05:00
|
|
|
var ur = prototypes.get_ur(file);
|
|
|
|
if (!ur) return;
|
|
|
|
var obj = editor.edit_level.spawn(ur);
|
2023-11-16 09:27:04 -06:00
|
|
|
obj.set_worldpos(Mouse.worldpos);
|
2023-09-14 12:49:29 -05:00
|
|
|
this.selectlist = [obj];
|
2023-04-22 16:44:26 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
load_prev() {
|
|
|
|
if (this.lvl_history.length === 0) return;
|
|
|
|
|
|
|
|
var file = this.lvl_history.pop();
|
|
|
|
this.edit_level = Level.loadfile(file);
|
|
|
|
this.unselect();
|
|
|
|
},
|
|
|
|
|
2023-09-26 13:34:02 -05:00
|
|
|
/* Checking to save an entity as a subtype. */
|
2023-10-30 17:41:32 -05:00
|
|
|
/* sub is the name of the (sub)type; obj is the object to save it as */
|
2023-09-29 13:16:59 -05:00
|
|
|
saveas_check(sub, obj) {
|
2023-09-26 13:34:02 -05:00
|
|
|
if (!sub) return;
|
2023-09-29 13:16:59 -05:00
|
|
|
obj ??= editor.selectlist[0];
|
|
|
|
|
2023-09-26 13:34:02 -05:00
|
|
|
var curur = prototypes.get_ur(sub);
|
2023-04-22 16:44:26 -05:00
|
|
|
|
2023-09-26 13:34:02 -05:00
|
|
|
if (curur) {
|
2023-04-22 16:44:26 -05:00
|
|
|
notifypanel.action = editor.saveas;
|
2023-10-06 12:38:49 -05:00
|
|
|
this.openpanel(gen_notify("Entity already exists with that name. Delete first."));
|
2023-09-26 13:34:02 -05:00
|
|
|
} else {
|
|
|
|
var path = sub.replaceAll('.', '/') + ".json";
|
2023-10-10 17:37:58 -05:00
|
|
|
var saveobj = obj.json_obj();
|
2023-09-29 13:16:59 -05:00
|
|
|
IO.slurpwrite(JSON.stringify(saveobj,null,1), path);
|
2023-10-06 12:38:49 -05:00
|
|
|
|
|
|
|
if (obj === editor.edit_level) {
|
2023-10-30 17:41:32 -05:00
|
|
|
if (obj === editor.desktop) {
|
|
|
|
obj.clear();
|
|
|
|
var nobj = editor.edit_level.spawn(sub);
|
|
|
|
editor.selectlist = [nobj];
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
editor.edit_level = editor.edit_level.level;
|
2023-10-06 12:38:49 -05:00
|
|
|
}
|
2023-10-30 17:41:32 -05:00
|
|
|
|
|
|
|
var t = obj.transform();
|
2023-09-26 13:34:02 -05:00
|
|
|
editor.unselect();
|
2023-10-30 17:41:32 -05:00
|
|
|
obj.kill();
|
|
|
|
obj = editor.edit_level.spawn(sub);
|
2023-09-29 13:16:59 -05:00
|
|
|
obj.pos = t.pos;
|
|
|
|
obj.angle = t.angle;
|
2023-09-26 13:34:02 -05:00
|
|
|
}
|
2023-04-22 16:44:26 -05:00
|
|
|
},
|
2023-08-24 16:22:52 -05:00
|
|
|
}
|
2023-04-22 16:44:26 -05:00
|
|
|
|
2023-08-24 16:22:52 -05:00
|
|
|
editor.inputs = {};
|
2023-11-22 03:51:43 -06:00
|
|
|
editor.inputs.f9 = function() {
|
|
|
|
Log.warn("CAPTURING");
|
|
|
|
cmd(173, "capture.bmp", 0, 0, 500, 500);
|
|
|
|
}
|
|
|
|
|
2023-10-29 16:39:45 -05:00
|
|
|
editor.inputs.post = function() {
|
|
|
|
if (editor.sel_comp && 'sync' in editor.sel_comp) editor.sel_comp.sync();
|
|
|
|
};
|
2023-09-14 12:49:29 -05:00
|
|
|
editor.inputs.release_post = function() {
|
2023-10-18 17:20:23 -05:00
|
|
|
editor.snapshot();
|
2023-11-20 07:49:14 -06:00
|
|
|
editor.edit_level._ed.check_dirty();
|
2023-09-14 12:49:29 -05:00
|
|
|
};
|
2023-08-24 16:22:52 -05:00
|
|
|
editor.inputs['C-a'] = function() {
|
|
|
|
if (!editor.selectlist.empty) { editor.unselect(); return; }
|
|
|
|
editor.unselect();
|
|
|
|
editor.selectlist = editor.edit_level.objects.slice();
|
|
|
|
};
|
|
|
|
editor.inputs['C-a'].doc = "Select all objects.";
|
|
|
|
|
2023-09-21 19:51:38 -05:00
|
|
|
editor.inputs['C-`'] = function() { editor.openpanel(replpanel); }
|
|
|
|
editor.inputs['C-`'].doc = "Open or close the repl.";
|
2023-08-24 16:22:52 -05:00
|
|
|
|
2023-11-06 07:05:27 -06:00
|
|
|
editor.inputs.n = function() {
|
|
|
|
if (editor.selectlist.length !== 1) return;
|
|
|
|
var o = editor.try_select();
|
|
|
|
if (!o) return;
|
|
|
|
if (o === editor.selectlist[0]) return;
|
|
|
|
if (o.level !== editor.selectlist[0].level) return;
|
|
|
|
|
|
|
|
var tpos = editor.selectlist[0].pos;
|
|
|
|
tpos.x *= -1;
|
|
|
|
o.pos = tpos;
|
|
|
|
};
|
|
|
|
editor.inputs.n.doc = "Set the hovered object's position to mirror the selected object's position on the X axis."
|
|
|
|
editor.inputs['M-n'] = function()
|
|
|
|
{
|
|
|
|
if (editor.selectlist.length !== 1) return;
|
|
|
|
var o = editor.try_select();
|
|
|
|
if (!o) return;
|
|
|
|
if (o === editor.selectlist[0]) return;
|
|
|
|
if (o.level !== editor.selectlist[0].level) return;
|
|
|
|
|
|
|
|
var tpos = editor.selectlist[0].pos;
|
|
|
|
tpos.y *= -1;
|
|
|
|
o.pos = tpos;
|
|
|
|
};
|
|
|
|
editor.inputs.n.doc = "Set the hovered object's position to mirror the selected object's position on the Y axis."
|
|
|
|
|
2023-08-24 16:22:52 -05:00
|
|
|
/* Return if selected component. */
|
|
|
|
editor.inputs['h'] = function() {
|
|
|
|
var visible = true;
|
|
|
|
editor.selectlist.forEach(function(x) { if (x.visible) visible = false; });
|
|
|
|
editor.selectlist.forEach(function(x) { x.visible = visible; });
|
|
|
|
};
|
|
|
|
editor.inputs['h'].doc = "Toggle object hidden.";
|
|
|
|
|
2023-09-22 09:44:58 -05:00
|
|
|
editor.inputs['C-h'] = function() { Primum.objects.forEach(function(x) { x.visible = true; }); };
|
2023-08-24 16:22:52 -05:00
|
|
|
editor.inputs['C-h'].doc = "Unhide all objects.";
|
|
|
|
|
|
|
|
editor.inputs['C-e'] = function() { editor.openpanel(assetexplorer); };
|
|
|
|
editor.inputs['C-e'].doc = "Open asset explorer.";
|
|
|
|
|
2023-09-26 13:34:02 -05:00
|
|
|
editor.inputs['C-l'] = function() { editor.openpanel(entitylistpanel); };
|
2023-09-11 15:07:36 -05:00
|
|
|
editor.inputs['C-l'].doc = "Open list of spawned entities.";
|
2023-08-24 16:22:52 -05:00
|
|
|
|
2023-10-11 17:22:41 -05:00
|
|
|
editor.inputs['C-i'] = function() {
|
2023-08-24 16:22:52 -05:00
|
|
|
if (editor.selectlist.length !== 1) return;
|
|
|
|
objectexplorer.obj = editor.selectlist[0];
|
|
|
|
editor.openpanel(objectexplorer);
|
|
|
|
};
|
2023-09-11 15:07:36 -05:00
|
|
|
editor.inputs['C-i'].doc = "Open the object explorer for a selected object.";
|
2023-10-11 17:22:41 -05:00
|
|
|
|
2023-08-24 16:22:52 -05:00
|
|
|
editor.inputs['C-d'] = function() {
|
|
|
|
if (editor.selectlist.length === 0) return;
|
|
|
|
var duped = editor.dup_objects(editor.selectlist);
|
|
|
|
editor.unselect();
|
|
|
|
editor.selectlist = duped;
|
|
|
|
};
|
|
|
|
editor.inputs['C-d'].doc = "Duplicate all selected objects.";
|
|
|
|
|
2023-11-15 16:42:39 -06:00
|
|
|
|
2023-08-24 16:22:52 -05:00
|
|
|
editor.inputs['C-m'] = function() {
|
2023-08-25 01:30:39 -05:00
|
|
|
if (editor.sel_comp) {
|
2023-10-29 16:39:45 -05:00
|
|
|
if ('flipy' in editor.sel_comp)
|
2023-08-25 01:30:39 -05:00
|
|
|
editor.sel_comp.flipy = !editor.sel_comp.flipy;
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-11-15 16:42:39 -06:00
|
|
|
editor.selectlist.forEach(function(x) { x.mirror([0,1]);});
|
2023-08-24 16:22:52 -05:00
|
|
|
};
|
|
|
|
editor.inputs['C-m'].doc = "Mirror selected objects on the Y axis.";
|
|
|
|
|
2023-08-25 01:30:39 -05:00
|
|
|
editor.inputs.m = function() {
|
|
|
|
if (editor.sel_comp) {
|
2023-10-29 16:39:45 -05:00
|
|
|
if ('flipx' in editor.sel_comp)
|
2023-08-25 01:30:39 -05:00
|
|
|
editor.sel_comp.flipx = !editor.sel_comp.flipx;
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-11-15 16:42:39 -06:00
|
|
|
editor.selectlist.forEach(x => x.mirror([1,0]));
|
2023-08-25 01:30:39 -05:00
|
|
|
};
|
2023-08-24 16:22:52 -05:00
|
|
|
editor.inputs.m.doc = "Mirror selected objects on the X axis.";
|
|
|
|
|
2023-11-15 16:42:39 -06:00
|
|
|
|
2023-08-24 16:22:52 -05:00
|
|
|
editor.inputs.q = function() { editor.comp_info = !editor.comp_info; };
|
|
|
|
editor.inputs.q.doc = "Toggle help for the selected component.";
|
|
|
|
|
|
|
|
editor.inputs.f = function() {
|
|
|
|
if (editor.selectlist.length === 0) return;
|
2023-09-14 17:37:04 -05:00
|
|
|
var bb = editor.selectlist[0].boundingbox();
|
|
|
|
editor.selectlist.forEach(function(obj) { bb = bb_expand(bb, obj.boundingbox()); });
|
2023-08-24 16:22:52 -05:00
|
|
|
editor.zoom_to_bb(bb);
|
|
|
|
};
|
|
|
|
editor.inputs.f.doc = "Find the selected objects.";
|
|
|
|
|
|
|
|
editor.inputs['C-f'] = function() {
|
|
|
|
if (editor.selectlist.length !== 1) return;
|
2023-09-22 09:44:58 -05:00
|
|
|
|
2023-08-24 16:22:52 -05:00
|
|
|
editor.edit_level = editor.selectlist[0];
|
|
|
|
editor.unselect();
|
2023-11-20 07:49:14 -06:00
|
|
|
editor.reset_undos();
|
2023-08-24 16:22:52 -05:00
|
|
|
};
|
|
|
|
editor.inputs['C-f'].doc = "Tunnel into the selected level object to edit it.";
|
|
|
|
|
2023-09-22 09:44:58 -05:00
|
|
|
editor.inputs['C-F'] = function() {
|
2023-09-29 13:16:59 -05:00
|
|
|
if (editor.edit_level.level === Primum) return;
|
2023-08-24 16:22:52 -05:00
|
|
|
|
|
|
|
editor.edit_level = editor.edit_level.level;
|
|
|
|
editor.unselect();
|
|
|
|
editor.reset_undos();
|
|
|
|
};
|
2023-09-22 09:44:58 -05:00
|
|
|
editor.inputs['C-F'].doc = "Tunnel out of the level you are editing, saving it in the process.";
|
2023-08-24 16:22:52 -05:00
|
|
|
|
|
|
|
editor.inputs['C-r'] = function() { editor.selectlist.forEach(function(x) { x.angle = -x.angle; }); };
|
|
|
|
editor.inputs['C-r'].doc = "Negate the selected's angle.";
|
|
|
|
|
|
|
|
editor.inputs.r = function() {
|
|
|
|
if (editor.sel_comp && 'angle' in editor.sel_comp) {
|
2023-10-02 17:03:01 -05:00
|
|
|
var relpos = Mouse.worldpos.sub(editor.sel_comp.gameobject.worldpos());
|
2023-08-24 16:22:52 -05:00
|
|
|
editor.startoffset = Math.atan2(relpos.y, relpos.x);
|
|
|
|
editor.startrot = editor.sel_comp.angle;
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-09-14 12:49:29 -05:00
|
|
|
editor.rotlist = [];
|
|
|
|
editor.selectlist.forEach(function(x) {
|
|
|
|
var relpos = Mouse.worldpos.sub(editor.cursor);
|
|
|
|
editor.rotlist.push({
|
|
|
|
obj: x,
|
|
|
|
angle: x.angle,
|
|
|
|
pos: x.pos,
|
|
|
|
offset: x.pos.sub(editor.cursor),
|
|
|
|
rotoffset: Math.atan2(relpos.y, relpos.x),
|
|
|
|
});
|
|
|
|
});
|
2023-08-24 16:22:52 -05:00
|
|
|
};
|
|
|
|
editor.inputs.r.doc = "Rotate selected using the mouse while held down.";
|
|
|
|
|
2023-09-14 12:49:29 -05:00
|
|
|
editor.inputs.r.released = function() { editor.rotlist = []; }
|
2023-09-11 17:09:21 -05:00
|
|
|
|
2023-10-09 18:10:10 -05:00
|
|
|
editor.inputs.f5 = function()
|
|
|
|
{
|
|
|
|
editor.start_play_ed();
|
|
|
|
}
|
|
|
|
|
|
|
|
editor.inputs.f5.doc = "Start game from 'debug' if it exists; otherwise, from 'game'.";
|
2023-08-27 21:57:19 -05:00
|
|
|
|
2023-11-20 15:57:23 -06:00
|
|
|
editor.inputs.f6 = function()
|
|
|
|
{
|
|
|
|
editor.start_play();
|
|
|
|
}
|
|
|
|
|
|
|
|
editor.inputs.f6.doc = "Start game as if the player started it.";
|
|
|
|
|
2023-08-27 21:57:19 -05:00
|
|
|
editor.inputs['M-p'] = function() {
|
|
|
|
if (Game.playing())
|
|
|
|
Game.pause();
|
2023-08-24 16:22:52 -05:00
|
|
|
|
2023-08-27 21:57:19 -05:00
|
|
|
Game.step();
|
|
|
|
}
|
|
|
|
editor.inputs['M-p'].doc = "Do one time step, pausing if necessary.";
|
|
|
|
|
|
|
|
editor.inputs['C-M-p'] = function() {
|
2023-10-06 12:38:49 -05:00
|
|
|
if (!Game.playing()) {
|
|
|
|
editor.start_play_ed();
|
|
|
|
}
|
2023-08-27 21:57:19 -05:00
|
|
|
Log.warn(`Starting edited level ...`);
|
|
|
|
};
|
|
|
|
editor.inputs['C-M-p'].doc = "Start game from currently edited level.";
|
2023-08-24 16:22:52 -05:00
|
|
|
|
2023-08-27 21:57:19 -05:00
|
|
|
editor.inputs['C-q'] = function() {
|
2023-10-04 08:18:09 -05:00
|
|
|
|
2023-08-24 16:22:52 -05:00
|
|
|
};
|
2023-08-27 21:57:19 -05:00
|
|
|
editor.inputs['C-q'].doc = "Quit simulation and return to editor.";
|
|
|
|
|
|
|
|
var rebinder = {};
|
|
|
|
rebinder.inputs = {};
|
|
|
|
rebinder.inputs.any = function(cmd) {
|
|
|
|
|
2023-08-24 16:22:52 -05:00
|
|
|
};
|
2023-08-27 21:57:19 -05:00
|
|
|
|
|
|
|
editor.inputs['C-space'] = function() {
|
|
|
|
|
|
|
|
};
|
|
|
|
editor.inputs['C-space'].doc = "Search to execute a specific command.";
|
|
|
|
|
|
|
|
editor.inputs['M-m'] = function() {
|
2023-08-28 17:00:53 -05:00
|
|
|
// Player.players[0].control(rebinder);
|
2023-08-27 21:57:19 -05:00
|
|
|
};
|
|
|
|
editor.inputs['M-m'].doc = "Rebind a shortcut. Usage: M-m SHORTCUT TARGET";
|
|
|
|
|
|
|
|
editor.inputs['M-S-8'] = function() {
|
|
|
|
editor.camera_recall_pop();
|
|
|
|
};
|
|
|
|
editor.inputs['M-S-8'].doc = "Jump to last location.";
|
2023-08-24 16:22:52 -05:00
|
|
|
|
|
|
|
editor.inputs.escape = function() { editor.openpanel(quitpanel); }
|
|
|
|
editor.inputs.escape.doc = "Quit editor.";
|
|
|
|
|
|
|
|
editor.inputs['C-s'] = function() {
|
2023-10-16 19:59:58 -05:00
|
|
|
var saveobj = undefined;
|
2023-09-29 13:16:59 -05:00
|
|
|
if (editor.selectlist.length === 0) {
|
2023-10-16 19:59:58 -05:00
|
|
|
if (editor.edit_level === editor.desktop) {
|
|
|
|
saveaspanel.stem = editor.edit_level.ur.toString();
|
|
|
|
saveaspanel.obj = editor.edit_level;
|
|
|
|
editor.openpanel(saveaspanel);
|
|
|
|
return;
|
|
|
|
} else
|
|
|
|
saveobj = editor.edit_level;
|
|
|
|
} else if (editor.selectlist.length === 1)
|
|
|
|
saveobj = editor.selectlist[0];
|
|
|
|
|
2023-10-26 11:48:02 -05:00
|
|
|
// saveobj._ed.check_dirty();
|
|
|
|
// if (!saveobj._ed.dirty) return;
|
2023-10-16 19:59:58 -05:00
|
|
|
|
|
|
|
var savejs = saveobj.json_obj();
|
|
|
|
Object.merge(saveobj.__proto__, savejs);
|
2023-10-26 11:48:02 -05:00
|
|
|
if (savejs.objects) saveobj.__proto__.objects = savejs.objects;
|
2023-11-17 15:16:13 -06:00
|
|
|
var path = prototypes.ur_stem(saveobj.ur.toString()) + ".json";
|
2023-10-02 17:03:01 -05:00
|
|
|
|
2023-10-16 19:59:58 -05:00
|
|
|
IO.slurpwrite(JSON.stringify(saveobj.__proto__,null,1), path);
|
2023-10-10 17:37:58 -05:00
|
|
|
Log.warn(`Wrote to file ${path}`);
|
2023-10-26 11:48:02 -05:00
|
|
|
|
|
|
|
Object.values(saveobj.objects).forEach(function(x) { x._ed.check_dirty(); });
|
2023-10-30 17:41:32 -05:00
|
|
|
|
2023-11-29 12:40:13 -06:00
|
|
|
|
|
|
|
Game.all_objects(function(x) {
|
2023-11-16 09:27:04 -06:00
|
|
|
if (typeof x !== 'object') return;
|
|
|
|
if (!('_ed' in x)) return;
|
2023-10-30 17:41:32 -05:00
|
|
|
if (x._ed.dirty) return;
|
|
|
|
x.revert();
|
|
|
|
x._ed.check_dirty();
|
|
|
|
});
|
2023-08-24 16:22:52 -05:00
|
|
|
};
|
|
|
|
editor.inputs['C-s'].doc = "Save selected.";
|
|
|
|
|
2023-09-22 09:44:58 -05:00
|
|
|
editor.inputs['C-S'] = function() {
|
2023-09-26 13:34:02 -05:00
|
|
|
if (editor.selectlist.length !== 1) return;
|
2023-10-30 17:41:32 -05:00
|
|
|
saveaspanel.stem = this.selectlist[0].ur;
|
2023-08-24 16:22:52 -05:00
|
|
|
editor.openpanel(saveaspanel);
|
|
|
|
};
|
2023-09-22 09:44:58 -05:00
|
|
|
editor.inputs['C-S'].doc = "Save selected as.";
|
2023-08-24 16:22:52 -05:00
|
|
|
|
|
|
|
editor.inputs['C-z'] = function() { editor.undo(); };
|
|
|
|
editor.inputs['C-z'].doc = "Undo the last change made.";
|
|
|
|
|
|
|
|
editor.inputs['C-S-z'] = function() { editor.redo(); };
|
|
|
|
editor.inputs['C-S-z'].doc = "Redo the last undo.";
|
|
|
|
|
2023-10-06 12:38:49 -05:00
|
|
|
editor.inputs.t = function() { editor.selectlist.forEach(function(x) { x._ed.selectable = false; }); };
|
2023-08-24 16:22:52 -05:00
|
|
|
editor.inputs.t.doc = "Lock selected objects to make them non selectable.";
|
|
|
|
|
2023-10-06 12:38:49 -05:00
|
|
|
editor.inputs['M-t'] = function() { editor.edit_level.objects.forEach(function(x) { x._ed.selectable = true; }); };
|
2023-08-24 16:22:52 -05:00
|
|
|
editor.inputs['M-t'].doc = "Unlock all objects in current level.";
|
|
|
|
|
|
|
|
editor.inputs['C-n'] = function() {
|
2023-10-11 17:22:41 -05:00
|
|
|
/* if (editor.edit_level._ed.dirty) {
|
2023-08-24 16:22:52 -05:00
|
|
|
Log.info("Level has changed; save before starting a new one.");
|
|
|
|
editor.openpanel(gen_notify("Level is changed. Are you sure you want to close it?", _ => editor.clear_level()));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-10-11 17:22:41 -05:00
|
|
|
editor.clear_level();
|
|
|
|
*/
|
2023-08-24 16:22:52 -05:00
|
|
|
};
|
|
|
|
editor.inputs['C-n'].doc = "Open a new level.";
|
|
|
|
|
|
|
|
editor.inputs['C-o'] = function() {
|
|
|
|
editor.openpanel(openlevelpanel);
|
|
|
|
};
|
|
|
|
editor.inputs['C-o'].doc = "Open a level.";
|
|
|
|
|
|
|
|
editor.inputs['C-M-o'] = function() {
|
|
|
|
if (editor.selectlist.length === 1 && editor.selectlist[0].file) {
|
2023-10-05 08:02:12 -05:00
|
|
|
if (editor.edit_level._ed.dirty) return;
|
2023-08-24 16:22:52 -05:00
|
|
|
editor.load(editor.selectlist[0].file);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
editor.inputs['C-M-o'].doc = "Revert opened level back to its disk form.";
|
|
|
|
|
|
|
|
editor.inputs['C-S-o'] = function() {
|
2023-10-05 08:02:12 -05:00
|
|
|
if (!editor.edit_level._ed.dirty)
|
2023-08-24 16:22:52 -05:00
|
|
|
editor.load_prev();
|
|
|
|
};
|
|
|
|
editor.inputs['C-S-o'].doc = "Open previous level.";
|
|
|
|
|
2023-09-11 15:07:36 -05:00
|
|
|
editor.inputs['C-y'] = function() {
|
2023-08-24 16:22:52 -05:00
|
|
|
texteditor.on_close = function() { editor.edit_level.script = texteditor.value;};
|
|
|
|
|
|
|
|
editor.openpanel(texteditor);
|
2023-09-29 08:27:34 -05:00
|
|
|
texteditor.value = "";
|
2023-08-24 16:22:52 -05:00
|
|
|
texteditor.start();
|
|
|
|
};
|
2023-09-11 15:07:36 -05:00
|
|
|
editor.inputs['C-y'].doc = "Open script editor for the level.";
|
2023-04-22 16:44:26 -05:00
|
|
|
|
2023-09-11 15:07:36 -05:00
|
|
|
editor.inputs['M-y'] = function() { editor.programmode = !editor.programmode; };
|
|
|
|
editor.inputs['M-y'].doc = "Toggle program mode.";
|
2023-04-22 16:44:26 -05:00
|
|
|
|
2023-08-24 16:22:52 -05:00
|
|
|
editor.inputs.minus = function() {
|
|
|
|
if (!editor.selectlist.empty) {
|
|
|
|
editor.selectlist.forEach(function(x) { x.draw_layer--; });
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (editor.working_layer > -1)
|
|
|
|
editor.working_layer--;
|
|
|
|
};
|
|
|
|
editor.inputs.minus.doc = "Go down one working layer, or, move selected objects down one layer.";
|
|
|
|
|
|
|
|
editor.inputs.plus = function() {
|
|
|
|
if (!editor.selectlist.empty) {
|
|
|
|
editor.selectlist.forEach(x => x.draw_layer++);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (editor.working_layer < 4)
|
|
|
|
editor.working_layer++;
|
|
|
|
};
|
|
|
|
|
|
|
|
editor.inputs.plus.doc = "Go up one working layer, or, move selected objects down one layer.";
|
|
|
|
|
2023-08-25 01:30:39 -05:00
|
|
|
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.";
|
|
|
|
|
2023-09-25 16:34:48 -05:00
|
|
|
|
2023-08-25 01:30:39 -05:00
|
|
|
editor.inputs.f2 = function() {
|
|
|
|
objectexplorer.on_close = save_configs;
|
|
|
|
objectexplorer.obj = configs;
|
|
|
|
this.openpanel(objectexplorer);
|
|
|
|
};
|
|
|
|
editor.inputs.f2.doc = "Open configurations object.";
|
|
|
|
|
2023-09-14 12:49:29 -05:00
|
|
|
editor.inputs.lm = function() { editor.sel_start = Mouse.worldpos; };
|
2023-08-25 01:30:39 -05:00
|
|
|
editor.inputs.lm.doc = "Selection box.";
|
|
|
|
|
2023-09-11 17:09:21 -05:00
|
|
|
editor.inputs.lm.released = function() {
|
|
|
|
Mouse.normal();
|
2023-10-02 07:58:17 -05:00
|
|
|
editor.unselect();
|
2023-09-11 17:09:21 -05:00
|
|
|
|
|
|
|
if (!editor.sel_start) return;
|
|
|
|
|
|
|
|
if (editor.sel_comp) {
|
|
|
|
editor.sel_start = undefined;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var selects = [];
|
|
|
|
|
|
|
|
/* TODO: selects somehow gets undefined objects in here */
|
2023-11-20 07:49:14 -06:00
|
|
|
if (Vector.equal(Mouse.worldpos, editor.sel_start, 5)) {
|
2023-09-11 17:09:21 -05:00
|
|
|
var sel = editor.try_select();
|
|
|
|
if (sel) selects.push(sel);
|
|
|
|
} else {
|
2023-09-14 12:49:29 -05:00
|
|
|
var box = points2cwh(editor.sel_start, Mouse.worldpos);
|
2023-09-11 17:09:21 -05:00
|
|
|
|
|
|
|
box.pos = box.c;
|
|
|
|
|
|
|
|
var hits = physics.box_query(box);
|
|
|
|
|
|
|
|
hits.forEach(function(x, i) {
|
|
|
|
var obj = editor.do_select(x);
|
|
|
|
if (obj)
|
|
|
|
selects.push(obj);
|
|
|
|
},editor);
|
|
|
|
|
|
|
|
var levels = editor.edit_level.objects.filter(function(x) { return x.file; });
|
|
|
|
var lvlpos = [];
|
|
|
|
levels.forEach(function(x) { lvlpos.push(x.pos); });
|
|
|
|
var lvlhits = physics.box_point_query(box, lvlpos);
|
|
|
|
|
|
|
|
lvlhits.forEach(function(x) { selects.push(levels[x]); });
|
|
|
|
}
|
|
|
|
|
|
|
|
this.sel_start = undefined;
|
|
|
|
selects = selects.flat();
|
|
|
|
selects = selects.unique();
|
|
|
|
|
|
|
|
if (selects.empty) return;
|
|
|
|
|
|
|
|
if (Keys.shift()) {
|
|
|
|
selects.forEach(function(x) {
|
|
|
|
this.selectlist.push_unique(x);
|
|
|
|
}, this);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Keys.ctrl()) {
|
|
|
|
selects.forEach(function(x) {
|
|
|
|
this.selectlist.remove(x);
|
|
|
|
}, this);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
editor.selectlist = [];
|
|
|
|
selects.forEach(function(x) {
|
|
|
|
if (x !== undefined)
|
|
|
|
this.selectlist.push(x);
|
|
|
|
}, this);
|
|
|
|
};
|
|
|
|
|
|
|
|
editor.inputs.rm = function() {
|
|
|
|
if (editor.brush_obj)
|
|
|
|
editor.brush_obj = undefined;
|
|
|
|
|
|
|
|
if (editor.sel_comp) {
|
|
|
|
editor.sel_comp = undefined;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
editor.unselect();
|
|
|
|
};
|
|
|
|
|
2023-09-29 08:27:34 -05:00
|
|
|
editor.try_pick = function()
|
|
|
|
{
|
|
|
|
editor.grabselect = [];
|
|
|
|
|
2023-10-18 17:20:23 -05:00
|
|
|
if (editor.sel_comp && 'pick' in editor.sel_comp)
|
|
|
|
return editor.sel_comp.pick(Mouse.worldpos);
|
2023-09-29 08:27:34 -05:00
|
|
|
|
2023-10-18 17:20:23 -05:00
|
|
|
return editor.try_select();
|
2023-09-29 08:27:34 -05:00
|
|
|
}
|
|
|
|
|
2023-09-11 17:09:21 -05:00
|
|
|
editor.inputs.mm = function() {
|
|
|
|
if (editor.brush_obj) {
|
|
|
|
editor.selectlist = editor.dup_objects([editor.brush_obj]);
|
2023-09-14 12:49:29 -05:00
|
|
|
editor.selectlist[0].pos = Mouse.worldpos;
|
2023-09-11 17:09:21 -05:00
|
|
|
editor.grabselect = editor.selectlist[0];
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-10-18 17:20:23 -05:00
|
|
|
var o = editor.try_pick();
|
|
|
|
if (!o) return;
|
2023-10-30 17:41:32 -05:00
|
|
|
// editor.selectlist = [o];
|
2023-10-18 17:20:23 -05:00
|
|
|
editor.grabselect = [o];
|
2023-09-11 17:09:21 -05:00
|
|
|
};
|
2023-09-12 17:19:46 -05:00
|
|
|
editor.inputs['C-mm'] = editor.inputs.mm;
|
2023-09-11 17:09:21 -05:00
|
|
|
|
2023-10-17 12:22:06 -05:00
|
|
|
editor.inputs['C-M-lm'] = function()
|
|
|
|
{
|
2023-11-29 12:40:13 -06:00
|
|
|
var go = physics.pos_query(Mouse.worldpos);
|
2023-10-17 12:22:06 -05:00
|
|
|
if (!go) return;
|
|
|
|
editor.edit_level = go.level;
|
|
|
|
}
|
|
|
|
|
2023-09-12 17:19:46 -05:00
|
|
|
editor.inputs['C-M-mm'] = function() {
|
|
|
|
editor.mousejoy = Mouse.pos;
|
|
|
|
editor.joystart = editor.camera.pos;
|
2023-09-11 17:09:21 -05:00
|
|
|
};
|
|
|
|
|
2023-09-12 17:19:46 -05:00
|
|
|
editor.inputs['C-M-rm'] = function() {
|
|
|
|
editor.mousejoy = Mouse.pos;
|
|
|
|
editor.z_start = editor.camera.zoom;
|
|
|
|
Mouse.disabled();
|
|
|
|
};
|
2023-09-11 17:09:21 -05:00
|
|
|
|
2023-09-12 17:19:46 -05:00
|
|
|
editor.inputs.rm.released = function() {
|
|
|
|
editor.mousejoy = undefined;
|
|
|
|
editor.z_start = undefined;
|
|
|
|
Mouse.normal();
|
|
|
|
};
|
|
|
|
|
|
|
|
editor.inputs.mm.released = function () {
|
|
|
|
Mouse.normal();
|
2023-09-14 12:49:29 -05:00
|
|
|
this.grabselect = [];
|
2023-09-12 17:19:46 -05:00
|
|
|
editor.mousejoy = undefined;
|
|
|
|
editor.joystart = undefined;
|
|
|
|
};
|
|
|
|
editor.inputs.mouse = {};
|
|
|
|
editor.inputs.mouse.move = function(pos, dpos)
|
|
|
|
{
|
|
|
|
if (editor.mousejoy) {
|
|
|
|
if (editor.z_start)
|
2023-09-14 12:49:29 -05:00
|
|
|
editor.camera.zoom -= dpos.y/500;
|
2023-09-12 17:19:46 -05:00
|
|
|
else if (editor.joystart)
|
2023-11-16 09:27:04 -06:00
|
|
|
editor.camera.pos = editor.camera.pos.sub(Game.camera.dir_view2world(dpos));
|
2023-09-12 17:19:46 -05:00
|
|
|
}
|
2023-09-14 12:49:29 -05:00
|
|
|
|
2023-09-27 12:36:32 -05:00
|
|
|
editor.grabselect?.forEach(function(x) {
|
2023-11-16 09:27:04 -06:00
|
|
|
x.move(Game.camera.dir_view2world(dpos));
|
2023-09-27 12:36:32 -05:00
|
|
|
if ('sync' in x)
|
|
|
|
x.sync();
|
|
|
|
});
|
2023-09-12 17:19:46 -05:00
|
|
|
|
2023-09-14 12:49:29 -05:00
|
|
|
var relpos = Mouse.worldpos.sub(editor.cursor);
|
|
|
|
var dist = Vector.length(relpos);
|
|
|
|
|
|
|
|
editor.scalelist?.forEach(function(x) {
|
|
|
|
var scalediff = dist / x.scaleoffset;
|
2023-11-20 07:49:14 -06:00
|
|
|
if (typeof x.obj.scale === 'number')
|
|
|
|
x.obj.scale = x.scale * scalediff;
|
|
|
|
else {
|
|
|
|
x.obj.scale = x.scale.map(x=> x * scalediff);
|
|
|
|
if (x.offset)
|
|
|
|
x.obj.pos = editor.cursor.add(x.offset.scale(scalediff));
|
|
|
|
}
|
2023-09-14 12:49:29 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
editor.rotlist?.forEach(function(x) {
|
|
|
|
var anglediff = Math.atan2(relpos.y, relpos.x) - x.rotoffset;
|
|
|
|
|
|
|
|
x.obj.angle = x.angle + Math.rad2deg(anglediff);
|
|
|
|
if (x.pos)
|
|
|
|
x.obj.pos = x.pos.sub(x.offset).add(x.offset.rotate(anglediff));
|
|
|
|
});
|
2023-09-12 17:19:46 -05:00
|
|
|
}
|
2023-09-11 17:09:21 -05:00
|
|
|
|
2023-09-24 11:26:44 -05:00
|
|
|
editor.inputs.mouse.scroll = function(scroll)
|
|
|
|
{
|
|
|
|
scroll.y *= -1;
|
2023-11-16 09:27:04 -06:00
|
|
|
// editor.grabselect?.forEach(x => x.move(Game.camera.dir_view2world(scroll)));
|
|
|
|
editor.camera.move(Game.camera.dir_view2world(scroll.scale(-3)));
|
2023-09-15 22:40:19 -05:00
|
|
|
}
|
|
|
|
|
2023-09-29 08:27:34 -05:00
|
|
|
editor.inputs.mouse['C-scroll'] = function(scroll)
|
2023-09-15 22:40:19 -05:00
|
|
|
{
|
|
|
|
editor.camera.zoom += scroll.y/100;
|
|
|
|
}
|
|
|
|
|
2023-09-14 12:49:29 -05:00
|
|
|
editor.inputs['C-M-S-lm'] = function() { editor.selectlist[0].set_center(Mouse.worldpos); };
|
2023-08-25 01:30:39 -05:00
|
|
|
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.";
|
2023-09-21 08:38:23 -05:00
|
|
|
editor.inputs['S-d'] = editor.inputs.delete;
|
2023-09-26 08:37:19 -05:00
|
|
|
editor.inputs['C-k'] = editor.inputs.delete;
|
2023-08-25 01:30:39 -05:00
|
|
|
|
|
|
|
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() {
|
2023-10-18 17:20:23 -05:00
|
|
|
if (editor.selectlist.length === 0) {
|
|
|
|
var o = editor.try_pick();
|
|
|
|
if (!o) return;
|
|
|
|
editor.selectlist = [o];
|
|
|
|
}
|
2023-10-29 16:39:45 -05:00
|
|
|
|
|
|
|
if (editor.sel_comp && 'pick' in editor.sel_comp) {
|
|
|
|
var o = editor.sel_comp.pick(Mouse.worldpos);
|
|
|
|
if (o) editor.grabselect = [o];
|
|
|
|
return;
|
|
|
|
}
|
2023-10-18 17:20:23 -05:00
|
|
|
|
2023-10-29 16:39:45 -05:00
|
|
|
editor.grabselect = editor.selectlist.slice();
|
2023-09-12 17:19:46 -05:00
|
|
|
};
|
2023-10-29 16:39:45 -05:00
|
|
|
|
2023-09-14 12:49:29 -05:00
|
|
|
editor.inputs.g.doc = "Move selected objects.";
|
|
|
|
editor.inputs.g.released = function() { editor.grabselect = []; Mouse.normal(); };
|
2023-09-12 17:19:46 -05:00
|
|
|
|
|
|
|
editor.inputs.up = function() { this.key_move([0,1]); };
|
|
|
|
editor.inputs.up.rep = true;
|
|
|
|
|
|
|
|
editor.inputs.left = function() { this.key_move([-1,0]); };
|
|
|
|
editor.inputs.left.rep = true;
|
|
|
|
|
|
|
|
editor.inputs.right = function() { this.key_move([1,0]); };
|
|
|
|
editor.inputs.right.rep = true;
|
|
|
|
|
|
|
|
editor.inputs.down = function() { this.key_move([0,-1]); };
|
|
|
|
editor.inputs.down.rep = true;
|
|
|
|
|
2023-08-25 01:30:39 -05:00
|
|
|
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)
|
2023-09-11 17:09:21 -05:00
|
|
|
this.sel_comp = undefined;
|
2023-08-25 01:30:39 -05:00
|
|
|
else
|
|
|
|
this.sel_comp = sel.nth(idx);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
editor.inputs.tab.doc = "Cycle through selected object's components.";
|
|
|
|
|
|
|
|
editor.inputs['C-g'] = function() {
|
2023-09-11 17:09:21 -05:00
|
|
|
if (!this.selectlist) return;
|
2023-08-25 01:30:39 -05:00
|
|
|
this.selectlist = this.dup_objects(this.selectlist);
|
|
|
|
editor.inputs.g();
|
|
|
|
};
|
|
|
|
editor.inputs['C-g'].doc = "Duplicate selected objects, then move them.";
|
|
|
|
|
2023-10-29 16:39:45 -05:00
|
|
|
editor.inputs['M-g'] = function()
|
|
|
|
{
|
|
|
|
if (this.sel_comp && 'pick_all' in this.sel_comp)
|
|
|
|
this.grabselect = this.sel_comp.pick_all();
|
|
|
|
}
|
|
|
|
editor.inputs['M-g'].doc = "Move all.";
|
|
|
|
|
2023-08-25 01:30:39 -05:00
|
|
|
editor.inputs['C-lb'] = function() {
|
2023-11-29 12:40:13 -06:00
|
|
|
editor.grid_size -= Keys.shift() ? 10 : 1;
|
|
|
|
if (editor.grid_size <= 0) editor.grid_size = 1;
|
2023-08-25 01:30:39 -05:00
|
|
|
};
|
|
|
|
editor.inputs['C-lb'].doc = "Decrease grid size. Hold shift to decrease it more.";
|
|
|
|
editor.inputs['C-lb'].rep = true;
|
|
|
|
|
2023-11-29 12:40:13 -06:00
|
|
|
editor.inputs['C-rb'] = function() { editor.grid_size += Keys.shift() ? 10 : 1; };
|
2023-08-25 01:30:39 -05:00
|
|
|
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 = [];
|
2023-11-29 12:40:13 -06:00
|
|
|
this.killcom = physics.com(this.selectlist.map(x=>x.pos));
|
2023-08-25 01:30:39 -05:00
|
|
|
|
|
|
|
this.selectlist.forEach(function(x) {
|
2023-09-26 08:37:19 -05:00
|
|
|
this.killring.push(x.make_ur());
|
2023-08-25 01:30:39 -05:00
|
|
|
},this);
|
|
|
|
};
|
|
|
|
editor.inputs['C-c'].doc = "Copy selected objects to killring.";
|
|
|
|
|
|
|
|
editor.inputs['C-x'] = function() {
|
2023-09-26 08:37:19 -05:00
|
|
|
editor.inputs['C-c'].call(editor);
|
|
|
|
this.selectlist.forEach(function(x) { x.kill(); });
|
|
|
|
editor.unselect();
|
2023-08-25 01:30:39 -05:00
|
|
|
};
|
|
|
|
editor.inputs['C-x'].doc = "Cut objects to killring.";
|
|
|
|
|
2023-09-26 08:37:19 -05:00
|
|
|
editor.inputs['C-v'] = function() {
|
|
|
|
this.unselect();
|
|
|
|
this.killring.forEach(function(x) {
|
|
|
|
editor.selectlist.push(editor.edit_level.spawn(x));
|
|
|
|
});
|
|
|
|
|
|
|
|
this.selectlist.forEach(function(x) {
|
|
|
|
x.pos = x.pos.sub(this.killcom).add(this.cursor);
|
|
|
|
},this);
|
|
|
|
};
|
2023-08-25 01:30:39 -05:00
|
|
|
editor.inputs['C-v'].doc = "Pull objects from killring to world.";
|
|
|
|
|
2023-09-14 12:49:29 -05:00
|
|
|
editor.inputs.char = function(c) {
|
2023-11-02 17:25:00 -05:00
|
|
|
if (c === '0') {
|
|
|
|
this.camera.pos = [0,0];
|
|
|
|
this.camera.zoom = 1;
|
|
|
|
}
|
2023-08-25 01:30:39 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
var brushmode = {};
|
|
|
|
brushmode.inputs = {};
|
2023-09-26 08:37:19 -05:00
|
|
|
brushmode.inputs.lm = function() { editor.inputs['C-v'].call(editor); };
|
2023-08-25 01:30:39 -05:00
|
|
|
brushmode.inputs.lm.doc = "Paste selected brush.";
|
|
|
|
|
|
|
|
brushmode.inputs.b = function() {
|
|
|
|
if (editor.brush_obj) {
|
2023-09-11 17:09:21 -05:00
|
|
|
editor.brush_obj = undefined;
|
2023-08-25 01:30:39 -05:00
|
|
|
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() {};
|
|
|
|
|
2023-09-14 12:49:29 -05:00
|
|
|
editor.scalelist = [];
|
2023-08-24 16:22:52 -05:00
|
|
|
editor.inputs.s = function() {
|
2023-09-14 12:49:29 -05:00
|
|
|
var scaleoffset = Vector.length(Mouse.worldpos.sub(editor.cursor));
|
|
|
|
editor.scalelist = [];
|
|
|
|
|
2023-08-24 16:22:52 -05:00
|
|
|
if (editor.sel_comp) {
|
|
|
|
if (!('scale' in editor.sel_comp)) return;
|
2023-09-14 12:49:29 -05:00
|
|
|
editor.scalelist.push({
|
|
|
|
obj: editor.sel_comp,
|
|
|
|
scale: editor.sel_comp.scale,
|
|
|
|
scaleoffset: scaleoffset,
|
|
|
|
});
|
2023-08-24 16:22:52 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-09-14 12:49:29 -05:00
|
|
|
editor.selectlist.forEach(function(x) {
|
|
|
|
editor.scalelist.push({
|
|
|
|
obj: x,
|
|
|
|
scale: x.scale,
|
|
|
|
offset: x.pos.sub(editor.cursor),
|
|
|
|
scaleoffset: scaleoffset,
|
|
|
|
});
|
|
|
|
});
|
2023-08-24 16:22:52 -05:00
|
|
|
};
|
|
|
|
editor.inputs.s.doc = "Scale selected.";
|
2023-04-22 16:44:26 -05:00
|
|
|
|
2023-09-14 12:49:29 -05:00
|
|
|
editor.inputs.s.released = function() { this.scalelist = []; };
|
2023-09-11 17:09:21 -05:00
|
|
|
|
2023-04-22 16:44:26 -05:00
|
|
|
var inputpanel = {
|
|
|
|
title: "untitled",
|
2023-10-16 19:59:58 -05:00
|
|
|
toString() { return this.title; },
|
2023-04-22 16:44:26 -05:00
|
|
|
value: "",
|
|
|
|
on: false,
|
2023-10-04 17:57:37 -05:00
|
|
|
pos:[100,Window.height-50],
|
|
|
|
wh:[350,600],
|
|
|
|
anchor: [0,1],
|
2023-10-06 12:38:49 -05:00
|
|
|
padding:[5,-15],
|
2023-10-04 17:57:37 -05:00
|
|
|
|
2023-04-22 16:44:26 -05:00
|
|
|
gui() {
|
2023-10-09 13:03:12 -05:00
|
|
|
this.win ??= Mum.window({width:this.wh.x,height:this.wh.y, color:Color.black.alpha(0.1), anchor:this.anchor, padding:this.padding});
|
2023-10-04 17:57:37 -05:00
|
|
|
var itms = this.guibody();
|
|
|
|
if (!Array.isArray(itms)) itms = [itms];
|
2023-10-06 12:38:49 -05:00
|
|
|
if (this.title)
|
|
|
|
this.win.items = [
|
|
|
|
Mum.column({items: [
|
|
|
|
Mum.text({str:this.title}),
|
|
|
|
...itms
|
|
|
|
]})
|
|
|
|
];
|
|
|
|
else
|
|
|
|
this.win.items = itms;
|
|
|
|
this.win.draw(this.pos.slice());
|
2023-04-22 16:44:26 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
guibody() {
|
2023-10-04 17:57:37 -05:00
|
|
|
return [
|
|
|
|
Mum.text({str:this.value, color:Color.green}),
|
2023-10-06 12:38:49 -05:00
|
|
|
Mum.button({str:"SUBMIT", action:this.submit.bind(this)})
|
2023-10-04 17:57:37 -05:00
|
|
|
];
|
2023-04-22 16:44:26 -05:00
|
|
|
},
|
|
|
|
|
2023-10-16 19:59:58 -05:00
|
|
|
open() {
|
2023-04-22 16:44:26 -05:00
|
|
|
this.on = true;
|
|
|
|
this.value = "";
|
|
|
|
this.start();
|
|
|
|
this.keycb();
|
|
|
|
},
|
|
|
|
|
|
|
|
start() {},
|
|
|
|
|
|
|
|
close() {
|
2023-08-28 17:00:53 -05:00
|
|
|
Player.players[0].uncontrol(this);
|
2023-04-22 16:44:26 -05:00
|
|
|
this.on = false;
|
|
|
|
if ('on_close' in this)
|
|
|
|
this.on_close();
|
|
|
|
},
|
|
|
|
|
|
|
|
action() {
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
closeonsubmit: true,
|
|
|
|
submit() {
|
|
|
|
if (!this.submit_check()) return;
|
|
|
|
this.action();
|
|
|
|
if (this.closeonsubmit)
|
|
|
|
this.close();
|
|
|
|
},
|
|
|
|
|
|
|
|
submit_check() { return true; },
|
|
|
|
|
|
|
|
keycb() {},
|
2023-10-04 17:57:37 -05:00
|
|
|
|
|
|
|
caret: 0,
|
2023-10-05 13:33:43 -05:00
|
|
|
|
|
|
|
reset_value() {
|
|
|
|
this.value = "";
|
|
|
|
this.caret = 0;
|
|
|
|
},
|
2023-04-22 16:44:26 -05:00
|
|
|
|
|
|
|
input_backspace_pressrep() {
|
|
|
|
this.value = this.value.slice(0,-1);
|
|
|
|
this.keycb();
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2023-09-14 12:49:29 -05:00
|
|
|
inputpanel.inputs = {};
|
2023-10-09 13:03:12 -05:00
|
|
|
|
|
|
|
inputpanel.inputs.post = function()
|
|
|
|
{
|
|
|
|
this.keycb();
|
|
|
|
}
|
|
|
|
|
2023-10-04 17:57:37 -05:00
|
|
|
inputpanel.inputs.char = function(c) {
|
|
|
|
this.value = this.value.slice(0,this.caret) + c + this.value.slice(this.caret);
|
|
|
|
this.caret++;
|
|
|
|
}
|
|
|
|
inputpanel.inputs['C-d'] = function() { this.value = this.value.slice(0,this.caret) + this.value.slice(this.caret+1); };
|
2023-10-09 13:03:12 -05:00
|
|
|
inputpanel.inputs['C-d'].rep = true;
|
|
|
|
inputpanel.inputs.tab = function() {
|
|
|
|
this.value = tab_complete(this.value, this.assets);
|
|
|
|
this.caret = this.value.length;
|
|
|
|
}
|
2023-09-14 12:49:29 -05:00
|
|
|
inputpanel.inputs.escape = function() { this.close(); }
|
2023-10-05 08:02:12 -05:00
|
|
|
inputpanel.inputs['C-b'] = function() {
|
|
|
|
if (this.caret === 0) return;
|
|
|
|
this.caret--;
|
|
|
|
};
|
2023-10-09 13:03:12 -05:00
|
|
|
inputpanel.inputs['C-b'].rep = true;
|
|
|
|
inputpanel.inputs['C-u'] = function()
|
|
|
|
{
|
|
|
|
this.value = this.value.slice(this.caret);
|
|
|
|
this.caret = 0;
|
|
|
|
}
|
2023-10-05 13:33:43 -05:00
|
|
|
inputpanel.inputs['C-f'] = function() {
|
|
|
|
if (this.caret === this.value.length) return;
|
|
|
|
this.caret++;
|
|
|
|
};
|
2023-10-09 13:03:12 -05:00
|
|
|
inputpanel.inputs['C-f'].rep = true;
|
2023-10-05 08:02:12 -05:00
|
|
|
inputpanel.inputs['C-a'] = function() { this.caret = 0; };
|
2023-10-05 13:33:43 -05:00
|
|
|
inputpanel.inputs['C-e'] = function() { this.caret = this.value.length; };
|
2023-10-04 17:57:37 -05:00
|
|
|
inputpanel.inputs.backspace = function() {
|
2023-10-05 08:02:12 -05:00
|
|
|
if (this.caret === 0) return;
|
2023-10-04 17:57:37 -05:00
|
|
|
this.value = this.value.slice(0,this.caret-1) + this.value.slice(this.caret);
|
|
|
|
this.caret--;
|
|
|
|
};
|
2023-09-21 12:50:39 -05:00
|
|
|
inputpanel.inputs.backspace.rep = true;
|
2023-09-14 12:49:29 -05:00
|
|
|
inputpanel.inputs.enter = function() { this.submit(); }
|
|
|
|
|
2023-10-05 13:33:43 -05:00
|
|
|
inputpanel.inputs['C-k'] = function() {
|
|
|
|
this.value = this.value.slice(0,this.caret);
|
|
|
|
};
|
|
|
|
|
2023-10-26 11:48:02 -05:00
|
|
|
inputpanel.inputs.lm = function()
|
|
|
|
{
|
|
|
|
gui_controls.check_submit();
|
|
|
|
}
|
|
|
|
|
2023-09-12 17:19:46 -05:00
|
|
|
load("scripts/textedit.js");
|
2023-04-22 16:44:26 -05:00
|
|
|
|
2023-09-21 12:50:39 -05:00
|
|
|
var replpanel = Object.copy(inputpanel, {
|
2023-10-06 12:38:49 -05:00
|
|
|
title: "",
|
2023-09-21 12:50:39 -05:00
|
|
|
closeonsubmit:false,
|
2023-10-04 17:57:37 -05:00
|
|
|
wh: [700,300],
|
|
|
|
pos: [50,50],
|
|
|
|
anchor: [0,0],
|
2023-10-06 12:38:49 -05:00
|
|
|
padding: [0,0],
|
2023-10-09 13:03:12 -05:00
|
|
|
scrolloffset: [0,0],
|
2023-10-04 17:57:37 -05:00
|
|
|
|
2023-09-21 12:50:39 -05:00
|
|
|
guibody() {
|
2023-10-09 13:03:12 -05:00
|
|
|
this.win.selectable = true;
|
2023-09-21 12:50:39 -05:00
|
|
|
var log = cmd(84);
|
2023-10-09 13:03:12 -05:00
|
|
|
log = log.slice(-5000);
|
2023-10-04 17:57:37 -05:00
|
|
|
|
|
|
|
return [
|
2023-10-09 13:03:12 -05:00
|
|
|
Mum.text({str:log, anchor:[0,0], offset:[0,-300].sub(this.scrolloffset), selectable: true}),
|
2023-11-07 12:45:52 -06:00
|
|
|
Mum.text({str:this.value,color:Color.green, offset:[0,-290], caret: this.caret})
|
2023-10-04 17:57:37 -05:00
|
|
|
];
|
2023-09-21 12:50:39 -05:00
|
|
|
},
|
2023-10-04 17:57:37 -05:00
|
|
|
prevmark:-1,
|
|
|
|
prevthis:[],
|
2023-09-21 12:50:39 -05:00
|
|
|
|
|
|
|
action() {
|
2023-10-04 17:57:37 -05:00
|
|
|
if (!this.value) return;
|
|
|
|
this.prevthis.unshift(this.value);
|
2023-10-05 08:02:12 -05:00
|
|
|
this.prevmark = -1;
|
2023-10-02 17:03:01 -05:00
|
|
|
var ecode = "";
|
2023-10-17 12:22:06 -05:00
|
|
|
var repl_obj = editor.get_this();
|
2023-10-02 17:03:01 -05:00
|
|
|
ecode += `var $ = repl_obj.objects;`;
|
|
|
|
for (var key in repl_obj.objects)
|
|
|
|
ecode += `var ${key} = editor.edit_level.objects['${key}'];`;
|
2023-09-21 12:50:39 -05:00
|
|
|
|
|
|
|
ecode += this.value;
|
2023-09-22 09:44:58 -05:00
|
|
|
Log.say(this.value);
|
2023-09-21 12:50:39 -05:00
|
|
|
this.value = "";
|
2023-10-04 17:57:37 -05:00
|
|
|
this.caret = 0;
|
2023-10-02 17:03:01 -05:00
|
|
|
var ret = function() {return eval(ecode);}.call(repl_obj);
|
2023-10-05 13:33:43 -05:00
|
|
|
Log.say(ret);
|
2023-09-21 12:50:39 -05:00
|
|
|
},
|
2023-10-09 13:03:12 -05:00
|
|
|
|
|
|
|
resetscroll() {
|
|
|
|
this.scrolloffset.y = 0;
|
|
|
|
},
|
2023-09-21 12:50:39 -05:00
|
|
|
});
|
|
|
|
|
2023-10-04 17:57:37 -05:00
|
|
|
replpanel.inputs = Object.create(inputpanel.inputs);
|
2023-10-17 12:22:06 -05:00
|
|
|
replpanel.inputs.block = true;
|
|
|
|
replpanel.inputs.lm = function()
|
|
|
|
{
|
2023-11-29 12:40:13 -06:00
|
|
|
var mg = physics.pos_query(Mouse.worldpos);
|
2023-10-17 12:22:06 -05:00
|
|
|
if (!mg) return;
|
|
|
|
var p = mg.path_from(editor.get_this());
|
|
|
|
this.value = p;
|
|
|
|
this.caret = this.value.length;
|
|
|
|
}
|
2023-10-09 13:03:12 -05:00
|
|
|
replpanel.inputs.tab = function() {
|
|
|
|
this.resetscroll();
|
2023-10-16 19:59:58 -05:00
|
|
|
if (!this.value) return;
|
2023-10-09 13:03:12 -05:00
|
|
|
var obj = globalThis;
|
|
|
|
var keys = [];
|
|
|
|
var keyobj = this.value.tolast('.');
|
|
|
|
var o = this.value.tolast('.');
|
|
|
|
var stub = this.value.fromlast('.');
|
|
|
|
var replobj = (editor.selectlist.length === 1) ? "editor.selectlist[0]" : "editor.edit_level";
|
|
|
|
|
|
|
|
if (this.value.startswith("this."))
|
|
|
|
keyobj = keyobj.replace("this", replobj);
|
|
|
|
|
|
|
|
if (!this.value.includes('.')) keys.push("this");
|
|
|
|
|
2023-10-09 13:05:48 -05:00
|
|
|
if (eval(`typeof ${keyobj.tofirst('.')}`) === 'object' && eval(`typeof ${keyobj.replace('.', '?.')}`) === 'object')
|
2023-10-09 13:03:12 -05:00
|
|
|
obj = eval(keyobj);
|
|
|
|
else if (this.value.includes('.')){
|
|
|
|
Log.say(`${this.value} is not an object.`);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (var k in obj)
|
|
|
|
keys.push(k)
|
|
|
|
|
2023-10-17 12:22:06 -05:00
|
|
|
for (var k in editor.get_this())
|
|
|
|
keys.push(k);
|
|
|
|
|
2023-10-09 13:03:12 -05:00
|
|
|
var comp = "";
|
|
|
|
if (stub)
|
|
|
|
comp = tab_complete(stub, keys);
|
|
|
|
else if (!this.value.includes('.'))
|
|
|
|
comp = tab_complete(o, keys);
|
|
|
|
else
|
|
|
|
comp = tab_complete("",keys);
|
|
|
|
|
|
|
|
if (stub)
|
|
|
|
this.value = o + '.' + comp;
|
|
|
|
else if (this.value.endswith('.'))
|
|
|
|
this.value = o + '.' + comp;
|
|
|
|
else
|
|
|
|
this.value = comp;
|
|
|
|
|
|
|
|
this.caret = this.value.length;
|
|
|
|
|
|
|
|
keys = keys.sort();
|
|
|
|
|
|
|
|
keys = keys.map(function(x) {
|
|
|
|
if (typeof obj[x] === 'function')
|
|
|
|
return Esc.color(Color.Apple.orange) + x + Esc.reset;
|
|
|
|
if (Object.isObject(obj[x]))
|
|
|
|
return Esc.color(Color.Apple.purple) + x + Esc.reset;
|
|
|
|
if (Array.isArray(obj[x]))
|
|
|
|
return Esc.color(Color.Apple.green) + x + Esc.reset;
|
|
|
|
|
|
|
|
return x;
|
|
|
|
});
|
|
|
|
|
|
|
|
if (keys.length > 1)
|
2023-12-09 22:09:15 -06:00
|
|
|
Log.repl(keys.join(', '));
|
2023-10-09 13:03:12 -05:00
|
|
|
};
|
2023-10-04 17:57:37 -05:00
|
|
|
replpanel.inputs['C-p'] = function()
|
|
|
|
{
|
|
|
|
if (this.prevmark >= this.prevthis.length) return;
|
|
|
|
this.prevmark++;
|
|
|
|
this.value = this.prevthis[this.prevmark];
|
2023-10-05 13:33:43 -05:00
|
|
|
this.inputs['C-e'].call(this);
|
2023-10-04 17:57:37 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
replpanel.inputs['C-n'] = function()
|
|
|
|
{
|
|
|
|
this.prevmark--;
|
|
|
|
if (this.prevmark < 0) {
|
|
|
|
this.prevmark = -1;
|
|
|
|
this.value = "";
|
|
|
|
} else
|
|
|
|
this.value = this.prevthis[this.prevmark];
|
2023-10-05 08:02:12 -05:00
|
|
|
|
2023-10-05 13:33:43 -05:00
|
|
|
this.inputs['C-e'].call(this);
|
2023-10-04 17:57:37 -05:00
|
|
|
}
|
|
|
|
|
2023-10-09 13:03:12 -05:00
|
|
|
replpanel.inputs.mouse = {};
|
|
|
|
replpanel.inputs.mouse.scroll = function(scroll)
|
|
|
|
{
|
|
|
|
if (!this.win.selected) return;
|
|
|
|
|
|
|
|
this.scrolloffset.y += scroll.y;
|
|
|
|
if (this.scrolloffset.y < 0) this.scrolloffset.y = 0;
|
|
|
|
}
|
|
|
|
|
2023-10-16 19:59:58 -05:00
|
|
|
replpanel.inputs.mm = function() { this.mm = true; };
|
|
|
|
replpanel.inputs.mm.released = function() { this.mm = false; };
|
|
|
|
|
|
|
|
replpanel.inputs.mouse.move = function(pos,dpos)
|
|
|
|
{
|
|
|
|
if (this.mm)
|
|
|
|
this.scrolloffset.y -= dpos.y;
|
|
|
|
}
|
|
|
|
|
2023-10-09 13:03:12 -05:00
|
|
|
replpanel.inputs.up = function()
|
|
|
|
{
|
|
|
|
this.scrolloffset.y += 40;
|
|
|
|
}
|
|
|
|
replpanel.inputs.up.rep = true;
|
|
|
|
replpanel.inputs.down = function()
|
|
|
|
{
|
|
|
|
this.scrolloffset.y -= 40;
|
|
|
|
if (this.scrolloffset.y < 0) this.scrolloffset.y = 0;
|
|
|
|
}
|
|
|
|
replpanel.inputs.down.rep = true;
|
|
|
|
|
|
|
|
replpanel.inputs.pgup = function()
|
|
|
|
{
|
|
|
|
this.scrolloffset.y += 300;
|
|
|
|
}
|
|
|
|
replpanel.inputs.pgup.rep = true;
|
|
|
|
|
|
|
|
replpanel.inputs.pgdown = function()
|
|
|
|
{
|
|
|
|
this.scrolloffset.y -= 300;
|
|
|
|
if (this.scrolloffset.y < 0) this.scrolloffset.y = 0;
|
|
|
|
}
|
|
|
|
replpanel.inputs.pgdown.rep = true;
|
|
|
|
|
2023-09-20 17:58:18 -05:00
|
|
|
var objectexplorer = Object.copy(inputpanel, {
|
2023-04-22 16:44:26 -05:00
|
|
|
title: "object explorer",
|
2023-09-11 17:09:21 -05:00
|
|
|
obj: undefined,
|
2023-04-22 16:44:26 -05:00
|
|
|
previous: [],
|
|
|
|
start() {
|
|
|
|
this.previous = [];
|
|
|
|
Input.setnuke();
|
|
|
|
},
|
|
|
|
|
|
|
|
goto_obj(obj) {
|
|
|
|
if (obj === this.obj) return;
|
|
|
|
this.previous.push(this.obj);
|
|
|
|
this.obj = obj;
|
|
|
|
},
|
|
|
|
|
2023-10-11 17:22:41 -05:00
|
|
|
prev_obj() {
|
|
|
|
this.obj = this.previous.pop();
|
|
|
|
},
|
|
|
|
|
2023-04-22 16:44:26 -05:00
|
|
|
guibody() {
|
2023-10-11 17:22:41 -05:00
|
|
|
var items = [];
|
2023-10-26 11:48:02 -05:00
|
|
|
items.push(Mum.text({str:"Examining " + this.obj.toString()}));
|
|
|
|
return items;
|
2023-04-22 16:44:26 -05:00
|
|
|
|
|
|
|
var n = 0;
|
|
|
|
var curobj = this.obj;
|
|
|
|
while (curobj) {
|
|
|
|
n++;
|
|
|
|
curobj = curobj.__proto__;
|
|
|
|
}
|
|
|
|
|
|
|
|
n--;
|
|
|
|
curobj = this.obj.__proto__;
|
|
|
|
while (curobj) {
|
2023-10-11 17:22:41 -05:00
|
|
|
items.push(Mum.text({str:curobj.toString(), action:this.goto_obj(curobj)}));
|
2023-04-22 16:44:26 -05:00
|
|
|
curobj = curobj.__proto__;
|
|
|
|
}
|
|
|
|
|
2023-10-11 17:22:41 -05:00
|
|
|
if (!this.previous.empty)
|
|
|
|
items.push(Mum.text({str:"prev: " + this.previous.last, action: this.prev_obj}));
|
2023-04-22 16:44:26 -05:00
|
|
|
|
|
|
|
Object.getOwnPropertyNames(this.obj).forEach(key => {
|
|
|
|
var descriptor = Object.getOwnPropertyDescriptor(this.obj, key);
|
|
|
|
if (!descriptor) return;
|
|
|
|
var hidden = !descriptor.enumerable;
|
|
|
|
var writable = descriptor.writable;
|
|
|
|
var configurable = descriptor.configurable;
|
|
|
|
|
|
|
|
if (!descriptor.configurable) return;
|
|
|
|
if (hidden) return;
|
|
|
|
|
|
|
|
var name = (hidden ? "[hidden] " : "") + key;
|
|
|
|
var val = this.obj[key];
|
|
|
|
|
|
|
|
switch (typeof val) {
|
|
|
|
case 'object':
|
|
|
|
if (val) {
|
|
|
|
if (Array.isArray(val)) {
|
2023-10-11 17:22:41 -05:00
|
|
|
// this.obj[key] = Nuke.pprop(key,val);
|
2023-04-22 16:44:26 -05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2023-10-11 17:22:41 -05:00
|
|
|
// Nuke.newline(2);
|
|
|
|
items.push(Mum.text({str:name}));
|
|
|
|
items.push(Mum.text({str:val.toString(), action: this.goto_obj.bind(val)}));
|
2023-04-22 16:44:26 -05:00
|
|
|
} else {
|
2023-10-11 17:22:41 -05:00
|
|
|
// this.obj[key] = Nuke.pprop(key,val);
|
2023-04-22 16:44:26 -05:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'function':
|
2023-10-11 17:22:41 -05:00
|
|
|
items.push(Mum.text({str:name}));
|
|
|
|
items.push(Mum.text({str:"function"}));
|
2023-04-22 16:44:26 -05:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
if (!hidden) {// && Object.getOwnPropertyDescriptor(this.obj, key).writable) {
|
2023-10-11 17:22:41 -05:00
|
|
|
// this.obj[key] = Nuke.pprop(key, this.obj[key]);
|
2023-04-22 16:44:26 -05:00
|
|
|
|
2023-10-11 17:22:41 -05:00
|
|
|
/* if (key in this.obj.__proto__) {
|
2023-04-22 16:44:26 -05:00
|
|
|
if (Nuke.button("delete " + key)) {
|
|
|
|
if ("_"+key in this.obj)
|
|
|
|
delete this.obj["_"+key];
|
|
|
|
else
|
|
|
|
delete this.obj[key];
|
|
|
|
}
|
2023-10-11 17:22:41 -05:00
|
|
|
}*/
|
2023-04-22 16:44:26 -05:00
|
|
|
}
|
|
|
|
else {
|
2023-10-11 17:22:41 -05:00
|
|
|
items.push(Mum.text({str:name}));
|
|
|
|
items.push(Mum.text({str:val.toString()}));
|
2023-04-22 16:44:26 -05:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2023-10-11 17:22:41 -05:00
|
|
|
items.push(Mum.text({str:"Properties that can be pulled in ..."}));
|
|
|
|
// Nuke.newline(3);
|
2023-04-22 16:44:26 -05:00
|
|
|
var pullprops = [];
|
|
|
|
for (var key in this.obj.__proto__) {
|
|
|
|
if (!this.obj.hasOwn(key)) {
|
|
|
|
if (typeof this.obj[key] === 'object' || typeof this.obj[key] === 'function') continue;
|
|
|
|
pullprops.push(key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pullprops = pullprops.sort();
|
|
|
|
|
|
|
|
pullprops.forEach(function(key) {
|
2023-10-11 17:22:41 -05:00
|
|
|
items.push(Mum.text({str:key}));
|
|
|
|
// this.obj[key] = this.obj[key];
|
|
|
|
});
|
2023-04-22 16:44:26 -05:00
|
|
|
|
2023-11-29 12:40:13 -06:00
|
|
|
// Game.all_objects(function(x) { x.sync(); });
|
2023-10-11 17:22:41 -05:00
|
|
|
return items;
|
2023-04-22 16:44:26 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
2023-09-20 17:58:18 -05:00
|
|
|
var helppanel = Object.copy(inputpanel, {
|
2023-04-22 16:44:26 -05:00
|
|
|
title: "help",
|
|
|
|
|
|
|
|
start() {
|
|
|
|
this.helptext = slurp("editor.adoc");
|
|
|
|
},
|
|
|
|
|
|
|
|
guibody() {
|
|
|
|
Nuke.label(this.helptext);
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
2023-09-20 17:58:18 -05:00
|
|
|
var openlevelpanel = Object.copy(inputpanel, {
|
2023-09-11 15:07:36 -05:00
|
|
|
title: "open entity",
|
2023-04-22 16:44:26 -05:00
|
|
|
action() {
|
|
|
|
editor.load(this.value);
|
|
|
|
},
|
|
|
|
|
|
|
|
assets: [],
|
|
|
|
allassets: [],
|
|
|
|
|
2023-10-04 08:18:09 -05:00
|
|
|
mumlist: {},
|
|
|
|
|
2023-04-22 16:44:26 -05:00
|
|
|
submit_check() {
|
2023-09-14 12:49:29 -05:00
|
|
|
if (this.assets.length === 0) return false;
|
|
|
|
|
|
|
|
this.value = this.assets[0];
|
|
|
|
return true;
|
2023-04-22 16:44:26 -05:00
|
|
|
},
|
2023-10-05 13:33:43 -05:00
|
|
|
|
2023-04-22 16:44:26 -05:00
|
|
|
start() {
|
2023-09-11 15:07:36 -05:00
|
|
|
this.allassets = prototypes.list.sort();
|
2023-04-22 16:44:26 -05:00
|
|
|
this.assets = this.allassets.slice();
|
2023-10-06 12:38:49 -05:00
|
|
|
this.caret = 0;
|
2023-10-05 13:33:43 -05:00
|
|
|
var click_ur = function(btn) {
|
|
|
|
this.value = btn.str;
|
|
|
|
this.keycb();
|
|
|
|
this.submit();
|
|
|
|
};
|
|
|
|
click_ur = click_ur.bind(this);
|
2023-09-14 12:49:29 -05:00
|
|
|
|
2023-10-04 08:18:09 -05:00
|
|
|
this.mumlist = [];
|
2023-04-22 16:44:26 -05:00
|
|
|
this.assets.forEach(function(x) {
|
2023-10-16 19:59:58 -05:00
|
|
|
this.mumlist[x] = Mum.text({str:x, action:click_ur, color: Color.blue, hovered: {color:Color.red}, selectable:true});
|
2023-04-22 16:44:26 -05:00
|
|
|
}, this);
|
2023-10-04 08:18:09 -05:00
|
|
|
},
|
2023-04-22 16:44:26 -05:00
|
|
|
|
2023-10-04 08:18:09 -05:00
|
|
|
keycb() {
|
2023-10-26 11:48:02 -05:00
|
|
|
if(this.value)
|
|
|
|
this.assets = this.allassets.filter(x => x.startswith(this.value));
|
|
|
|
else
|
|
|
|
this.assets = this.allassets.slice();
|
2023-10-04 08:18:09 -05:00
|
|
|
for (var m in this.mumlist)
|
|
|
|
this.mumlist[m].hide = true;
|
|
|
|
this.assets.forEach(function(x) {
|
|
|
|
this.mumlist[x].hide = false;
|
|
|
|
}, this);
|
|
|
|
},
|
|
|
|
|
|
|
|
guibody() {
|
2023-10-05 13:33:43 -05:00
|
|
|
var a = [Mum.text({str:this.value,color:Color.green, caret:this.caret})];
|
2023-10-04 17:57:37 -05:00
|
|
|
var b = a.concat(Object.values(this.mumlist));
|
2023-10-05 13:33:43 -05:00
|
|
|
return Mum.column({items:b, offset:[0,-10]});
|
2023-04-22 16:44:26 -05:00
|
|
|
},
|
|
|
|
});
|
|
|
|
|
2023-09-20 17:58:18 -05:00
|
|
|
var saveaspanel = Object.copy(inputpanel, {
|
2023-10-06 12:38:49 -05:00
|
|
|
get title() { return `save level as: ${this.stem}.`; },
|
|
|
|
|
2023-04-22 16:44:26 -05:00
|
|
|
action() {
|
2023-09-29 13:16:59 -05:00
|
|
|
var savename = "";
|
|
|
|
if (this.stem) savename += this.stem + ".";
|
|
|
|
editor.saveas_check(savename + this.value, this.obj);
|
2023-04-22 16:44:26 -05:00
|
|
|
},
|
|
|
|
});
|
|
|
|
|
2023-09-20 17:58:18 -05:00
|
|
|
var groupsaveaspanel = Object.copy(inputpanel, {
|
2023-04-22 16:44:26 -05:00
|
|
|
title: "group save as",
|
|
|
|
action() { editor.groupsaveas(editor.selectlist, this.value); }
|
|
|
|
});
|
|
|
|
|
2023-09-20 17:58:18 -05:00
|
|
|
var quitpanel = Object.copy(inputpanel, {
|
2023-04-22 16:44:26 -05:00
|
|
|
title: "really quit?",
|
|
|
|
action() {
|
2023-09-21 19:51:38 -05:00
|
|
|
Game.quit();
|
2023-04-22 16:44:26 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
guibody () {
|
2023-10-05 08:02:12 -05:00
|
|
|
return Mum.text({str: "Really quit?"});
|
2023-04-22 16:44:26 -05:00
|
|
|
},
|
|
|
|
});
|
|
|
|
|
2023-09-20 17:58:18 -05:00
|
|
|
var notifypanel = Object.copy(inputpanel, {
|
2023-04-22 16:44:26 -05:00
|
|
|
title: "notification",
|
|
|
|
msg: "Refusing to save. File already exists.",
|
|
|
|
action() {
|
|
|
|
this.close();
|
|
|
|
},
|
|
|
|
|
|
|
|
guibody() {
|
2023-10-06 12:38:49 -05:00
|
|
|
return Mum.column({items: [
|
|
|
|
Mum.text({str:this.msg}),
|
|
|
|
Mum.button({str:"OK", action:this.close.bind(this)})
|
|
|
|
]});
|
2023-04-22 16:44:26 -05:00
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
var gen_notify = function(val, fn) {
|
|
|
|
var panel = Object.create(notifypanel);
|
|
|
|
panel.msg = val;
|
|
|
|
panel.yes = fn;
|
2023-08-27 21:57:19 -05:00
|
|
|
panel.inputs = {};
|
|
|
|
panel.inputs.y = function() { panel.yes(); panel.close(); };
|
|
|
|
panel.inputs.y.doc = "Confirm yes.";
|
|
|
|
panel.inputs.enter = function() { panel.close(); };
|
|
|
|
panel.inputs.enter.doc = "Close.";
|
2023-04-22 16:44:26 -05:00
|
|
|
return panel;
|
|
|
|
};
|
|
|
|
|
|
|
|
var scripts = ["js"];
|
|
|
|
var images = ["png", "jpg", "jpeg"];
|
|
|
|
var sounds = ["wav", "mp3"];
|
|
|
|
var allfiles = [];
|
|
|
|
allfiles.push(scripts, images, sounds);
|
|
|
|
allfiles = allfiles.flat();
|
|
|
|
|
2023-09-20 17:58:18 -05:00
|
|
|
var assetexplorer = Object.copy(openlevelpanel, {
|
2023-04-22 16:44:26 -05:00
|
|
|
title: "asset explorer",
|
|
|
|
extensions: allfiles,
|
|
|
|
closeonsubmit: false,
|
|
|
|
allassets:[],
|
|
|
|
action() {
|
|
|
|
if (editor.sel_comp && 'asset' in editor.sel_comp)
|
|
|
|
editor.sel_comp.asset = this.value;
|
|
|
|
else
|
|
|
|
editor.viewasset(this.value);
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
function tab_complete(val, list) {
|
2023-10-09 13:03:12 -05:00
|
|
|
if (!val) return val;
|
|
|
|
list.dofilter(function(x) { return x.startsWith(val); });
|
2023-10-09 13:05:48 -05:00
|
|
|
|
2023-10-09 13:03:12 -05:00
|
|
|
if (list.length === 1) {
|
|
|
|
return list[0];
|
2023-04-22 16:44:26 -05:00
|
|
|
}
|
|
|
|
|
2023-09-11 17:09:21 -05:00
|
|
|
var ret = undefined;
|
2023-04-22 16:44:26 -05:00
|
|
|
var i = val.length;
|
2023-10-09 13:03:12 -05:00
|
|
|
while (!ret && !list.empty) {
|
|
|
|
var char = list[0][i];
|
|
|
|
if (!list.every(function(x) { return x[i] === char; }))
|
|
|
|
ret = list[0].slice(0, i);
|
2023-04-22 16:44:26 -05:00
|
|
|
else {
|
|
|
|
i++;
|
2023-10-09 13:03:12 -05:00
|
|
|
list.dofilter(function(x) { return x.length-1 > i; });
|
2023-04-22 16:44:26 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-09 13:03:12 -05:00
|
|
|
return ret ? ret : val;
|
2023-04-22 16:44:26 -05:00
|
|
|
}
|
|
|
|
|
2023-09-20 17:58:18 -05:00
|
|
|
var texgui = Object.copy(inputpanel, {
|
2023-04-22 16:44:26 -05:00
|
|
|
get path() { return this._path; },
|
|
|
|
set path(x) {
|
|
|
|
this._path = x;
|
|
|
|
this.title = "texture " + x;
|
|
|
|
},
|
|
|
|
|
|
|
|
guibody() {
|
|
|
|
Nuke.label("texture");
|
|
|
|
Nuke.img(this.path);
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
2023-09-20 17:58:18 -05:00
|
|
|
var entitylistpanel = Object.copy(inputpanel, {
|
2023-08-28 17:00:53 -05:00
|
|
|
title: "Level object list",
|
2023-04-22 16:44:26 -05:00
|
|
|
level: {},
|
|
|
|
start() {
|
|
|
|
this.level = editor.edit_level;
|
|
|
|
},
|
|
|
|
|
2023-11-16 09:27:04 -06:00
|
|
|
/* guibody() {
|
2023-04-22 16:44:26 -05:00
|
|
|
Nuke.newline(4);
|
|
|
|
Nuke.label("Object");
|
|
|
|
Nuke.label("Visible");
|
|
|
|
Nuke.label("Selectable");
|
|
|
|
Nuke.label("Selected?");
|
|
|
|
this.level.objects.forEach(function(x) {
|
|
|
|
if (Nuke.button(x.toString())) {
|
|
|
|
editor.selectlist = [];
|
|
|
|
editor.selectlist.push(x);
|
|
|
|
}
|
|
|
|
|
|
|
|
x.visible = Nuke.checkbox(x.visible);
|
2023-10-06 12:38:49 -05:00
|
|
|
x._ed.selectable = Nuke.checkbox(x._ed.selectable);
|
2023-04-22 16:44:26 -05:00
|
|
|
|
|
|
|
if (editor.selectlist.includes(x)) Nuke.label("T"); else Nuke.label("F");
|
|
|
|
});
|
|
|
|
},
|
2023-11-16 09:27:04 -06:00
|
|
|
*/
|
2023-04-22 16:44:26 -05:00
|
|
|
});
|
|
|
|
|
2023-08-27 21:57:19 -05:00
|
|
|
var limited_editor = {};
|
2023-04-22 16:44:26 -05:00
|
|
|
|
2023-08-27 21:57:19 -05:00
|
|
|
limited_editor.inputs = {};
|
|
|
|
|
|
|
|
limited_editor.inputs['C-p'] = function()
|
|
|
|
{
|
|
|
|
if (Game.playing())
|
|
|
|
Game.pause();
|
|
|
|
else
|
|
|
|
Game.play();
|
|
|
|
}
|
|
|
|
|
|
|
|
limited_editor.inputs['M-p'] = function()
|
|
|
|
{
|
|
|
|
Game.pause();
|
|
|
|
Game.step();
|
|
|
|
}
|
|
|
|
|
|
|
|
limited_editor.inputs['C-q'] = function()
|
|
|
|
{
|
2023-10-11 17:22:41 -05:00
|
|
|
Primum.clear();
|
2023-11-08 01:39:10 -06:00
|
|
|
load("editorconfig.js");
|
2023-10-29 16:39:45 -05:00
|
|
|
load("dbgret.js");
|
2023-10-11 17:22:41 -05:00
|
|
|
|
2023-10-09 18:10:10 -05:00
|
|
|
editor.enter_editor();
|
2023-08-27 21:57:19 -05:00
|
|
|
}
|
2023-04-22 16:44:26 -05:00
|
|
|
|
2023-08-28 17:00:53 -05:00
|
|
|
/* This is used for editing during a paused game */
|
|
|
|
var limited_editing = {};
|
|
|
|
limited_editing.inputs = {};
|
|
|
|
|
2023-04-22 16:44:26 -05:00
|
|
|
if (IO.exists("editor.config"))
|
|
|
|
load_configs("editor.config");
|
2023-09-08 12:35:06 -05:00
|
|
|
|
2023-09-13 16:49:22 -05:00
|
|
|
/* This is the editor level & camera - NOT the currently edited level, but a level to hold editor things */
|
2023-09-06 17:48:08 -05:00
|
|
|
Game.stop();
|
2023-09-19 17:37:54 -05:00
|
|
|
Game.editor_mode(true);
|
2023-10-11 17:22:41 -05:00
|
|
|
Debug.draw_phys(true);
|