Last active
April 15, 2020 14:03
-
-
Save zeddash/e081c7ec579943e2c8dcdc0d07681e8a to your computer and use it in GitHub Desktop.
staircase generator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "scripts": [], | |
| "styles": [] | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //https://developer.valvesoftware.com/wiki/Valve_Map_Format | |
| /* | |
| style | |
| step | |
| top | |
| side | |
| under | |
| stringer | |
| top | |
| side | |
| ramp | |
| side | |
| */ | |
| const stairStyles = { | |
| dev:{ | |
| maps:[], | |
| step: { | |
| top:"DEV/GRAYGRID", | |
| sides:"DEV/REFLECTIVITY_30", | |
| positions: { | |
| top:{ | |
| u:"world", | |
| v:"world" | |
| }, | |
| sides:{ | |
| u:"world", | |
| v:"world" | |
| } | |
| } | |
| }, | |
| stringer:{ | |
| top:"DEV/REFLECTIVITY_10B", | |
| sides:"DEV/REFLECTIVITY_10B", | |
| positions: { | |
| top:{ | |
| u:"world", | |
| v:"world" | |
| }, | |
| sides:{ | |
| u:"world", | |
| v:"world" | |
| } | |
| } | |
| } | |
| }, | |
| wooden1:{ | |
| maps:["pl_badwater"], | |
| step: { | |
| top:"WOOD/WOOD_BEAM03", | |
| sides:"WOOD/WALL020B", | |
| positions: { | |
| top:{ | |
| u:"world", | |
| v:"world" | |
| }, | |
| sides:{ | |
| u:"world", | |
| v:"world" | |
| } | |
| } | |
| }, | |
| stringer:{ | |
| top:"WOOD/WOOD_BEAM03", | |
| sides:"WOOD/WOOD_BEAM03", | |
| positions: { | |
| top:{ | |
| u:"random", | |
| v:"world" | |
| }, | |
| sides:{ | |
| u:"world", | |
| v:"world" | |
| } | |
| } | |
| } | |
| }, | |
| metal1:{ | |
| maps:[], | |
| step: { | |
| top:"METAL/IMETAL005", | |
| sides:"METAL/METALSTAIR001A", | |
| positions: { | |
| top:{ | |
| u:"random", | |
| v:"random" | |
| }, | |
| sides:{ | |
| u:"world", | |
| v:-48 //bottom step is y -48, each step up adds 32 so second step is -16, then 16, etc | |
| } | |
| } | |
| }, | |
| stringer:{ | |
| top:"METAL/METALTRACK001", | |
| sides:"METAL/METALTRACK001", | |
| positions: { | |
| top:{ | |
| u:"random", | |
| v:"world" | |
| }, | |
| sides:{ | |
| u:"random", | |
| v:"world" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| const settings = { | |
| step:{ | |
| depth:12, | |
| height:8, | |
| count:16 | |
| }, | |
| type:"ramp", //ramp, ramp + stringer, hanging tread, hanging tread + stringer, spiral, spiral + stringer | |
| stringer:null, | |
| spiral:null | |
| } | |
| const data = { | |
| id:0, | |
| uv: { | |
| x: { | |
| u:[0, -1, 0], | |
| v:[0, 0, -1] | |
| }, | |
| y: { | |
| u:[1, 0, 0], | |
| v:[0, 0, -1] | |
| }, | |
| z: { | |
| u:[-1, 0, 0], | |
| v:[0, -1, 0] | |
| } | |
| }, | |
| max: { | |
| x:0, | |
| y:0, | |
| z:0 | |
| }, | |
| checkMax: (d,v) => data.max[d] = Math.max(data.max[d], v) | |
| } | |
| class VMF { | |
| //Convert JS object into VMF format | |
| constructor(object) { | |
| this.object = object | |
| } | |
| ind = indent => ` `.repeat(indent) | |
| objectToVMF = (obj, i = 0) => | |
| `${[...Object.keys(obj)].map(x => typeof obj[x] == "object" ? Array.isArray(obj[x]) ? | |
| /*Array*/ obj[x].map(y => `${this.ind(i)}${x}\n${this.ind(i)}{\n${this.objectToVMF(y,i+1)}\n${this.ind(i)}}`).join(`\n`) : | |
| /*Object*/ `${this.ind(i)}${x}\n${this.ind(i)}{\n${this.objectToVMF(obj[x],i+1)}\n${this.ind(i)}}` : | |
| /*Other*/ `${this.ind(i)}"${x}" "${obj[x]}"`).join(`\n`)}` | |
| toString = () => { | |
| this.object.cordon.maxs = `(${data.max.x+64} ${data.max.y+64} ${data.max.z+64})` //Move this | |
| return this.objectToVMF(this.object,0) | |
| } | |
| } | |
| const GetAdjacentVertex = (d, x1, y1, z1, x2, y2, z2) => { | |
| switch (d) { | |
| case "xp": | |
| case "yn": | |
| return [x1, y1, z2] | |
| case "xn": | |
| case "zp": | |
| return [x1, y2, z1] | |
| case "yp": | |
| case "zn": | |
| return [x2, y1, z1] | |
| } | |
| } | |
| const ModifyU = (d, arr) => d[1] == "p" ? arr.map(x => x != 0 ? x *-1 : x) : arr | |
| const SideBuilder = (d, x1, y1, z1, x2, y2, z2, x3, y3, z3) => { | |
| if(x3 == undefined || y3 == undefined || z3 == undefined) { //orthagonal | |
| return SideBuilder(d, x1, y1, z1, x2, y2, z2, ...GetAdjacentVertex(d, x1, y1, z1, x2, y2, z2)) | |
| } else { //non-orthagonal | |
| return { | |
| id:data.id++, | |
| plane: `(${x1} ${y1} ${z1}) (${x3} ${y3} ${z3}) (${x2} ${y2} ${z2})`, | |
| material: "DEV/REFLECTIVITY_30", | |
| uaxis:`[${ModifyU(d,data.uv[d[0]].u).join(" ")} 0] 0.25`, | |
| vaxis:`[${data.uv[d[0]].v.join(" ")} 0] 0.25`, | |
| rotation:0, | |
| lightmapscale:16, | |
| smoothing_groups:0 | |
| } | |
| } | |
| } | |
| const BrushBuilder = (x,y,z,w,d,h,t="cuboid",o) => { | |
| data.checkMax("x",x+w) | |
| data.checkMax("y",y+d) | |
| data.checkMax("z",z+h) | |
| switch(t) { | |
| case "cuboid": | |
| return { | |
| id:data.id++, | |
| side:[ | |
| SideBuilder("xp", x+w, y, z, x+w, y+d, z+h), | |
| SideBuilder("xn", x, y, z, x, y+d, z+h), | |
| SideBuilder("yp", x, y+d, z, x+w, y+d, z+h), | |
| SideBuilder("yn", x, y, z, x+w, y, z+h), | |
| SideBuilder("zp", x, y, z+h, x+w, y+d, z+h), | |
| SideBuilder("zn", x, y, z, x+w, y+d, z) | |
| ], | |
| editor: { | |
| color: "255 255 255", | |
| visgroupshown: 1, | |
| visgroupautoshown: 1 | |
| //,groupid:0 | |
| } | |
| } | |
| case "ramp": //Lower end towards x-axis | |
| return { | |
| id:data.id++, | |
| side:[ | |
| SideBuilder("xp", x+w, y, z, x+w, y+d, z+h), | |
| SideBuilder("xn", x y, z, x, y+d, z+h), | |
| SideBuilder("yp", x, y+d, z, x+w, y+d, z+h), | |
| SideBuilder("zp", x, y, z, x+w, y+d, z+h, x, y+d, z+h), | |
| SideBuilder("zn", x, y, z, x+w, y+d, z) | |
| ], | |
| editor: { | |
| color: "255 255 255", | |
| visgroupshown: 1, | |
| visgroupautoshown: 1 | |
| //,groupid:0 | |
| } | |
| } | |
| } | |
| } | |
| const StaircaseMap = { | |
| versioninfo: { | |
| editorversion:420, | |
| editorbuild:1337, | |
| mapversion:1, | |
| formatversion:100, | |
| prefab:0 | |
| }, | |
| viewsettings: { | |
| bSnapToGrid:1, | |
| bShowGrid:1, | |
| bShowLogicalGrid:0, | |
| nGridSpacing:64, | |
| bShow3DGrid:0 | |
| }, | |
| world: { | |
| id:data.id++, | |
| mapversion:1, | |
| classname:"worldspawn", | |
| skyname:"sky_tf2_04", | |
| maxpropscreenwidth:-1, | |
| detailvbsp:"detail.vbsp", | |
| detailmaterial:"detail/detailsprites", | |
| solid:[ | |
| BrushBuilder(0,0,0,128,384,128), | |
| BrushBuilder(192,0,0,128,128*1.5,128, "ramp") | |
| ] | |
| }, | |
| cameras: { | |
| activecamera:-1 | |
| }, | |
| cordon: { | |
| mins:"(-64 -64 -64)", | |
| maxs:"(1024 1024 1024)", | |
| active:1 | |
| } | |
| } | |
| console.log(new VMF(StaircaseMap).toString()) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| body{ | |
| background: black; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment