circle and sprites work with saves
This commit is contained in:
parent
fe21b84785
commit
1143b9b3dc
|
@ -333,7 +333,8 @@ Object.defineProperty(String.prototype, 'ext', {
|
|||
|
||||
Object.defineProperty(String.prototype, 'set_ext', {
|
||||
value: function(val) {
|
||||
return this.dir() + this.name() + val;
|
||||
var s = this.strip_ext();
|
||||
return s + val;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -356,10 +357,16 @@ Object.defineProperty(String.prototype, 'dir', {
|
|||
value: function() {
|
||||
var e = this.lastIndexOf('/');
|
||||
if (e === -1) return "";
|
||||
return this.slice(0, e+1);
|
||||
return this.slice(0, e);
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(String.prototype, 'updir', {
|
||||
value: function() {
|
||||
var dir = this.dir();
|
||||
return dir.dir();
|
||||
}
|
||||
});
|
||||
|
||||
/* ARRAY DEFS */
|
||||
|
||||
|
|
|
@ -22,15 +22,46 @@ var component = {
|
|||
extend(spec) {
|
||||
return Object.copy(this, spec);
|
||||
},
|
||||
|
||||
/* Given a relative path, return the full path */
|
||||
resani(path) {
|
||||
if (!this.gameobject) return path;
|
||||
if (path[0] === '/') return path.slice(1);
|
||||
var res = this.gameobject.ur.toString();
|
||||
res = res.replaceAll('.', '/');
|
||||
var restry = res + "/" + path;
|
||||
while (!IO.exists(restry)) {
|
||||
res = res.updir() + "/";
|
||||
if (res === "/")
|
||||
return path;
|
||||
|
||||
restry = res + path;
|
||||
}
|
||||
return restry;
|
||||
},
|
||||
|
||||
/* Given the full path, return the most relative path */
|
||||
resavi(path) {
|
||||
if (!this.gameobject) return path;
|
||||
if (path[0] === '/') return path;
|
||||
|
||||
var res = this.gameobject.ur.toString();
|
||||
res = res.replaceAll('.', '/');
|
||||
if (!path.startsWith(res))
|
||||
return path;
|
||||
|
||||
return path.replace(res, "").slice(1);
|
||||
},
|
||||
};
|
||||
|
||||
component.toJSON = ur_json;
|
||||
//component.toJSON = ur_json;
|
||||
|
||||
component.sprite = {
|
||||
pos:[0,0],
|
||||
color:[1,1,1],
|
||||
layer:0,
|
||||
enabled:true,
|
||||
path: "",
|
||||
toString() { return "sprite"; },
|
||||
make(go) {
|
||||
var nsprite = Object.create(component.sprite.maker);
|
||||
|
@ -42,7 +73,13 @@ component.sprite = {
|
|||
};
|
||||
|
||||
component.sprite.maker = Object.copy(component, {
|
||||
set path(x) { cmd(12,this.id,x,this.rect); },
|
||||
set path(x) {
|
||||
x = this.resani(x);
|
||||
cmd(12,this.id,x,this.rect);
|
||||
},
|
||||
get path() {
|
||||
return cmd(116,this.id);
|
||||
},
|
||||
get visible() { return this.enabled; },
|
||||
set visible(x) { this.enabled = x; },
|
||||
asset(str) { this.path = str; },
|
||||
|
@ -690,6 +727,8 @@ component.circle2d = Object.copy(collider2d, {
|
|||
var circle = Object.create(this);
|
||||
circle.gameobject = go;
|
||||
Object.assign(circle, make_circle2d(go.body, circle.radius, circle.offset));
|
||||
Object.merge(circle, this.ur);
|
||||
|
||||
return circle;
|
||||
},
|
||||
|
||||
|
|
|
@ -73,91 +73,6 @@ var editor = {
|
|||
|
||||
programmode: false,
|
||||
|
||||
delete_empty_reviver(key, val) {
|
||||
if (typeof val === 'object' && val.empty)
|
||||
return undefined;
|
||||
|
||||
return val;
|
||||
},
|
||||
|
||||
save_proto() {
|
||||
if (this.selectlist.length !== 1) return;
|
||||
Log.warn(`Saving prototype ${this.selectlist[0].toString()}`);
|
||||
var protos = JSON.parse(IO.slurp("proto.json"));
|
||||
|
||||
var tobj = this.selectlist[0].prop_obj();
|
||||
var pobj = this.selectlist[0].__proto__.prop_obj();
|
||||
|
||||
Log.warn("Going to deep merge.");
|
||||
deep_merge(pobj, tobj);
|
||||
Log.warn("Finished deep merge.");
|
||||
|
||||
pobj.from = this.selectlist[0].__proto__.from;
|
||||
|
||||
protos[this.selectlist[0].__proto__.name] = pobj;
|
||||
Log.warn(JSON.stringify(protos));
|
||||
slurpwrite(JSON.stringify(protos, undefined, 2), "proto.json");
|
||||
|
||||
/* Save object changes to parent */
|
||||
Object.dainty_assign(this.selectlist[0].__proto__, tobj);
|
||||
|
||||
/* Remove the local from this object */
|
||||
unmerge(this.selectlist[0], tobj);
|
||||
|
||||
/* Now sync all objects */
|
||||
Game.objects.forEach(x => x.sync());
|
||||
|
||||
},
|
||||
|
||||
/* Save the selected object as a new prototype, extending the chain */
|
||||
save_proto_as(name) {
|
||||
if (name in gameobjects) {
|
||||
Log.info("Already an object with name '" + name + "'. Choose another one.");
|
||||
return;
|
||||
}
|
||||
var newp = this.selectlist[0].__proto__.clone(name);
|
||||
|
||||
for (var key in newp)
|
||||
if (typeof newp[key] === 'object' && 'clone' in newp[key])
|
||||
newp[key] = newp[key].clone();
|
||||
|
||||
Object.dainty_assign(newp, this.selectlist[0].prop_obj());
|
||||
this.selectlist[0].kill();
|
||||
var gopos = this.selectlist[0].pos;
|
||||
this.unselect();
|
||||
var proto = this.edit_level.spawn(gameobjects[name]);
|
||||
this.selectlist.push(proto);
|
||||
this.save_proto();
|
||||
proto.pos = gopos;
|
||||
},
|
||||
|
||||
/* Save selected object as a new prototype, replacing the current prototype */
|
||||
save_type_as(name) {
|
||||
if (name in gameobjects) {
|
||||
Log.info("Already an object with name '" + name + "'. Choose another one.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var newp = this.selectlist[0].__proto__.__proto__.clone(name);
|
||||
|
||||
for (var key in newp)
|
||||
if (typeof newp[key] === 'object' && 'clone' in newp[key])
|
||||
newp[key] = newp[key].clone();
|
||||
|
||||
var tobj = this.selectlist[0].prop_obj();
|
||||
var pobj = this.selectlist[0].__proto__.prop_obj();
|
||||
deep_merge(pobj, tobj);
|
||||
|
||||
|
||||
Object.dainty_assign(newp, pobj);
|
||||
this.selectlist[0].kill();
|
||||
this.unselect();
|
||||
var proto = this.edit_level.spawn(gameobjects[name]);
|
||||
this.selectlist.push(proto);
|
||||
this.save_proto();
|
||||
},
|
||||
|
||||
dup_objects(x) {
|
||||
var objs = x.slice();
|
||||
var duped = [];
|
||||
|
@ -504,7 +419,7 @@ return;
|
|||
this.selectlist.forEach(function(x) {
|
||||
var color = x.color ? x.color : Color.white;
|
||||
var sname = x.ur.toString();
|
||||
if (!x.save_obj().empty)
|
||||
if (!x.json_obj().empty)
|
||||
x.dirty = true;
|
||||
else
|
||||
x.dirty = false;
|
||||
|
@ -668,15 +583,6 @@ return;
|
|||
editor.selectlist[0].angle = t.angle;
|
||||
}
|
||||
},
|
||||
|
||||
saveas(file) {
|
||||
if (!file) return;
|
||||
|
||||
Log.info("made it");
|
||||
|
||||
this.edit_level.file = file;
|
||||
this.save_current();
|
||||
},
|
||||
}
|
||||
|
||||
editor.inputs = {};
|
||||
|
@ -864,10 +770,11 @@ editor.inputs.escape.doc = "Quit editor.";
|
|||
|
||||
editor.inputs['C-s'] = function() {
|
||||
if (editor.selectlist.length !== 1 || !editor.selectlist[0].dirty) return;
|
||||
Log.warn(`Saving ur for ${editor.selectlist[0].toString()}`);
|
||||
|
||||
Object.merge(editor.selectlist[0].ur, editor.selectlist[0].json_obj());
|
||||
IO.slurpwrite(JSON.stringify(editor.selectlist[0].ur,null,1), editor.selectlist[0].toString() + ".json");
|
||||
var path = editor.selectlist[0].toString();
|
||||
path = path.replaceAll('.','/');
|
||||
path = path + "/" + path.name() + ".json";
|
||||
IO.slurpwrite(JSON.stringify(editor.selectlist[0].ur,null,1), path);
|
||||
return;
|
||||
|
||||
if (editor.edit_level.level) {
|
||||
|
@ -1715,13 +1622,6 @@ var groupsaveaspanel = Object.copy(inputpanel, {
|
|||
action() { editor.groupsaveas(editor.selectlist, this.value); }
|
||||
});
|
||||
|
||||
var saveprototypeas = Object.copy(inputpanel, {
|
||||
title: "save prototype as",
|
||||
action() {
|
||||
editor.save_proto_as(this.value);
|
||||
},
|
||||
});
|
||||
|
||||
var savetypeas = Object.copy(inputpanel, {
|
||||
title: "save type as",
|
||||
action() {
|
||||
|
|
|
@ -94,20 +94,11 @@ var gameobject = {
|
|||
return bb.t-bb.b;
|
||||
},
|
||||
|
||||
save_obj() {
|
||||
var json = JSON.stringify(this);
|
||||
if (!json) return {};
|
||||
var o = JSON.parse(json);
|
||||
delete o.pos;
|
||||
delete o.angle;
|
||||
return o;
|
||||
},
|
||||
|
||||
/* Make a unique object the same as its prototype */
|
||||
revert() {
|
||||
var save = this.save_obj();
|
||||
for (var key in save)
|
||||
this[key] = this.ur[key];
|
||||
var t = this.transform();
|
||||
Object.totalmerge(this,this.ur);
|
||||
Object.merge(this,t);
|
||||
},
|
||||
|
||||
gui() {
|
||||
|
@ -368,12 +359,11 @@ var gameobject = {
|
|||
if ('ur' in p) {
|
||||
obj[prop] = obj.spawn(prototypes.get_ur(p.ur));
|
||||
obj.$[prop] = obj[prop];
|
||||
} else if ('make' in p) {
|
||||
obj[prop] = p.make(obj);
|
||||
obj.components[prop] = obj[prop];
|
||||
} else if ('comp' in p) {
|
||||
obj[prop] = component[p.comp].make(obj);
|
||||
obj.components[prop] = obj[prop];
|
||||
obj[prop].ur = Object.create(obj[prop].ur);
|
||||
Object.totalmerge(obj[prop].ur, p);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -483,8 +473,14 @@ prototypes.from_file = function(file)
|
|||
if (IO.exists(jsfile)) script = IO.slurp(jsfile);
|
||||
}
|
||||
|
||||
if (IO.exists(jsonfile))
|
||||
if (IO.exists(jsonfile)) {
|
||||
try {
|
||||
json = JSON.parse(IO.slurp(jsonfile));
|
||||
}
|
||||
catch(e) {
|
||||
Log.warn(`JSON in file ${jsonfile} is malformed.`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
jsonfile = urpath + "/" + path.at(-1) + ".json";
|
||||
if (IO.exists(jsonfile)) json = JSON.parse(IO.slurp(jsonfile));
|
||||
|
@ -555,7 +551,6 @@ prototypes.get_ur = function(name)
|
|||
|
||||
if (!prototypes.ur[urpath]) {
|
||||
var ur = prototypes.from_file(urpath);
|
||||
Log.warn(`tried to make ${urpath}`);
|
||||
if (ur)
|
||||
return ur;
|
||||
else {
|
||||
|
|
|
@ -201,6 +201,7 @@ struct phys2d_circle *Make2DCircle(int go) {
|
|||
new->shape.shape = cpSpaceAddShape(space, cpCircleShapeNew(id2go(go)->body, new->radius, cpvzero));
|
||||
new->shape.debugdraw = phys2d_dbgdrawcircle;
|
||||
new->shape.moi = phys2d_circle_moi;
|
||||
new->shape.apply = phys2d_applycircle;
|
||||
init_phys2dshape(&new->shape, go, new);
|
||||
|
||||
return new;
|
||||
|
|
|
@ -21,13 +21,13 @@ extern struct rgba kinematic_color;
|
|||
extern struct rgba static_color;
|
||||
extern struct rgba sleep_color;
|
||||
|
||||
|
||||
struct phys2d_shape {
|
||||
cpShape *shape;
|
||||
int go;
|
||||
void *data;
|
||||
void (*debugdraw)(void *data);
|
||||
float (*moi)(void *data, float mass);
|
||||
void (*apply)(void *data);
|
||||
};
|
||||
|
||||
/* Circles are the fastest collier type */
|
||||
|
|
|
@ -707,6 +707,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
|||
|
||||
case 36:
|
||||
id2go(js2int(argv[1]))->scale = js2number(argv[2]);
|
||||
gameobject_apply(id2go(js2int(argv[1])));
|
||||
cpSpaceReindexShapesForBody(space, id2go(js2int(argv[1]))->body);
|
||||
return JS_NULL;
|
||||
|
||||
|
|
|
@ -95,6 +95,10 @@ void go_shape_apply(cpBody *body, cpShape *shape, struct gameobject *go) {
|
|||
filter.categories = CP_ALL_CATEGORIES;//1<<go->layer;
|
||||
filter.mask = CP_ALL_CATEGORIES;//category_masks[go->layer];
|
||||
cpShapeSetFilter(shape, filter);
|
||||
|
||||
struct phys2d_shape *ape = cpShapeGetUserData(shape);
|
||||
if (ape)
|
||||
ape->apply(ape->data);
|
||||
}
|
||||
|
||||
void go_shape_moi(cpBody *body, cpShape *shape, struct gameobject *go) {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include "font.h"
|
||||
|
||||
|
@ -248,8 +249,34 @@ char *slurp_text(const char *filename, size_t *size)
|
|||
return retstr;
|
||||
}
|
||||
|
||||
void rek_mkdir(char *path) {
|
||||
char *sep = strrchr(path, '/');
|
||||
if(sep != NULL) {
|
||||
*sep = 0;
|
||||
rek_mkdir(path);
|
||||
*sep = '/';
|
||||
}
|
||||
#if defined __WIN32
|
||||
if(mkdir(path) && errno != EEXIST)
|
||||
#else
|
||||
if (mkdir(path, 0777) && errno != EEXIST)
|
||||
#endif
|
||||
printf("error while trying to create '%s'\n%m\n", path);
|
||||
}
|
||||
|
||||
FILE *fopen_mkdir(char *path, char *mode) {
|
||||
char *sep = strrchr(path, '/');
|
||||
if(sep) {
|
||||
char *path0 = strdup(path);
|
||||
path0[ sep - path ] = 0;
|
||||
rek_mkdir(path0);
|
||||
free(path0);
|
||||
}
|
||||
return fopen(path,mode);
|
||||
}
|
||||
|
||||
int slurp_write(const char *txt, const char *filename) {
|
||||
FILE *f = fopen(filename, "w");
|
||||
FILE *f = fopen_mkdir(filename, "w");
|
||||
if (!f) return 1;
|
||||
|
||||
fputs(txt, f);
|
||||
|
|
Loading…
Reference in a new issue