diff --git a/.github/workflows/render_nanomaps.yml b/.github/workflows/render_nanomaps.yml new file mode 100644 index 0000000000..6b58c9e8e0 --- /dev/null +++ b/.github/workflows/render_nanomaps.yml @@ -0,0 +1,35 @@ +# GitHub action to autorender nanomaps outside the game +# This kills off the awful verb we have that takes a full 50 seconds and hangs the whole server +# The file names and locations are VERY important here +# DO NOT EDIT THIS UNLESS YOU KNOW WHAT YOU ARE DOING +# -aa +name: 'Render Nanomaps' +on: + push: + branches: master + paths: + - 'maps/**' + +jobs: + generate_maps: + name: 'Generate NanoMaps' + runs-on: ubuntu-18.04 + steps: + - name: 'Update Branch' + uses: actions/checkout@v2 + with: + fetch-depth: 1 + + - name: 'Generate Maps' + run: './tools/github-actions/nanomap-renderer-invoker.sh' + + - name: 'Commit Maps' + run: | + git config --local user.email "action@github.com" + git config --local user.name "NanoMap Generation" + git pull origin master + git commit -m "NanoMap Auto-Update (`date`)" -a || true + - name: 'Push Maps' + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/README.md b/README.md index 2780275b94..51ceb23af6 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,8 @@ Going to make a Pull Request? Make sure you read the [CONTRIBUTING.md](.github/C VOREStation is a fork of the Polaris code branch, itself a fork of the Baystation12 code branch, for the game Space Station 13. +![Render Nanomaps](https://github.com/VOREStation/VOREStation/workflows/Render%20Nanomaps/badge.svg) + --- ### LICENSE diff --git a/code/datums/repositories/crew.dm b/code/datums/repositories/crew.dm index 7a748049bc..c45202194b 100644 --- a/code/datums/repositories/crew.dm +++ b/code/datums/repositories/crew.dm @@ -38,9 +38,10 @@ var/global/datum/repository/crew/crew_repository = new() crewmemberData["assignment"] = H.get_assignment(if_no_id="Unknown", if_no_job="No Job") if(C.sensor_mode >= SUIT_SENSOR_BINARY) - crewmemberData["dead"] = H.stat > UNCONSCIOUS + crewmemberData["dead"] = H.stat == DEAD if(C.sensor_mode >= SUIT_SENSOR_VITAL) + crewmemberData["stat"] = H.stat crewmemberData["oxy"] = round(H.getOxyLoss(), 1) crewmemberData["tox"] = round(H.getToxLoss(), 1) crewmemberData["fire"] = round(H.getFireLoss(), 1) diff --git a/code/modules/admin/admin_verb_lists.dm b/code/modules/admin/admin_verb_lists.dm index b576bec44a..0eaedc9fbe 100644 --- a/code/modules/admin/admin_verb_lists.dm +++ b/code/modules/admin/admin_verb_lists.dm @@ -181,7 +181,6 @@ var/list/admin_verbs_server = list( /datum/admins/proc/toggle_space_ninja, /client/proc/toggle_random_events, /client/proc/check_customitem_activity, - /client/proc/nanomapgen_DumpImage, /client/proc/modify_server_news, /client/proc/recipe_dump, /client/proc/panicbunker, diff --git a/code/modules/asset_cache/asset_list_items.dm b/code/modules/asset_cache/asset_list_items.dm index bb43597d95..815d250dcc 100644 --- a/code/modules/asset_cache/asset_list_items.dm +++ b/code/modules/asset_cache/asset_list_items.dm @@ -490,16 +490,14 @@ // It REALLY doesnt matter too much if these arent up to date // They are relatively big assets = list( - "southern_cross_nanomap_z1.png" = 'icons/_nanomaps/southern_cross_nanomap_z1.png', - "southern_cross_nanomap_z10.png" = 'icons/_nanomaps/southern_cross_nanomap_z10.png', - "southern_cross_nanomap_z2.png" = 'icons/_nanomaps/southern_cross_nanomap_z2.png', - "southern_cross_nanomap_z3.png" = 'icons/_nanomaps/southern_cross_nanomap_z3.png', - "southern_cross_nanomap_z5.png" = 'icons/_nanomaps/southern_cross_nanomap_z5.png', - "southern_cross_nanomap_z6.png" = 'icons/_nanomaps/southern_cross_nanomap_z6.png', + // VOREStation Edit: We don't need Southern Cross + // "southern_cross_nanomap_z1.png" = 'icons/_nanomaps/southern_cross_nanomap_z1.png', + // "southern_cross_nanomap_z10.png" = 'icons/_nanomaps/southern_cross_nanomap_z10.png', + // "southern_cross_nanomap_z2.png" = 'icons/_nanomaps/southern_cross_nanomap_z2.png', + // "southern_cross_nanomap_z3.png" = 'icons/_nanomaps/southern_cross_nanomap_z3.png', + // "southern_cross_nanomap_z5.png" = 'icons/_nanomaps/southern_cross_nanomap_z5.png', + // "southern_cross_nanomap_z6.png" = 'icons/_nanomaps/southern_cross_nanomap_z6.png', "tether_nanomap_z1.png" = 'icons/_nanomaps/tether_nanomap_z1.png', - "tether_nanomap_z10.png" = 'icons/_nanomaps/tether_nanomap_z10.png', - "tether_nanomap_z13.png" = 'icons/_nanomaps/tether_nanomap_z13.png', - "tether_nanomap_z14.png" = 'icons/_nanomaps/tether_nanomap_z14.png', "tether_nanomap_z2.png" = 'icons/_nanomaps/tether_nanomap_z2.png', "tether_nanomap_z3.png" = 'icons/_nanomaps/tether_nanomap_z3.png', "tether_nanomap_z4.png" = 'icons/_nanomaps/tether_nanomap_z4.png', @@ -508,4 +506,8 @@ "tether_nanomap_z7.png" = 'icons/_nanomaps/tether_nanomap_z7.png', "tether_nanomap_z8.png" = 'icons/_nanomaps/tether_nanomap_z8.png', "tether_nanomap_z9.png" = 'icons/_nanomaps/tether_nanomap_z9.png', + "tether_nanomap_z10.png" = 'icons/_nanomaps/tether_nanomap_z10.png', + "tether_nanomap_z13.png" = 'icons/_nanomaps/tether_nanomap_z13.png', + "tether_nanomap_z14.png" = 'icons/_nanomaps/tether_nanomap_z14.png', + // VOREStation Edit End ) \ No newline at end of file diff --git a/code/modules/tgui/nanomapgen.dm b/code/modules/tgui/nanomapgen.dm deleted file mode 100644 index 79c2332901..0000000000 --- a/code/modules/tgui/nanomapgen.dm +++ /dev/null @@ -1,92 +0,0 @@ -// This file is a modified version of https://raw2.github.com/Baystation12/OldCode-BS12/master/code/TakePicture.dm - -#define NANOMAP_ICON_SIZE 4 -#define NANOMAP_MAX_ICON_DIMENSION 1200 - -#define NANOMAP_TILES_PER_IMAGE (NANOMAP_MAX_ICON_DIMENSION / NANOMAP_ICON_SIZE) - -#define NANOMAP_TERMINALERR 5 -#define NANOMAP_INPROGRESS 2 -#define NANOMAP_BADOUTPUT 2 -#define NANOMAP_SUCCESS 1 -#define NANOMAP_WATCHDOGSUCCESS 4 -#define NANOMAP_WATCHDOGTERMINATE 3 - - -//Call these procs to dump your world to a series of image files (!!) -//NOTE: Does not explicitly support non 32x32 icons or stuff with large pixel_* values, so don't blame me if it doesn't work perfectly - -/client/proc/nanomapgen_DumpImage() - set name = "Generate NanoUI Map" - set category = "Server" - - if(holder) - nanomapgen_DumpTile(1, 1, text2num(input(usr,"Enter the Z level to generate"))) - -/client/proc/nanomapgen_DumpTile(var/startX = 1, var/startY = 1, var/currentZ = 1, var/endX = -1, var/endY = -1) - - if (endX < 0 || endX > world.maxx) - endX = world.maxx - - if (endY < 0 || endY > world.maxy) - endY = world.maxy - - if (currentZ < 0 || currentZ > world.maxz) - to_chat(usr, "NanoMapGen: ERROR: currentZ ([currentZ]) must be between 1 and [world.maxz]") - - sleep(3) - return NANOMAP_TERMINALERR - - if (startX > endX) - to_chat(usr, "NanoMapGen: ERROR: startX ([startX]) cannot be greater than endX ([endX])") - - sleep(3) - return NANOMAP_TERMINALERR - - if (startY > endX) - to_chat(usr, "NanoMapGen: ERROR: startY ([startY]) cannot be greater than endY ([endY])") - sleep(3) - return NANOMAP_TERMINALERR - - var/icon/Tile = icon('icons/_nanomaps/mapbase1200.png') - if (Tile.Width() != NANOMAP_MAX_ICON_DIMENSION || Tile.Height() != NANOMAP_MAX_ICON_DIMENSION) - to_world_log("NanoMapGen: ERROR: BASE IMAGE DIMENSIONS ARE NOT [NANOMAP_MAX_ICON_DIMENSION]x[NANOMAP_MAX_ICON_DIMENSION]") - sleep(3) - return NANOMAP_TERMINALERR - - Tile.Scale((endX - startX + 1) * NANOMAP_ICON_SIZE, (endY - startY + 1) * NANOMAP_ICON_SIZE) // VOREStation Edit - Scale image to actual size mapped. - - to_world_log("NanoMapGen: GENERATE MAP ([startX],[startY],[currentZ]) to ([endX],[endY],[currentZ])") - to_chat(usr, "NanoMapGen: GENERATE MAP ([startX],[startY],[currentZ]) to ([endX],[endY],[currentZ])") - - var/count = 0; - for(var/WorldX = startX, WorldX <= endX, WorldX++) - for(var/WorldY = startY, WorldY <= endY, WorldY++) - - var/atom/Turf = locate(WorldX, WorldY, currentZ) - - var/icon/TurfIcon = new(Turf.icon, Turf.icon_state) - TurfIcon.Scale(NANOMAP_ICON_SIZE, NANOMAP_ICON_SIZE) - - Tile.Blend(TurfIcon, ICON_OVERLAY, ((WorldX - 1) * NANOMAP_ICON_SIZE), ((WorldY - 1) * NANOMAP_ICON_SIZE)) - - count++ - - if (count % 8000 == 0) - to_world_log("NanoMapGen: [count] tiles done") - sleep(1) - - var/mapFilename = "nanomap_z[currentZ]-new.png" - - to_world_log("NanoMapGen: sending [mapFilename] to client") - - usr << browse(Tile, "window=picture;file=[mapFilename];display=0") - - to_world_log("NanoMapGen: Done.") - - to_chat(usr, "NanoMapGen: Done. File [mapFilename] uploaded to your cache.") - - if (Tile.Width() != NANOMAP_MAX_ICON_DIMENSION || Tile.Height() != NANOMAP_MAX_ICON_DIMENSION) - return NANOMAP_BADOUTPUT - - return NANOMAP_SUCCESS \ No newline at end of file diff --git a/icons/_nanomaps/tether_nanomap_z1.png b/icons/_nanomaps/tether_nanomap_z1.png index c463bd04b7..03aad88117 100644 Binary files a/icons/_nanomaps/tether_nanomap_z1.png and b/icons/_nanomaps/tether_nanomap_z1.png differ diff --git a/icons/_nanomaps/tether_nanomap_z13.png b/icons/_nanomaps/tether_nanomap_z13.png index 6f87d9911f..83792e9db4 100644 Binary files a/icons/_nanomaps/tether_nanomap_z13.png and b/icons/_nanomaps/tether_nanomap_z13.png differ diff --git a/icons/_nanomaps/tether_nanomap_z14.png b/icons/_nanomaps/tether_nanomap_z14.png index 84d106a5ac..aa62758eb1 100644 Binary files a/icons/_nanomaps/tether_nanomap_z14.png and b/icons/_nanomaps/tether_nanomap_z14.png differ diff --git a/icons/_nanomaps/tether_nanomap_z2.png b/icons/_nanomaps/tether_nanomap_z2.png index 5ccd461808..8b52113523 100644 Binary files a/icons/_nanomaps/tether_nanomap_z2.png and b/icons/_nanomaps/tether_nanomap_z2.png differ diff --git a/icons/_nanomaps/tether_nanomap_z3.png b/icons/_nanomaps/tether_nanomap_z3.png index 0761eed916..e3838796e0 100644 Binary files a/icons/_nanomaps/tether_nanomap_z3.png and b/icons/_nanomaps/tether_nanomap_z3.png differ diff --git a/icons/_nanomaps/tether_nanomap_z4.png b/icons/_nanomaps/tether_nanomap_z4.png index f6465c7c13..34759796d5 100644 Binary files a/icons/_nanomaps/tether_nanomap_z4.png and b/icons/_nanomaps/tether_nanomap_z4.png differ diff --git a/icons/_nanomaps/tether_nanomap_z5.png b/icons/_nanomaps/tether_nanomap_z5.png index d8aece303d..394c1052a7 100644 Binary files a/icons/_nanomaps/tether_nanomap_z5.png and b/icons/_nanomaps/tether_nanomap_z5.png differ diff --git a/icons/_nanomaps/tether_nanomap_z6.png b/icons/_nanomaps/tether_nanomap_z6.png index 7fb5111527..6d67bae632 100644 Binary files a/icons/_nanomaps/tether_nanomap_z6.png and b/icons/_nanomaps/tether_nanomap_z6.png differ diff --git a/icons/_nanomaps/tether_nanomap_z7.png b/icons/_nanomaps/tether_nanomap_z7.png index 7645d78d09..8e03cc03fc 100644 Binary files a/icons/_nanomaps/tether_nanomap_z7.png and b/icons/_nanomaps/tether_nanomap_z7.png differ diff --git a/icons/_nanomaps/tether_nanomap_z8.png b/icons/_nanomaps/tether_nanomap_z8.png index c973b2b784..3d2acaf6b4 100644 Binary files a/icons/_nanomaps/tether_nanomap_z8.png and b/icons/_nanomaps/tether_nanomap_z8.png differ diff --git a/icons/_nanomaps/tether_nanomap_z9.png b/icons/_nanomaps/tether_nanomap_z9.png index bff91820dd..734f44dd95 100644 Binary files a/icons/_nanomaps/tether_nanomap_z9.png and b/icons/_nanomaps/tether_nanomap_z9.png differ diff --git a/tgui/packages/tgui/components/NanoMap.js b/tgui/packages/tgui/components/NanoMap.js index 261fb8b1d3..2d7f969890 100644 --- a/tgui/packages/tgui/components/NanoMap.js +++ b/tgui/packages/tgui/components/NanoMap.js @@ -1,38 +1,44 @@ -import { Box, Icon, Tooltip } from '.'; import { Component } from 'inferno'; +import { Box, Button, Icon, Tooltip, LabeledList, Slider } from '.'; import { useBackend } from "../backend"; -import { resolveAsset } from '../assets'; -import { logger } from '../logging'; + +const pauseEvent = e => { + if (e.stopPropagation) { e.stopPropagation(); } + if (e.preventDefault) { e.preventDefault(); } + e.cancelBubble = true; + e.returnValue = false; + return false; +}; export class NanoMap extends Component { constructor(props) { super(props); // Auto center based on window size + const Xcenter = (window.innerWidth / 2) - 256; + const Ycenter = (window.innerHeight / 2) - 256; + this.state = { - offsetX: 0, - offsetY: 0, + offsetX: Xcenter, + offsetY: Ycenter, transform: 'none', dragging: false, originX: null, originY: null, + zoom: 1, }; + // Dragging this.handleDragStart = e => { - document.body.style['pointer-events'] = 'none'; this.ref = e.target; this.setState({ dragging: false, originX: e.screenX, originY: e.screenY, }); - this.timer = setTimeout(() => { - this.setState({ - dragging: true, - }); - }, 250); document.addEventListener('mousemove', this.handleDragMove); document.addEventListener('mouseup', this.handleDragEnd); + pauseEvent(e); }; this.handleDragMove = e => { @@ -41,8 +47,8 @@ export class NanoMap extends Component { const newOffsetX = e.screenX - state.originX; const newOffsetY = e.screenY - state.originY; if (prevState.dragging) { - state.offsetX += (newOffsetX / this.props.zoom); - state.offsetY += (newOffsetY / this.props.zoom); + state.offsetX += newOffsetX; + state.offsetY += newOffsetY; state.originX = e.screenX; state.originY = e.screenY; } else { @@ -50,11 +56,10 @@ export class NanoMap extends Component { } return state; }); + pauseEvent(e); }; this.handleDragEnd = e => { - document.body.style['pointer-events'] = 'auto'; - clearTimeout(this.timer); this.setState({ dragging: false, originX: null, @@ -62,28 +67,54 @@ export class NanoMap extends Component { }); document.removeEventListener('mousemove', this.handleDragMove); document.removeEventListener('mouseup', this.handleDragEnd); + pauseEvent(e); }; + + this.handleZoom = (_e, value) => { + this.setState(state => { + const newZoom = Math.min(Math.max(value, 1), 8); + let zoomDiff = (newZoom - state.zoom) * 1.5; + state.zoom = newZoom; + + let newOffsetX = state.offsetX - 262 * zoomDiff; + if (newOffsetX < -500) { newOffsetX = -500; } + if (newOffsetX > 500) { newOffsetX = 500; } + + let newOffsetY = state.offsetY - 256 * zoomDiff; + if (newOffsetY < -200) { newOffsetY = -200; } + if (newOffsetY > 200) { newOffsetY = 200; } + + state.offsetX = newOffsetX; + state.offsetY = newOffsetY; + if (props.onZoom) { + props.onZoom(state.zoom); + } + return state; + }); + }; + } render() { const { config } = useBackend(this.context); - const { offsetX, offsetY } = this.state; - const { children, zoom, reset } = this.props; + const { dragging, offsetX, offsetY, zoom = 1 } = this.state; + const { children } = this.props; - let matrix - = `matrix(${zoom}, 0, 0, ${zoom}, ${offsetX * zoom}, ${offsetY * zoom})`; - + const mapUrl = config.map + "_nanomap_z" + config.mapZLevel + ".png"; + // (x * zoom), x Needs to be double the turf- map size. (for virgo, 140x140) + const mapSize = (280 * zoom) + 'px'; const newStyle = { - width: '560px', - height: '560px', + width: mapSize, + height: mapSize, + "margin-top": offsetY + "px", + "margin-left": offsetX + "px", "overflow": "hidden", "position": "relative", - "padding": "0px", - "background-image": - "url("+config.map+"_nanomap_z"+config.mapZLevel+".png)", + "background-image": "url(" + mapUrl + ")", "background-size": "cover", + "background-repeat": "no-repeat", "text-align": "center", - "transform": matrix, + "cursor": dragging ? "move" : "auto", }; return ( @@ -96,6 +127,7 @@ export class NanoMap extends Component { {children} + ); } @@ -105,31 +137,73 @@ const NanoMapMarker = (props, context) => { const { x, y, - zoom, + zoom = 1, icon, tooltip, color, onClick, } = props; - const rx = (x * 4) - 5; - const ry = (y * 4) - 4; + const handleOnClick = e => { + pauseEvent(e); + onClick(e); + }; + + const rx = ((x * 2 * zoom) - zoom) - 3; + const ry = ((y * 2 * zoom) - zoom) - 3; return ( - - - - +
+ + + + +
); }; NanoMap.Marker = NanoMapMarker; + +const NanoMapZoomer = (props, context) => { + const { act, config, data } = useBackend(context); + return ( + + + + v + "x"} + value={props.zoom} + onDrag={(e, v) => props.onZoom(e, v)} + /> + + + {data.map_levels + .sort((a, b) => Number(a) - Number(b)) + .map(level => ( +