diff --git a/.github/workflows/render_nanomaps.yml b/.github/workflows/render_nanomaps.yml index 57f305772c..d6f2622041 100644 --- a/.github/workflows/render_nanomaps.yml +++ b/.github/workflows/render_nanomaps.yml @@ -11,8 +11,13 @@ on: paths: - 'maps/**' +permissions: {} jobs: generate_maps: + permissions: + contents: write # to push to branch + pull-requests: write # to create pull requests (repo-sync/pull-request) + name: 'Generate NanoMaps' runs-on: ubuntu-latest steps: diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 4ce9b60b73..30cd6dc47b 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -6,7 +6,6 @@ "oderwat.indent-rainbow", "rexebin.darkpurple-black", "dbaeumer.vscode-eslint", - "editorconfig.editorconfig", "donkie.vscode-tgstation-test-adapter", "icrawl.discord-vscode", "esbenp.prettier-vscode", diff --git a/README.md b/README.md index 2c769a3af9..3e98669224 100644 --- a/README.md +++ b/README.md @@ -1,101 +1,103 @@ -# Yawn-Wider - -[![forthebadge](http://forthebadge.com/images/badges/60-percent-of-the-time-works-every-time.svg)](http://forthebadge.com) [![forthebadge](http://forthebadge.com/images/badges/compatibility-club-penguin.svg)](http://forthebadge.com) [![forthebadge](http://forthebadge.com/images/badges/no-ragrets.svg)](http://forthebadge.com) - -[Website (we dont have one)](https://www.youtube.com/watch?v=oHg5SJYRHA0) - [Forums](https://yawn-widerstation.proboards.com/) - [Wiki](https://yawn.izac.live/index.php?title=Main_Page) - [Discord](https://discord.gg/Wh27EAY) - -Going to make a Pull Request? Make sure you read the [CONTRIBUTING.md](.github/CONTRIBUTING.md) first! - -Yawn-Wider is a fork of the VOREStation code branch which 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/Yawn-Wider/YWPolarisVore/workflows/Render%20Nanomaps/badge.svg) -[![CI](https://github.com/Yawn-Wider/YWPolarisVore/actions/workflows/ci.yml/badge.svg)](https://github.com/Yawn-Wider/YWPolarisVore/actions/workflows/ci.yml) - ---- - -### LICENSE -The code for Yawn-Wider is licensed under the [GNU Affero General Public License](http://www.gnu.org/licenses/agpl.html) version 3, which can be found in full in LICENSE-AGPL3.txt. - -Code with a git authorship date prior to `1420675200 +0000` (2015/01/08 00:00) are licensed under the GNU General Public License version 3, which can be found in full in LICENSE-GPL3.txt. - -All code whose authorship dates are not prior to `1420675200 +0000` is assumed to be licensed under AGPL v3, if you wish to license under GPL v3 please make this clear in the commit message and any added files. - -If you wish to develop and host this codebase in a closed source manner you may use all code prior to `1420675200 +0000`, which is licensed under GPL v3. The major change here is that if you host a server using any code licensed under AGPLv3 you are required to provide full source code for your servers users as well including addons and modifications you have made. - -See [here](https://www.gnu.org/licenses/why-affero-gpl.html) for more information. - -Any files located in the -`vorestation/goon`, -`vorestation/icons/goonstation`, or -`vorestation/sound/goonstation` -directories, or any subdirectories of mentioned directories are licensed under the -Creative Commons 3.0 BY-NC-SA license -(https://creativecommons.org/licenses/by-nc-sa/3.0) - -All assets including icons and sound are under a [CC BY-SA 3.0](http://creativecommons.org/licenses/by-sa/3.0/) license unless otherwise indicated. - -Attributions and other licenses with links to original works are noted in [ATTRIBUTIONS.md](./ATTRIBUTIONS.md). - -### GETTING THE CODE -The simplest way to obtain the code is using the github .zip feature. If you do this, you won't be able to make a Pull Request later, though. You'll need to use the git method. - -Click [here](https://github.com/Yawn-Wider/YWPolarisVore/archive/master.zip) to get the latest code as a .zip file, then unzip it to wherever you want. - -The more complicated and easier to update method is using git. You'll need to download git or some client from [here](http://git-scm.com/). When that's installed, right click in any folder and click on "Git Bash". When that opens, type in: - - git clone https://github.com/Yawn-Wider/YWPolarisVore.git - -(hint: hold down ctrl and press insert to paste into git bash) - -This will take a while to download, but it provides an easier method for updating. - -### INSTALLATION - -First-time installation should be fairly straightforward. First, you'll need BYOND installed. You can get it from [here](http://www.byond.com/). - -This is a sourcecode-only release, so the next step is to compile the server files. Open vorestation.dme by double-clicking it, open the Build menu, and click compile. This'll take a little while, and if everything's done right you'll get a message like this: - - saving vorestation.dmb (DEBUG mode) - - vorestation.dmb - 0 errors, 0 warnings - -If you see any errors or warnings, something has gone wrong - possibly a corrupt download or the files extracted wrong, or a code issue on the main repo. Ask on IRC. - -Once that's done, open up the config folder. You'll want to edit config.txt to set the probabilities for different gamemodes in Secret and to set your server location so that all your players don't get disconnected at the end of each round. It's recommended you don't turn on the gamemodes with probability 0, as they have various issues and aren't currently being tested, so they may have unknown and bizarre bugs. - -You'll also want to edit admins.txt to remove the default admins and add your own. "Host" is the highest level of access, and the other recommended admin levels for now are "Game Admin" and "Moderator". The format is: - - byondkey - Rank - -where the BYOND key must be in lowercase and the admin rank must be properly capitalised. There are a bunch more admin ranks, but these two should be enough for most servers, assuming you have trustworthy admins. - -Finally, to start the server, run Dream Daemon and enter the path to your compiled vorestation.dmb file. Make sure to set the port to the one you specified in the config.txt, and set the Security box to 'Trusted'. Then press GO and the server should start up and be ready to join. - ---- - -### UPDATING - -To update an existing installation, first back up your /config and /data folders -as these store your server configuration, player preferences and banlist. - -If you used the zip method, you'll need to download the zip file again and unzip it somewhere else, and then copy the /config and /data folders over. - -If you used the git method, you simply need to type this in to git bash: - - git pull - -When this completes, copy over your /data and /config folders again, just in case. - -When you have done this, you'll need to recompile the code, but then it should work fine. - ---- - -### Configuration - -For a basic setup, simply copy every file from config/example to config. - ---- - -### SQL Setup - -The SQL backend for the library and stats tracking requires a MySQL server. Your server details go in /config/dbconfig.txt, and the SQL schema is in /SQL/tgstation_schema.sql. More detailed setup instructions arecoming soon, for now ask in our Discord. \ No newline at end of file +# Yawn-Wider + +[![forthebadge](http://forthebadge.com/images/badges/60-percent-of-the-time-works-every-time.svg)](http://forthebadge.com) [![forthebadge](http://forthebadge.com/images/badges/compatibility-club-penguin.svg)](http://forthebadge.com) [![forthebadge](http://forthebadge.com/images/badges/no-ragrets.svg)](http://forthebadge.com) + +[Website (we dont have one)](https://www.youtube.com/watch?v=oHg5SJYRHA0) - [Forums](https://yawn-widerstation.proboards.com/) - [Wiki](https://yawn.izac.live/index.php?title=Main_Page) - [Discord](https://discord.gg/Wh27EAY) + +Going to make a Pull Request? Make sure you read the [CONTRIBUTING.md](.github/CONTRIBUTING.md) first! + +Want to make a test server or your own private server? Read our [GitHub Wiki!](https://github.com/VOREStation/VOREStation/wiki) + +Yawn-Wider is a fork of the VOREStation code branch which 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/Yawn-Wider/YWPolarisVore/workflows/Render%20Nanomaps/badge.svg) +[![CI](https://github.com/Yawn-Wider/YWPolarisVore/actions/workflows/ci.yml/badge.svg)](https://github.com/Yawn-Wider/YWPolarisVore/actions/workflows/ci.yml) + +--- + +### LICENSE +The code for Yawn-Wider is licensed under the [GNU Affero General Public License](http://www.gnu.org/licenses/agpl.html) version 3, which can be found in full in LICENSE-AGPL3.txt. + +Code with a git authorship date prior to `1420675200 +0000` (2015/01/08 00:00) are licensed under the GNU General Public License version 3, which can be found in full in LICENSE-GPL3.txt. + +All code whose authorship dates are not prior to `1420675200 +0000` is assumed to be licensed under AGPL v3, if you wish to license under GPL v3 please make this clear in the commit message and any added files. + +If you wish to develop and host this codebase in a closed source manner you may use all code prior to `1420675200 +0000`, which is licensed under GPL v3. The major change here is that if you host a server using any code licensed under AGPLv3 you are required to provide full source code for your servers users as well including addons and modifications you have made. + +See [here](https://www.gnu.org/licenses/why-affero-gpl.html) for more information. + +Any files located in the +`vorestation/goon`, +`vorestation/icons/goonstation`, or +`vorestation/sound/goonstation` +directories, or any subdirectories of mentioned directories are licensed under the +Creative Commons 3.0 BY-NC-SA license +(https://creativecommons.org/licenses/by-nc-sa/3.0) + +All assets including icons and sound are under a [CC BY-SA 3.0](http://creativecommons.org/licenses/by-sa/3.0/) license unless otherwise indicated. + +Attributions and other licenses with links to original works are noted in [ATTRIBUTIONS.md](./ATTRIBUTIONS.md). + +### GETTING THE CODE +The simplest way to obtain the code is using the github .zip feature. If you do this, you won't be able to make a Pull Request later, though. You'll need to use the git method. + +Click [here](https://github.com/Yawn-Wider/YWPolarisVore/archive/master.zip) to get the latest code as a .zip file, then unzip it to wherever you want. + +The more complicated and easier to update method is using git. You'll need to download git or some client from [here](http://git-scm.com/). When that's installed, right click in any folder and click on "Git Bash". When that opens, type in: + + git clone https://github.com/Yawn-Wider/YWPolarisVore.git + +(hint: hold down ctrl and press insert to paste into git bash) + +This will take a while to download, but it provides an easier method for updating. + +### INSTALLATION + +First-time installation should be fairly straightforward. First, you'll need BYOND installed. You can get it from [here](http://www.byond.com/). + +This is a sourcecode-only release, so the next step is to compile the server files. Open vorestation.dme by double-clicking it, open the Build menu, and click compile. This'll take a little while, and if everything's done right you'll get a message like this: + + saving vorestation.dmb (DEBUG mode) + + vorestation.dmb - 0 errors, 0 warnings + +If you see any errors or warnings, something has gone wrong - possibly a corrupt download or the files extracted wrong, or a code issue on the main repo. Ask on IRC. + +Once that's done, open up the config folder. You'll want to edit config.txt to set the probabilities for different gamemodes in Secret and to set your server location so that all your players don't get disconnected at the end of each round. It's recommended you don't turn on the gamemodes with probability 0, as they have various issues and aren't currently being tested, so they may have unknown and bizarre bugs. + +You'll also want to edit admins.txt to remove the default admins and add your own. "Host" is the highest level of access, and the other recommended admin levels for now are "Game Admin" and "Moderator". The format is: + + byondkey - Rank + +where the BYOND key must be in lowercase and the admin rank must be properly capitalised. There are a bunch more admin ranks, but these two should be enough for most servers, assuming you have trustworthy admins. + +Finally, to start the server, run Dream Daemon and enter the path to your compiled vorestation.dmb file. Make sure to set the port to the one you specified in the config.txt, and set the Security box to 'Trusted'. Then press GO and the server should start up and be ready to join. + +--- + +### UPDATING + +To update an existing installation, first back up your /config and /data folders +as these store your server configuration, player preferences and banlist. + +If you used the zip method, you'll need to download the zip file again and unzip it somewhere else, and then copy the /config and /data folders over. + +If you used the git method, you simply need to type this in to git bash: + + git pull + +When this completes, copy over your /data and /config folders again, just in case. + +When you have done this, you'll need to recompile the code, but then it should work fine. + +--- + +### Configuration + +For a basic setup, simply copy every file from config/example to config. + +--- + +### SQL Setup + +The SQL backend for the library and stats tracking requires a MySQL server. Your server details go in /config/dbconfig.txt, and the SQL schema is in /SQL/tgstation_schema.sql. More detailed setup instructions arecoming soon, for now ask in our Discord. diff --git a/code/ATMOSPHERICS/components/unary/vent_pump.dm b/code/ATMOSPHERICS/components/unary/vent_pump.dm index 145381146f..4b8970fd94 100644 --- a/code/ATMOSPHERICS/components/unary/vent_pump.dm +++ b/code/ATMOSPHERICS/components/unary/vent_pump.dm @@ -94,6 +94,13 @@ assign_uid() id_tag = num2text(uid) +/obj/machinery/atmospherics/unary/vent_pump/proc/update_area() + initial_loc = get_area(loc) + area_uid = "\ref[initial_loc]" + assign_uid() + id_tag = num2text(uid) + + /obj/machinery/atmospherics/unary/vent_pump/Destroy() unregister_radio(src, frequency) if(initial_loc) diff --git a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm index 64a57a744e..fe3e68130f 100644 --- a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm +++ b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm @@ -43,6 +43,12 @@ assign_uid() id_tag = num2text(uid) +/obj/machinery/atmospherics/unary/vent_scrubber/proc/update_area() + initial_loc = get_area(loc) + area_uid = "\ref[initial_loc]" + assign_uid() + id_tag = num2text(uid) + /obj/machinery/atmospherics/unary/vent_scrubber/Destroy() unregister_radio(src, frequency) if(initial_loc) diff --git a/code/ATMOSPHERICS/datum_pipeline.dm b/code/ATMOSPHERICS/datum_pipeline.dm index 64b5490472..7a1f5cce95 100644 --- a/code/ATMOSPHERICS/datum_pipeline.dm +++ b/code/ATMOSPHERICS/datum_pipeline.dm @@ -161,16 +161,14 @@ if(istype(target, /turf/simulated)) var/turf/simulated/modeled_location = target - - if(modeled_location.special_temperature)//First do special interactions then the usuall stuff - var/delta_temp = modeled_location.special_temperature - air.temperature//2200C - 20C = 2180K - //assuming aluminium with thermal conductivity 235 W * K / m, Copper (400), Silver (430), steel (50), gold (320) - var/heat_gain = 23500 * 100 * delta_temp - air.add_thermal_energy(heat_gain) - if(network) - network.update = 1 - + if (modeled_location.special_temperature) + air.temperature += thermal_conductivity * (modeled_location.special_temperature - air.temperature) + if (air.temperature < TCMB) + air.temperature = TCMB + if (network) + network.update = TRUE + if(modeled_location.blocks_air) if((modeled_location.heat_capacity>0) && (partial_heat_capacity>0)) diff --git a/code/__defines/input.dm b/code/__defines/input.dm index cbc703935a..16afe5a2f3 100644 --- a/code/__defines/input.dm +++ b/code/__defines/input.dm @@ -10,7 +10,7 @@ // Combine the held WASD and arrow keys together (OR) into byond N/S/E/W dir #define MOVEMENT_KEYS_TO_DIR(MK) ((((MK)>>4)|(MK))&(ALL_CARDINALS)) -// Bitflags for pressed modifier keys. +// Bitflags for pressed modifier keys. // Values chosen specifically to not conflict with dir bitfield, in case we want to smoosh them together. #define CTRL_KEY (1<<8) #define SHIFT_KEY (1<<9) diff --git a/code/__defines/materials.dm b/code/__defines/materials.dm index 7086ef7c9d..97f30e5247 100644 --- a/code/__defines/materials.dm +++ b/code/__defines/materials.dm @@ -54,6 +54,8 @@ #define MAT_PLATINUM "platinum" #define MAT_TRITIUM "tritium" #define MAT_DEUTERIUM "deuterium" +#define MAT_CONCRETE "concrete" +#define MAT_PLASTEELREBAR "plasteel rebar" #define DEFAULT_TABLE_MATERIAL MAT_PLASTIC diff --git a/code/__defines/nifsoft.dm b/code/__defines/nifsoft.dm index cca614f1fb..114ee32779 100644 --- a/code/__defines/nifsoft.dm +++ b/code/__defines/nifsoft.dm @@ -40,9 +40,10 @@ #define NIF_SIZECHANGE 33 #define NIF_SOULCATCHER 34 #define NIF_WORLDBEND 35 +#define NIF_MALWARE 36 // Must be equal to the highest number above -#define TOTAL_NIF_SOFTWARE 35 +#define TOTAL_NIF_SOFTWARE 36 ////////////////////// // NIF flag list hints diff --git a/code/__defines/subsystems.dm b/code/__defines/subsystems.dm index 8ed8125dac..716a1c1540 100644 --- a/code/__defines/subsystems.dm +++ b/code/__defines/subsystems.dm @@ -118,26 +118,3 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G #define FIRE_PRIORITY_CHAT 400 #define FIRE_PRIORITY_OVERLAYS 500 #define FIRE_PRIORITY_INPUT 1000 // This must always always be the max highest priority. Player input must never be lost. - -// Macro defining the actual code applying our overlays lists to the BYOND overlays list. (I guess a macro for speed) -// TODO - I don't really like the location of this macro define. Consider it. ~Leshana -#define COMPILE_OVERLAYS(A)\ - do {\ - var/list/oo = A.our_overlays;\ - var/list/po = A.priority_overlays;\ - if(LAZYLEN(po)){\ - if(LAZYLEN(oo)){\ - A.overlays = oo + po;\ - }\ - else{\ - A.overlays = po;\ - }\ - }\ - else if(LAZYLEN(oo)){\ - A.overlays = oo;\ - }\ - else{\ - A.overlays.Cut();\ - }\ - A.flags &= ~OVERLAY_QUEUED;\ - } while (FALSE) diff --git a/code/__defines/turfs.dm b/code/__defines/turfs.dm index 1c4b228b63..fe327cd632 100644 --- a/code/__defines/turfs.dm +++ b/code/__defines/turfs.dm @@ -28,3 +28,12 @@ #define OUTDOORS_NO 0 // Ditto. #define OUTDOORS_AREA -1 // If a turf has this, it will defer to the area's settings on init. // Note that after init, it will be either YES or NO. + +//supposedly the fastest way to do this according to https://gist.github.com/Giacom/be635398926bb463b42a +///Returns a list of turf in a square + +#define RECT_TURFS(H_RADIUS, V_RADIUS, CENTER) \ + block( \ + locate(max(CENTER.x-(H_RADIUS),1), max(CENTER.y-(V_RADIUS),1), CENTER.z), \ + locate(min(CENTER.x+(H_RADIUS),world.maxx), min(CENTER.y+(V_RADIUS),world.maxy), CENTER.z) \ + ) \ No newline at end of file diff --git a/code/__defines/spaceman_dmm.dm b/code/__spaceman_dmm.dm similarity index 85% rename from code/__defines/spaceman_dmm.dm rename to code/__spaceman_dmm.dm index 94f1743377..51b09cd036 100644 --- a/code/__defines/spaceman_dmm.dm +++ b/code/__spaceman_dmm.dm @@ -1,7 +1,8 @@ -// Interfaces for the SpacemanDMM linter, define'd to nothing when the linter -// is not in use. +/** +* SpacemanDMM dreamchecker extensions for suite 1.7 +* +*/ -// The SPACEMAN_DMM define is set by the linter and other tooling when it runs. #ifdef SPACEMAN_DMM #define RETURN_TYPE(X) set SpacemanDMM_return_type = X #define SHOULD_CALL_PARENT(X) set SpacemanDMM_should_call_parent = X diff --git a/code/_global_vars/lists/misc.dm b/code/_global_vars/lists/misc.dm index a16573905e..97cc3753a1 100644 --- a/code/_global_vars/lists/misc.dm +++ b/code/_global_vars/lists/misc.dm @@ -2,7 +2,8 @@ GLOBAL_LIST_INIT(speech_toppings, list("|" = "i", "+" = "b", "_" = "u")) GLOBAL_LIST_EMPTY(meteor_list) /// List of wire colors for each object type of that round. One for airlocks, one for vendors, etc. -GLOBAL_LIST_EMPTY(wire_color_directory) // This is an associative list with the `holder_type` as the key, and a list of colors as the value. +GLOBAL_LIST_EMPTY(wire_color_directory) // This is an associative list with the `holder_type` as the key, and a list of colors as the value. +GLOBAL_LIST_EMPTY(wire_name_directory) // This is an associative list // Reference list for disposal sort junctions. Filled up by sorting junction's New() GLOBAL_LIST_EMPTY(tagger_locations) diff --git a/code/_helpers/global_lists_vr.dm b/code/_helpers/global_lists_vr.dm index d7d180d4df..513154dafd 100644 --- a/code/_helpers/global_lists_vr.dm +++ b/code/_helpers/global_lists_vr.dm @@ -43,7 +43,7 @@ var/global/list/item_vore_blacklist = list( /obj/item/weapon/gun, /obj/item/weapon/pinpointer, /obj/item/clothing/shoes/magboots, - /obj/item/blueprints, + /obj/item/areaeditor/blueprints, /obj/item/clothing/head/helmet/space, /obj/item/weapon/disk/nuclear, /obj/item/clothing/suit/storage/hooded/wintercoat/roiz) @@ -825,4 +825,96 @@ var/global/list/xenobio_rainbow_extracts = list( /obj/item/slime_extract/ruby = 3, /obj/item/slime_extract/emerald = 3, /obj/item/slime_extract/light_pink = 1, - /obj/item/slime_extract/rainbow = 1) \ No newline at end of file + /obj/item/slime_extract/rainbow = 1) + + +// AREA GENERATION AND BLUEPRINT STUFF BELOW HERE +// typecacheof(list) and list() are two completely separate things, don't break! + +// WHATEVER YOU DO, DO NOT LEAVE THE LAST THING IN THE LIST BELOW HAVE A COMMA OR EVERYTHING EVER WILL BREAK +// ENSURE THE LAST AREA OR TURF LISTED IS SIMPLY "/area/clownhideout" AND NOT "/area/clownhideout," OR YOU WILL IMMEDIATELY DIE + +// These lists are, obviously, unfinished. + +// ALLOWING BUILDING IN AN AREA: +// If you want someone to be able to build a new area in a place, add the area to the 'BUILDABLE_AREA_TYPES' and 'blacklisted_areas' +// BUILDABLE_AREA_TYPES means they can build an area there. The blacklisted_areas means they CAN NOT EXPAND that area. No making space bigger! + +// DISALLOW BUILDING/AREA MANIPULATION IN AN AREA (OR A TURF TYPE): +// Likewise, if you want someone to never ever EVER be able to do anything area generation/expansion related to an area +// Then add it to SPECIALS and area_or_turf_fail_types + +// If you want someone to +var/global/list/BUILDABLE_AREA_TYPES = list( + /area/space, + /area/mine, +// /area/surface/outside, //SC +// /area/surface/cave, //SC + /area/tether/surfacebase/outside, + /area/groundbase/unexplored/outdoors, + /area/maintenance/groundbase/level1, + /area/submap/groundbase/wilderness, + /area/groundbase/mining, + /area/offmap/aerostat/surface, + /area/tether_away/beach, + /area/tether_away/cave, +) + +var/static/list/blacklisted_areas = typecacheof(list( + /area/space, + /area/mine, +// /area/surface/outside, //SC +// /area/surface/cave, //SC + //TETHER STUFF BELOW THIS + /area/tether/surfacebase/outside, + //GROUNDBASE STUFF BELOW THIS + /area/groundbase/unexplored/outdoors, + /area/maintenance/groundbase/level1, + /area/submap/groundbase/wilderness, + /area/groundbase/mining, + /area/offmap/aerostat/surface, + /area/tether_away/beach, + /area/tether_away/cave + )) + +var/global/list/SPECIALS = list( + /turf/space, + /area/shuttle, + /area/admin, + /area/arrival, + /area/centcom, + /area/asteroid, + /area/tdome, + /area/syndicate_station, + /area/wizard_station, + /area/prison, + /area/holodeck, + /area/turbolift, + /area/tether/elevator, + /turf/unsimulated/wall/planetary, + /area/submap/virgo2, + /area/submap/event, + /area/submap/casino_event + // /area/derelict //commented out, all hail derelict-rebuilders! +) + +var/global/list/area_or_turf_fail_types = typecacheof(list( + /turf/space, + /area/shuttle, + /area/admin, + /area/arrival, + /area/centcom, + /area/asteroid, + /area/tdome, + /area/syndicate_station, + /area/wizard_station, + /area/prison, + /area/holodeck, + /turf/simulated/wall/elevator, + /area/turbolift, + /area/tether/elevator, + /turf/unsimulated/wall/planetary, + /area/submap/virgo2, + /area/submap/event, + /area/submap/casino_event + )) diff --git a/code/_helpers/type2type.dm b/code/_helpers/type2type.dm index 700bbbfc57..ef25f44142 100644 --- a/code/_helpers/type2type.dm +++ b/code/_helpers/type2type.dm @@ -98,12 +98,18 @@ if(!direction) return "" var/list/dirs = list() - if(direction & NORTH) dirs += "NORTH" - if(direction & SOUTH) dirs += "SOUTH" - if(direction & EAST) dirs += "EAST" - if(direction & WEST) dirs += "WEST" - if(direction & UP) dirs += "UP" - if(direction & DOWN) dirs += "DOWN" + if(direction & NORTH) + dirs += "NORTH" + if(direction & SOUTH) + dirs += "SOUTH" + if(direction & EAST) + dirs += "EAST" + if(direction & WEST) + dirs += "WEST" + if(direction & UP) + dirs += "UP" + if(direction & DOWN) + dirs += "DOWN" return dirs.Join(" ") // Converts an angle (degrees) into an ss13 direction @@ -315,4 +321,4 @@ error("File not found ([filename])") catch(var/exception/E) if(error_on_invalid_return) - error("Exception when loading file as string: [E]") \ No newline at end of file + error("Exception when loading file as string: [E]") diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm index 84844936c4..d0a7bff2e0 100644 --- a/code/_helpers/unsorted.dm +++ b/code/_helpers/unsorted.dm @@ -643,6 +643,20 @@ Turf and target are seperate in case you want to teleport some distance from a t for(var/turf/T in N) turfs += T return turfs + +//Takes: An instance of the area. +//Returns: A list of all turfs in that area. +//Side note: I don't know why this was never a thing. Did everyone just ignore the Blueprint item?! - C.L. +/proc/get_current_area_turfs(var/area/checked_area) + if(!checked_area) + return null + + var/list/turfs = new/list() + for(var/turf/counted_turfs in checked_area.contents) //Cheap. Efficient. Lovely. + turfs += counted_turfs + return turfs + + //Takes: Area type as text string or as typepath OR an instance of the area. //Returns: A list of all atoms (objs, turfs, mobs) in areas of that type of that type in the world. /proc/get_area_all_atoms(var/areatype) @@ -659,6 +673,18 @@ Turf and target are seperate in case you want to teleport some distance from a t atoms += A return atoms + +//Takes: Area as an instance of the area. +//Returns: A list of all atoms (objs, turfs, mobs) in the selected area. +/proc/get_current_area_atoms(var/area/checked_area) + if(!checked_area) + return null + + var/list/atoms = new/list() + for(var/atom/A in checked_area.contents) + atoms += A + return atoms + /datum/coords //Simple datum for storing coordinates. var/x_pos = null var/y_pos = null diff --git a/code/_onclick/hud/popups_vr.dm b/code/_onclick/hud/popups_vr.dm new file mode 100644 index 0000000000..76e72224ef --- /dev/null +++ b/code/_onclick/hud/popups_vr.dm @@ -0,0 +1,71 @@ +/obj/screen/popup + name = "popup" + desc = "NOTICE ME!" + + icon = 'icons/mob/screen1_popups.dmi' + plane = PLANE_PLAYER_HUD_ABOVE + layer = INFINITY + + var/close_button_x_start + var/close_button_x_end + var/close_button_y_start + var/close_button_y_end + + var/client/holder + +/obj/screen/popup/Click(location, control,params) + var/list/PL = params2list(params) + var/icon_x = text2num(PL["icon-x"]) + var/icon_y = text2num(PL["icon-y"]) + if(check_click_spot(icon_x, icon_y)) + close_popup() + else + popup_action() + +/obj/screen/popup/proc/popup_action() + return + +/obj/screen/popup/proc/close_popup() + holder.screen -= src + qdel(src) + +/obj/screen/popup/proc/check_click_spot(click_x, click_y) + if((click_x <= close_button_x_end) && (click_x >= close_button_x_start)) + if((click_y <= close_button_y_end) && (click_y >= close_button_y_start)) + return TRUE + return FALSE + +/obj/screen/popup/proc/get_random_screen_location() + var/loc_x = rand(1,11) + var/loc_x_offset = rand(0,16) + var/loc_y = rand(1,12) + var/loc_y_offset = rand(0,16) + return "[loc_x]:[loc_x_offset],[loc_y]:[loc_y_offset]" + +/client/proc/create_fake_ad_popup(popup_type) + if(!src) + return + var/obj/screen/popup/ad = new popup_type() + ad.screen_loc = ad.get_random_screen_location() + src.screen |= ad + ad.holder = src + +/client/proc/create_fake_ad_popup_multiple(popup_type, popup_amount) + if(!src) + return + for(var/i = 0, i < popup_amount, i++) + create_fake_ad_popup(popup_type) + +/obj/screen/popup/default + name = "CLICK ME" + + icon_state = "popup1" + + close_button_x_start = 118 + close_button_x_end = 126 + close_button_y_start = 86 + close_button_y_end = 94 + +/obj/screen/popup/default/New() + ..() + icon_state = "popup[rand(1,4)]" \ No newline at end of file diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 8954bf45bc..72e2219ad8 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -167,6 +167,9 @@ vis_contents -= hover_overlays_cache[hovering_choice] hovering_choice = choice + if(!choice) + return + var/obj/effect/overlay/zone_sel/overlay_object = hover_overlays_cache[choice] if(!overlay_object) overlay_object = new @@ -174,7 +177,6 @@ hover_overlays_cache[choice] = overlay_object vis_contents += overlay_object - /obj/effect/overlay/zone_sel icon = 'icons/mob/zone_sel.dmi' mouse_opacity = MOUSE_OPACITY_TRANSPARENT @@ -240,7 +242,7 @@ update_icon() /obj/screen/zone_sel/update_icon() - cut_overlay(selecting_appearance) + cut_overlays() selecting_appearance = mutable_appearance('icons/mob/zone_sel.dmi', "[selecting]") add_overlay(selecting_appearance) @@ -985,4 +987,4 @@ else //"0" is still length 1 so this means it's over 999 overlays += image('icons/mob/screen_ammo.dmi', src, "o9") overlays += image('icons/mob/screen_ammo.dmi', src, "t9") - overlays += image('icons/mob/screen_ammo.dmi', src, "h9") \ No newline at end of file + overlays += image('icons/mob/screen_ammo.dmi', src, "h9") diff --git a/code/controllers/subsystems/ai.dm b/code/controllers/subsystems/ai.dm index 41fb3a7e29..eb29e2fec2 100644 --- a/code/controllers/subsystems/ai.dm +++ b/code/controllers/subsystems/ai.dm @@ -39,7 +39,7 @@ SUBSYSTEM_DEF(ai) if(!L?.loc) continue - if(process_z[get_z(L)] || !L.low_priority) //VOREStation Edit End + if((get_z(L) && process_z[get_z(L)]) || !L.low_priority) //VOREStation Edit End A.handle_strategicals() else slept_mobs++ diff --git a/code/controllers/subsystems/mobs.dm b/code/controllers/subsystems/mobs.dm index 1c80497983..c124b5573e 100644 --- a/code/controllers/subsystems/mobs.dm +++ b/code/controllers/subsystems/mobs.dm @@ -15,7 +15,7 @@ SUBSYSTEM_DEF(mobs) var/list/currentrun = list() var/log_extensively = FALSE var/list/timelog = list() - + var/slept_mobs = 0 var/list/process_z = list() @@ -40,10 +40,10 @@ SUBSYSTEM_DEF(mobs) if(!M || QDELETED(M)) mob_list -= M continue - else if(M.low_priority && !(M.loc && process_z[get_z(M)])) + else if(M.low_priority && !(M.loc && get_z(M) && process_z[get_z(M)])) slept_mobs++ continue - + M.Life(times_fired) if (MC_TICK_CHECK) @@ -58,14 +58,14 @@ SUBSYSTEM_DEF(mobs) log_world(msg) return msg += "Lists: currentrun: [currentrun.len], mob_list: [mob_list.len]\n" - + if(!currentrun.len) msg += "!!The subsystem just finished the mob_list list, and currentrun is empty (or has never run).\n" msg += "!!The info below is the tail of mob_list instead of currentrun.\n" - + var/datum/D = currentrun.len ? currentrun[currentrun.len] : mob_list[mob_list.len] msg += "Tail entry: [describeThis(D)] (this is likely the item AFTER the problem item)\n" - + var/position = mob_list.Find(D) if(!position) msg += "Unable to find context of tail entry in mob_list list.\n" diff --git a/code/controllers/subsystems/overlays.dm b/code/controllers/subsystems/overlays.dm index 92400e495b..25dbfbd62a 100644 --- a/code/controllers/subsystems/overlays.dm +++ b/code/controllers/subsystems/overlays.dm @@ -1,176 +1,149 @@ SUBSYSTEM_DEF(overlays) name = "Overlay" flags = SS_TICKER - wait = 1 + wait = 1 // SS_TICKER - Ticks priority = FIRE_PRIORITY_OVERLAYS init_order = INIT_ORDER_OVERLAY - var/list/queue // Queue of atoms needing overlay compiling (TODO-VERIFY!) - var/list/stats - var/list/overlay_icon_state_caches // Cache thing - var/list/overlay_icon_cache // Cache thing + /// The queue of atoms that need overlay updates. + var/static/tmp/list/queue = list() - var/static/image/stringbro - var/static/image/iconbro - var/static/image/appearance_bro + /// A list([icon] = list([state] = [appearance], ...), ...) cache of appearances. + var/static/tmp/list/state_cache = list() -/datum/controller/subsystem/overlays/PreInit() - overlay_icon_state_caches = list() - overlay_icon_cache = list() - queue = list() - stats = list() + /// A list([icon] = [appearance], ...) cache of appearances. + var/static/tmp/list/icon_cache = list() - stringbro = new() - iconbro = new() - appearance_bro = new() + /// The number of appearances currently cached. + var/static/tmp/cache_size = 0 -/datum/controller/subsystem/overlays/Initialize() - fire(mc_check = FALSE) + +/datum/controller/subsystem/overlays/Recover() + queue.Cut() + state_cache.Cut() + icon_cache.Cut() + cache_size = 0 + for (var/atom/atom) + atom.flags &= ~OVERLAY_QUEUED + CHECK_TICK + + +/datum/controller/subsystem/overlays/Initialize(timeofday) + fire(FALSE, TRUE) ..() /datum/controller/subsystem/overlays/stat_entry() - ..("Ov:[length(queue)]") + ..("Queued Atoms: [queue.len], Cache Size: [cache_size]") -/datum/controller/subsystem/overlays/Shutdown() - text2file(render_stats(stats), "[log_path]-overlay.log") - -/datum/controller/subsystem/overlays/Recover() - overlay_icon_state_caches = SSoverlays.overlay_icon_state_caches - overlay_icon_cache = SSoverlays.overlay_icon_cache - queue = SSoverlays.queue - - -/datum/controller/subsystem/overlays/fire(resumed = FALSE, mc_check = TRUE) - var/list/queue = src.queue - var/static/count = 0 - if (count) - var/c = count - count = 0 //so if we runtime on the Cut, we don't try again. - queue.Cut(1,c+1) - - for (var/thing in queue) - count++ - if(thing) - STAT_START_STOPWATCH - var/atom/A = thing - COMPILE_OVERLAYS(A) - STAT_STOP_STOPWATCH - STAT_LOG_ENTRY(stats, A.type) - if(mc_check) - if(MC_TICK_CHECK) - break - else +/datum/controller/subsystem/overlays/fire(resumed, no_mc_tick) + var/count = 1 + for (var/atom/atom as anything in queue) + ++count + atom?.UpdateOverlays() + if (no_mc_tick) CHECK_TICK + else if (MC_TICK_CHECK) + queue.Cut(1, count) + return + queue.Cut() - if (count) - queue.Cut(1,count+1) - count = 0 -/proc/iconstate2appearance(icon, iconstate) - // var/static/image/stringbro = new() // Moved to be superglobal due to BYOND insane init order stupidness. - var/list/icon_states_cache = SSoverlays.overlay_icon_state_caches - var/list/cached_icon = icon_states_cache[icon] - if (cached_icon) - var/cached_appearance = cached_icon["[iconstate]"] - if (cached_appearance) - return cached_appearance - SSoverlays.stringbro.icon = icon - SSoverlays.stringbro.icon_state = iconstate - if (!cached_icon) //not using the macro to save an associated lookup - cached_icon = list() - icon_states_cache[icon] = cached_icon - var/cached_appearance = SSoverlays.stringbro.appearance - cached_icon["[iconstate]"] = cached_appearance - return cached_appearance +/datum/controller/subsystem/overlays/proc/GetStateAppearance(icon, state) + var/list/subcache = state_cache[icon] + if (!subcache) + subcache = list() + state_cache[icon] = subcache + if (!subcache[state]) + var/image/image = new (icon, null, state) + subcache[state] = image.appearance + ++cache_size + return subcache[state] -/proc/icon2appearance(icon) - // var/static/image/iconbro = new() // Moved to be superglobal due to BYOND insane init order stupidness. - var/list/icon_cache = SSoverlays.overlay_icon_cache - . = icon_cache[icon] - if (!.) - SSoverlays.iconbro.icon = icon - . = SSoverlays.iconbro.appearance - icon_cache[icon] = . -/atom/proc/build_appearance_list(old_overlays) - // var/static/image/appearance_bro = new() // Moved to be superglobal due to BYOND insane init order stupidness. - var/list/new_overlays = list() - if (!islist(old_overlays)) - old_overlays = list(old_overlays) - for (var/overlay in old_overlays) - if(!overlay) +/datum/controller/subsystem/overlays/proc/GetIconAppearance(icon) + if (!icon_cache[icon]) + var/image/image = new (icon) + icon_cache[icon] = image.appearance + ++cache_size + return icon_cache[icon] + + +/datum/controller/subsystem/overlays/proc/GetAppearanceList(atom/subject, list/sources) + if (!sources) + return list() + if (!islist(sources)) + sources = list(sources) + var/list/result = list() + var/icon/icon = subject.icon + for (var/atom/entry as anything in sources) + if (!entry) continue - if (istext(overlay)) - new_overlays += iconstate2appearance(icon, overlay) - else if(isicon(overlay)) - new_overlays += icon2appearance(overlay) + else if (istext(entry)) + result += GetStateAppearance(icon, entry) + else if (isicon(entry)) + result += GetIconAppearance(entry) else - if(isloc(overlay)) - var/atom/A = overlay - if (A.flags & OVERLAY_QUEUED) - COMPILE_OVERLAYS(A) - SSoverlays.appearance_bro.appearance = overlay //this works for images and atoms too! - if(!ispath(overlay)) - var/image/I = overlay - SSoverlays.appearance_bro.dir = I.dir - new_overlays += SSoverlays.appearance_bro.appearance - return new_overlays + if (isloc(entry)) + if (entry.flags & OVERLAY_QUEUED) + entry.ImmediateOverlayUpdate() + if (!ispath(entry)) + result += entry.appearance + else + var/image/image = entry + result += image.appearance + return result -#define NOT_QUEUED_ALREADY (!(flags & OVERLAY_QUEUED)) -#define QUEUE_FOR_COMPILE flags |= OVERLAY_QUEUED; SSoverlays.queue += src; -/** - * Cut all of atom's normal overlays. Usually leaves "priority" overlays untouched. - * - * @param priority If true, also will cut priority overlays. - */ -/atom/proc/cut_overlays(priority = FALSE) - var/list/cached_overlays = our_overlays - var/list/cached_priority = priority_overlays - - var/need_compile = FALSE - - if(LAZYLEN(cached_overlays)) //don't queue empty lists, don't cut priority overlays - cached_overlays.Cut() //clear regular overlays - need_compile = TRUE - - if(priority && LAZYLEN(cached_priority)) - cached_priority.Cut() - need_compile = TRUE - - if(NOT_QUEUED_ALREADY && need_compile) - QUEUE_FOR_COMPILE - -/** - * Removes specific overlay(s) from the atom. Usually does not remove them from "priority" overlays. - * - * @param overlays The overlays to removed, type can be anything that is allowed for add_overlay(). - * @param priority If true, also will remove them from the "priority" overlays. - */ -/atom/proc/cut_overlay(list/overlays, priority) - if(!overlays) +/// Enqueues the atom for an overlay update if not already queued +/atom/proc/QueueOverlayUpdate() + if (flags & OVERLAY_QUEUED) return + SSoverlays.queue += src + flags |= OVERLAY_QUEUED - overlays = build_appearance_list(overlays) - var/list/cached_overlays = our_overlays //sanic - var/list/cached_priority = priority_overlays - var/init_o_len = LAZYLEN(cached_overlays) - var/init_p_len = LAZYLEN(cached_priority) //starter pokemon +/// Builds the atom's overlay state from caches +/atom/proc/UpdateOverlays() + if (gc_destroyed) + if (length(overlays)) + overlays.Cut() + return + flags &= ~OVERLAY_QUEUED + if (length(priority_overlays)) + if (length(our_overlays)) + overlays = priority_overlays + our_overlays + else + overlays = priority_overlays + else if (length(our_overlays)) + overlays = our_overlays + else + overlays.Cut() - LAZYREMOVE(cached_overlays, overlays) - if(priority) - LAZYREMOVE(cached_priority, overlays) - if(NOT_QUEUED_ALREADY && ((init_o_len != LAZYLEN(cached_overlays)) || (init_p_len != LAZYLEN(cached_priority)))) - QUEUE_FOR_COMPILE +/// Immediately runs an overlay update and dequeues the atom +/atom/proc/ImmediateOverlayUpdate() + SSoverlays.queue -= src + UpdateOverlays() + + +/// Clears the atom's overlay cache(s) and queues an update if needed +/atom/proc/cut_overlays(priority) + if (priority) + if (!length(priority_overlays)) + return + priority_overlays.Cut() + QueueOverlayUpdate() + else if (length(our_overlays)) + our_overlays.Cut() + QueueOverlayUpdate() + /** * Adds specific overlay(s) to the atom. * It is designed so any of the types allowed to be added to /atom/overlays can be added here too. More details below. * - * @param overlays The overlay(s) to add. These may be + * @param add The overlay(s) to add. These may be * - A string: In which case it is treated as an icon_state of the atom's icon. * - An icon: It is treated as an icon. * - An atom: Its own overlays are compiled and then it's appearance is added. (Meaning its current apperance is frozen). @@ -179,30 +152,46 @@ SUBSYSTEM_DEF(overlays) * - Or a list containing any of the above. * @param priority The overlays are added to the "priority" list istead of the normal one. */ -/atom/proc/add_overlay(list/overlays, priority = FALSE) - if(!overlays) +/atom/proc/add_overlay(list/add, priority) + if (!add) return - - overlays = build_appearance_list(overlays) - - LAZYINITLIST(our_overlays) //always initialized after this point - LAZYINITLIST(priority_overlays) - - var/list/cached_overlays = our_overlays //sanic - var/list/cached_priority = priority_overlays - var/init_o_len = cached_overlays.len - var/init_p_len = cached_priority.len //starter pokemon - var/need_compile - - if(priority) - cached_priority += overlays //or in the image. Can we use [image] = image? - need_compile = init_p_len != cached_priority.len + add = SSoverlays.GetAppearanceList(src, add) + if (!length(add)) + return + if (priority) + if (priority_overlays) + priority_overlays += add + else + priority_overlays = add + else if (our_overlays) + our_overlays += add else - cached_overlays += overlays - need_compile = init_o_len != cached_overlays.len + our_overlays = add + QueueOverlayUpdate() + + +/** + * Removes specific overlay(s) from the atom. Usually does not remove them from "priority" overlays. + * + * @param overlays The overlays to removed, type can be anything that is allowed for add_overlay(). + * @param priority If true, also will remove them from the "priority" overlays. + */ +/atom/proc/cut_overlay(list/cut, priority) + if (!cut) + return + cut = SSoverlays.GetAppearanceList(src, cut) + if (!length(cut)) + return + var/update + if (priority && length(priority_overlays)) + priority_overlays -= cut + update = TRUE + if (length(our_overlays)) + our_overlays -= cut + update = TRUE + if (update) + QueueOverlayUpdate() - if(NOT_QUEUED_ALREADY && need_compile) //have we caught more pokemon? - QUEUE_FOR_COMPILE /** * Copy the overlays from another atom, either replacing all of ours or appending to our existing overlays. @@ -211,22 +200,21 @@ SUBSYSTEM_DEF(overlays) * @param other The atom to copy overlays from. * @param cut_old If true, all of our overlays will be *replaced* by the other's. If other is null, that means cutting all ours. */ -/atom/proc/copy_overlays(atom/other, cut_old) //copys our_overlays from another atom - if(!other) - if(cut_old) +/atom/proc/copy_overlays(atom/other, cut) + if (!other) + if (cut) cut_overlays() return + if (!length(other.our_overlays)) + if (cut) + cut_overlays() + return + if (cut || !length(our_overlays)) + our_overlays = other.our_overlays.Copy() + else + our_overlays |= other.our_overlays + QueueOverlayUpdate() - var/list/cached_other = other.our_overlays - if(cached_other) - if(cut_old || !LAZYLEN(our_overlays)) - our_overlays = cached_other.Copy() - else - our_overlays |= cached_other - if(NOT_QUEUED_ALREADY) - QUEUE_FOR_COMPILE - else if(cut_old) - cut_overlays() /** * Returns a list of overlays that the target atom has @@ -236,37 +224,32 @@ SUBSYSTEM_DEF(overlays) */ /proc/get_overlays(atom/other, priority, special) var/list/including = list() - if(!other) + if (!other) return including - - for(var/image/I as anything in other.our_overlays) - if(!special && I.plane > 0) + for (var/image/I as anything in other.our_overlays) + if (!special && I.plane > 0) continue including += I - - if(!priority) + if (!priority) return including - - for(var/image/I as anything in other.priority_overlays) - if(!special && I.plane > 0) + for (var/image/I as anything in other.priority_overlays) + if (!special && I.plane > 0) continue including += I - return including -#undef NOT_QUEUED_ALREADY -#undef QUEUE_FOR_COMPILE - -//TODO: Better solution for these? /image/proc/add_overlay(x) overlays += x + /image/proc/cut_overlay(x) overlays -= x + /image/proc/cut_overlays(x) overlays.Cut() + /image/proc/copy_overlays(atom/other, cut_old) if(!other) if(cut_old) diff --git a/code/controllers/subsystems/processing/instruments.dm b/code/controllers/subsystems/processing/instruments.dm index 3f305fb8fc..72770ea39b 100644 --- a/code/controllers/subsystems/processing/instruments.dm +++ b/code/controllers/subsystems/processing/instruments.dm @@ -34,7 +34,7 @@ PROCESSING_SUBSYSTEM_DEF(instruments) /datum/controller/subsystem/processing/instruments/proc/initialize_instrument_data() for(var/datum/instrument/I as anything in subtypesof(/datum/instrument)) - if(initial(I.abstract_type) == I) + if(initial(I.instrument_type) == I) continue I = new I I.Initialize() diff --git a/code/core/atom/Transform.dm b/code/core/atom/Transform.dm new file mode 100644 index 0000000000..8a914a52ed --- /dev/null +++ b/code/core/atom/Transform.dm @@ -0,0 +1,53 @@ +/// The atom's base transform scale for width. +/atom/var/tf_scale_x + +/// The atom's base transform scale for height. +/atom/var/tf_scale_y + +/// The atom's base transform scale for rotation. +/atom/var/tf_rotation + +/// The atom's base transform scale for horizontal offset. +/atom/var/tf_offset_x + +/// The atom's base transform scale for vertical offset. +/atom/var/tf_offset_y + + +/// Clear the atom's tf_* variables and the current transform state. +/atom/proc/ClearTransform() + tf_scale_x = null + tf_scale_y = null + tf_rotation = null + tf_offset_x = null + tf_offset_y = null + transform = null + + +/// Sets the atom's tf_* variables and the current transform state, also applying others if supplied. +/atom/proc/SetTransform( + scale, + scale_x = tf_scale_x, + scale_y = tf_scale_y, + rotation = tf_rotation, + offset_x = tf_offset_x, + offset_y = tf_offset_y, + list/others +) + if (!isnull(scale)) + tf_scale_x = scale + tf_scale_y = scale + else + tf_scale_x = scale_x + tf_scale_y = scale_y + tf_rotation = rotation + tf_offset_x = offset_x + tf_offset_y = offset_y + transform = matrix().Update( + scale_x = tf_scale_x, + scale_y = tf_scale_y, + rotation = tf_rotation, + offset_x = tf_offset_x, + offset_y = tf_offset_y, + others = others + ) diff --git a/code/core/datum/IsAbstract.dm b/code/core/datum/IsAbstract.dm new file mode 100644 index 0000000000..12263dc098 --- /dev/null +++ b/code/core/datum/IsAbstract.dm @@ -0,0 +1,23 @@ +/** +* Abstract-ness is a meta-property of a class that is used to indicate +* that the class is intended to be used as a base class for others, and +* should not (or cannot) be instantiated. +* We have no such language concept in DM, and so we provide a datum member +* that can be used to hint at abstractness for circumstances where we would +* like that to be the case, such as base behavior providers. +*/ + +/// If set, a path at/above this one that expects not to be instantiated. +/datum/var/abstract_type + +/// If true, this datum is an instance of an abstract type. Oops. +/datum/proc/IsAbstract() + SHOULD_NOT_OVERRIDE(TRUE) + return type == abstract_type + +/// Passed a path or instance, returns whether it is abstract. Otherwise null. +/proc/is_abstract(datum/thing) + if (ispath(thing)) + return thing == initial(thing.abstract_type) + if (istype(thing)) + return thing.IsAbstract() diff --git a/code/core/image/Transform.dm b/code/core/image/Transform.dm new file mode 100644 index 0000000000..8129952939 --- /dev/null +++ b/code/core/image/Transform.dm @@ -0,0 +1,53 @@ +/// The image's base transform scale for width. +/image/var/tf_scale_x + +/// The image's base transform scale for height. +/image/var/tf_scale_y + +/// The image's base transform scale for rotation. +/image/var/tf_rotation + +/// The image's base transform scale for horizontal offset. +/image/var/tf_offset_x + +/// The image's base transform scale for vertical offset. +/image/var/tf_offset_y + + +/// Clear the image's tf_* variables and the current transform state. +/image/proc/ClearTransform() + tf_scale_x = null + tf_scale_y = null + tf_rotation = null + tf_offset_x = null + tf_offset_y = null + transform = null + + +/// Sets the image's tf_* variables and the current transform state, also applying others if supplied. +/image/proc/SetTransform( + scale, + scale_x = tf_scale_x, + scale_y = tf_scale_y, + rotation = tf_rotation, + offset_x = tf_offset_x, + offset_y = tf_offset_y, + list/others +) + if (!isnull(scale)) + tf_scale_x = scale + tf_scale_y = scale + else + tf_scale_x = scale_x + tf_scale_y = scale_y + tf_rotation = rotation + tf_offset_x = offset_x + tf_offset_y = offset_y + transform = matrix().Update( + scale_x = tf_scale_x, + scale_y = tf_scale_y, + rotation = tf_rotation, + offset_x = tf_offset_x, + offset_y = tf_offset_y, + others = others + ) diff --git a/code/core/matrix/Transform.dm b/code/core/matrix/Transform.dm new file mode 100644 index 0000000000..c3efc59d9a --- /dev/null +++ b/code/core/matrix/Transform.dm @@ -0,0 +1,27 @@ +/// Clears the matrix's a-f variables to identity. +/matrix/proc/Clear() + a = 1 + b = 0 + c = 0 + d = 0 + e = 1 + f = 0 + return src + + +/// Runs Scale, Turn, and Translate if supplied parameters, then multiplies by others if set. +/matrix/proc/Update(scale_x, scale_y, rotation, offset_x, offset_y, list/others) + var/x_null = isnull(scale_x) + var/y_null = isnull(scale_y) + if (!x_null || !y_null) + Scale(x_null ? 1 : scale_x, y_null ? 1 : scale_y) + if (!isnull(rotation)) + Turn(rotation) + if (offset_x || offset_y) + Translate(offset_x || 0, offset_y || 0) + if (islist(others)) + for (var/other in others) + Multiply(other) + else if (others) + Multiply(others) + return src diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index b2ff9beff4..04f489be7c 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -338,18 +338,7 @@ var/global/list/PDA_Manifest = list() var/datum/job/J = SSjob.get_job(H.mind.assigned_role) hidden = J?.offmap_spawn - /* Note: Due to cached_character_icon, a number of emergent properties occur due to the initialization - * order of readied-up vs latejoiners. Namely, latejoiners will get a uniform in their datacore picture, but readied-up will - * not. This is due to the fact that SSticker calls data_core.manifest_inject() inside of ticker/proc/create_characters(), - * but does not equip them until ticker/proc/equip_characters(), which is called later. So, this proc is literally called before - * they ever get their equipment, and so it can't get a picture of them in their equipment. - * Latejoiners do not have this problem, because /mob/new_player/proc/AttemptLateSpawn calls EquipRank() before it calls - * this proc, which means that they're already clothed by the time they get their picture taken here. - * The COMPILE_OVERLAYS() here is just to bypass SSoverlays taking for-fucking-ever to update the mob, since we're about to - * take a picture of them, we want all the overlays. - */ - COMPILE_OVERLAYS(H) - SSoverlays.queue -= H + H.ImmediateOverlayUpdate() var/id = generate_record_id() //General Record diff --git a/code/datums/supplypacks/hospitality.dm b/code/datums/supplypacks/hospitality.dm index bcf472a0b9..fcc6e0562c 100644 --- a/code/datums/supplypacks/hospitality.dm +++ b/code/datums/supplypacks/hospitality.dm @@ -47,7 +47,7 @@ cost = 10 containertype = /obj/structure/closet/crate/gilthari containername = "crate of bar supplies" - + /datum/supply_pack/hospitality/cookingoil name = "Cooking oil tank crate" contains = list(/obj/structure/reagent_dispensers/cookingoil) @@ -96,6 +96,14 @@ containertype = /obj/structure/closet/crate/centauri containername = "Painting equipment" +/datum/supply_pack/hospitality/holywater + name = "Holy water crate" + contains = list( + /obj/item/weapon/reagent_containers/food/drinks/bottle/holywater = 3 + ) + cost = 15 + containertype = /obj/structure/closet/crate/gilthari + containername = "holy water crate" + /datum/supply_pack/randomised/hospitality/ group = "Hospitality" - diff --git a/code/datums/supplypacks/materials.dm b/code/datums/supplypacks/materials.dm index 3268d05a46..d06238dc41 100644 --- a/code/datums/supplypacks/materials.dm +++ b/code/datums/supplypacks/materials.dm @@ -83,4 +83,11 @@ containertype = /obj/structure/closet/crate/grayson containername = "Linoleum crate" cost = 15 - contains = list(/obj/fiftyspawner/linoleum) \ No newline at end of file + contains = list(/obj/fiftyspawner/linoleum) + +/datum/supply_pack/materials/concrete + name = "Concrete" + cost = 10 + containertype = /obj/structure/closet/crate/grayson + contains = list(/obj/fiftyspawner/concrete) + containername = "Concrete bricks crate" \ No newline at end of file diff --git a/code/datums/supplypacks/munitions.dm b/code/datums/supplypacks/munitions.dm index 73d150fd03..ee75b8efde 100644 --- a/code/datums/supplypacks/munitions.dm +++ b/code/datums/supplypacks/munitions.dm @@ -75,6 +75,19 @@ containername = "Shotgun crate" access = access_armory /* VOREStation edit -- This is a bad idea. -- So is this. + +/datum/supply_pack/munitions/shotgunsemi + name = "Weapons - Semi-Automatic Shotgun crate" + contains = list( + /obj/item/ammo_magazine/ammo_box/b12g, + /obj/item/ammo_magazine/ammo_box/b12g/pellet, + /obj/item/weapon/gun/projectile/shotgun/semi = 2 + ) + cost = 100 + containertype = /obj/structure/closet/crate/secure/weapon + containername = "Semi-Auto Shotgun crate" + access = access_armory + /datum/supply_pack/munitions/erifle name = "Weapons - Energy marksman" contains = list(/obj/item/weapon/gun/energy/sniperrifle = 2) diff --git a/code/datums/supplypacks/vending_refills_vr.dm b/code/datums/supplypacks/vending_refills_vr.dm index 348193a1bf..bfa42113f7 100644 --- a/code/datums/supplypacks/vending_refills_vr.dm +++ b/code/datums/supplypacks/vending_refills_vr.dm @@ -18,11 +18,6 @@ name = "SweatMAX Vendor Refill Cartridge" cost = 10 -/datum/supply_pack/vending_refills/hotfood - contains = list(/obj/item/weapon/refill_cartridge/autoname/food/hotfood) - name = "Hot Foods Vendor Refill Cartridge" - cost = 10 - /datum/supply_pack/vending_refills/weeb contains = list(/obj/item/weapon/refill_cartridge/autoname/food/weeb) name = "Nippon-tan Vendor Refill Cartridge" @@ -122,7 +117,6 @@ num_contained = 5 contains = list(/obj/item/weapon/refill_cartridge/autoname/food/snack, /obj/item/weapon/refill_cartridge/autoname/food/fitness, - /obj/item/weapon/refill_cartridge/autoname/food/hotfood, /obj/item/weapon/refill_cartridge/autoname/food/weeb, /obj/item/weapon/refill_cartridge/autoname/food/sol, /obj/item/weapon/refill_cartridge/autoname/food/snix, diff --git a/code/datums/underwear/socks.dm b/code/datums/underwear/socks.dm index e1fe7e07f2..16465cfb61 100644 --- a/code/datums/underwear/socks.dm +++ b/code/datums/underwear/socks.dm @@ -60,4 +60,128 @@ /datum/category_item/underwear/socks/leggings name = "Leggings" - icon_state = "leggings" \ No newline at end of file + icon_state = "leggings" + + + +//NEW SOCKS BELOW HERE +/datum/category_item/underwear/socks/white_norm + name = "White Socks" + icon_state = "white_norm" + has_color = TRUE + +/datum/category_item/underwear/socks/white_short + name = "Short White Socks" + icon_state = "white_short" + has_color = TRUE + +/datum/category_item/underwear/socks/white_knee + name = "White Knee Socks" + icon_state = "white_knee" + has_color = TRUE + +/datum/category_item/underwear/socks/white_thigh + name = "White Thigh Socks" + icon_state = "white_thigh" + has_color = TRUE + +/datum/category_item/underwear/socks/black_norm + name = "Black Socks" + icon_state = "black_norm" + +/datum/category_item/underwear/socks/black_short + name = "Short Black Socks" + icon_state = "black_short" + +/datum/category_item/underwear/socks/black_knee + name = "Black Knee Socks" + icon_state = "black_knee" + +/datum/category_item/underwear/socks/black_thigh + name = "Black Thigh Socks" + icon_state = "black_thigh" + +/datum/category_item/underwear/socks/assblastusa_knee + name = "Striped Patriotic Knee Socks" + icon_state = "assblastusa_knee" + +/datum/category_item/underwear/socks/assblastusa_thigh + name = "Striped Patriotic Thigh Socks" + icon_state = "assblastusa_thigh" + +/datum/category_item/underwear/socks/uk_knee + name = "United Kingdom Knee Socks" + icon_state = "uk_knee" + +/datum/category_item/underwear/socks/uk_thigh + name = "United Kingdom Thigh Socks" + icon_state = "uk_thigh" + +/datum/category_item/underwear/socks/commie_knee + name = "Yellow and Red Striped Knee Socks" + icon_state = "commie_knee" + +/datum/category_item/underwear/socks/commie_thigh + name = "Yellow and Red Striped Thigh Socks" + icon_state = "commie_thigh" + +/datum/category_item/underwear/socks/stockings_lpink + name = "Light Pink Stockings" + icon_state = "stockings_lpink" + +/datum/category_item/underwear/socks/stockings_purple + name = "Purple Stockings" + icon_state = "stockings_purple" + +/datum/category_item/underwear/socks/stockings_green + name = "Green Stockings" + icon_state = "stockings_green" + +/datum/category_item/underwear/socks/stockings_cyan + name = "Cyan Stockings" + icon_state = "stockings_cyan" + +/datum/category_item/underwear/socks/stockings_orange + name = "Orange Stockings" + icon_state = "stockings_orange" + +/datum/category_item/underwear/socks/stockings_yellow + name = "Yellow Stockings" + icon_state = "stockings_yellow" + +/datum/category_item/underwear/socks/stockings_dpink + name = "Dark Pink Stockings" + icon_state = "stockings_dpink" + +/datum/category_item/underwear/socks/stockings_blue + name = "Blue Stockings" + icon_state = "stockings_blue" + +/datum/category_item/underwear/socks/bee_thigh + name = "Bee Thigh Socks" + icon_state = "bee_thigh" + +/datum/category_item/underwear/socks/bee_knee + name = "Bee Knee Socks" //You do not know how much I want to make a 'bee's knees' pun. + icon_state = "bee_knee" + +/datum/category_item/underwear/socks/thocks + name = "Thocks" + icon_state = "thocks" + has_color = TRUE + +/datum/category_item/underwear/socks/ace_thigh + name = "Ace Pride Thigh Socks" + icon_state = "ace_thigh" + +/datum/category_item/underwear/socks/ace_knee + name = "Ace Pride Knee Socks" + icon_state = "ace_knee" + +/datum/category_item/underwear/socks/trans_knee + name = "Trans Pride Knee Socks" + icon_state = "trans_knee" + +/datum/category_item/underwear/socks/trans_thigh + name = "Trans Pride Thigh Socks" + icon_state = "trans_thigh" diff --git a/code/datums/uplink/armor.dm b/code/datums/uplink/armor.dm index 0d7d814310..362aec5d92 100644 --- a/code/datums/uplink/armor.dm +++ b/code/datums/uplink/armor.dm @@ -6,25 +6,25 @@ /datum/uplink_item/item/armor/combat name = "Combat Armor Set" - item_cost = 60 + item_cost = 30 path = /obj/item/weapon/storage/box/syndie_kit/combat_armor /datum/uplink_item/item/armor/heavy_vest name = "Heavy Armor Vest" - item_cost = 40 + item_cost = 20 path = /obj/item/clothing/suit/storage/vest/heavy/merc /datum/uplink_item/item/armor/gorlexsuit name = "Mercenary Voidsuit" - item_cost = 40 + item_cost = 20 path = /obj/item/weapon/storage/box/syndie_kit/voidsuit /datum/uplink_item/item/armor/gorlexsuit_fire name = "Mercenary Voidsuit (Fire)" - item_cost = 40 + item_cost = 20 path = /obj/item/weapon/storage/box/syndie_kit/voidsuit/fire /datum/uplink_item/item/armor/combat name = "Combat Platecarrier Set" - item_cost = 60 + item_cost = 30 path = /obj/item/clothing/suit/armor/pcarrier/merc diff --git a/code/datums/uplink/medical.dm b/code/datums/uplink/medical.dm index c7b0b0d123..c1ff848877 100644 --- a/code/datums/uplink/medical.dm +++ b/code/datums/uplink/medical.dm @@ -6,88 +6,108 @@ /datum/uplink_item/item/medical/onegativeblood name = "O- Blood Pack" - item_cost = 5 + item_cost = 1 path = /obj/item/weapon/reagent_containers/blood/OMinus /datum/uplink_item/item/medical/sinpockets name = "Box of Sin-Pockets" - item_cost = 5 + item_cost = 1 path = /obj/item/weapon/storage/box/sinpockets /datum/uplink_item/item/medical/ambrosiaseeds name = "Box of 7x ambrosia seed packets" - item_cost = 5 + item_cost = 1 path = /obj/item/weapon/storage/box/ambrosia /datum/uplink_item/item/medical/clotting name = "Clotting Medicine injector" - item_cost = 10 + item_cost = 5 path = /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/clotting /datum/uplink_item/item/medical/clotting_case name = "Clotting Medicine case" - item_cost = 20 + item_cost = 10 desc = "A case of three myelamine injectors. Can rapidly remove and stow up to six injectors." path = /obj/item/weapon/storage/quickdraw/syringe_case/clotting /datum/uplink_item/item/medical/bonemeds name = "Bone Repair injector" - item_cost = 10 + item_cost = 5 path = /obj/item/weapon/reagent_containers/hypospray/autoinjector/bonemed /datum/uplink_item/item/medical/clonemeds name = "Clone injector" - item_cost = 15 + item_cost = 5 path = /obj/item/weapon/reagent_containers/hypospray/autoinjector/clonemed /datum/uplink_item/item/medical/bonemeds_case name = "Bone Repair case" - item_cost = 20 + item_cost = 10 desc = "A case of three osteodaxon injectors. Can rapidly remove and stow up to six injectors." path = /obj/item/weapon/storage/quickdraw/syringe_case/bonemed /datum/uplink_item/item/medical/clonemeds_case name = "Clone case" - item_cost = 30 + item_cost = 10 desc = "A case of three rezadone injectors. Can rapidly remove and stow up to six injectors." path = /obj/item/weapon/storage/quickdraw/syringe_case/clonemed /datum/uplink_item/item/medical/ambrosiadeusseeds name = "Box of 7x ambrosia deus seed packets" - item_cost = 10 + item_cost = 5 path = /obj/item/weapon/storage/box/ambrosiadeus /datum/uplink_item/item/medical/freezer name = "Portable Freezer" - item_cost = 10 + item_cost = 1 path = /obj/item/weapon/storage/box/freezer /datum/uplink_item/item/medical/monkeycubes name = "Box, Monkey Cubes" - item_cost = 10 + item_cost = 1 path = /obj/item/weapon/storage/box/monkeycubes /datum/uplink_item/item/medical/farwacubes name = "Box, Farwa Cubes" - item_cost = 10 + item_cost = 1 path = /obj/item/weapon/storage/box/monkeycubes /datum/uplink_item/item/medical/neaeracubes name = "Box, Neaera Cubes" - item_cost = 10 + item_cost = 1 path = /obj/item/weapon/storage/box/monkeycubes/neaeracubes /datum/uplink_item/item/medical/stokcubes name = "Box, Stok Cubes" - item_cost = 10 + item_cost = 1 path = /obj/item/weapon/storage/box/monkeycubes/stokcubes /datum/uplink_item/item/medical/surgery name = "Surgery kit" - item_cost = 45 + item_cost = 5 path = /obj/item/weapon/storage/firstaid/surgery +/datum/uplink_item/item/medical/toxins + name = "Anti-toxins medical kit" + item_cost = 5 + path = /obj/item/weapon/storage/firstaid/toxin + +/datum/uplink_item/item/medical/o2 + name = "oxygen deprivation medical kit" + item_cost = 5 + path = /obj/item/weapon/storage/firstaid/o2 + +/datum/uplink_item/item/medical/fire + name = "fire medical kit" + item_cost = 5 + path = /obj/item/weapon/storage/firstaid/fire + +/datum/uplink_item/item/medical/adv + name = "advanced medical kit" + item_cost = 10 + path = /obj/item/weapon/storage/firstaid/adv + /datum/uplink_item/item/medical/combat name = "Combat medical kit" - item_cost = 60 + item_cost = 20 path = /obj/item/weapon/storage/firstaid/combat diff --git a/code/datums/uplink/stealthy_weapons.dm b/code/datums/uplink/stealthy_weapons.dm index 2f4cab5ff7..570b8c3341 100644 --- a/code/datums/uplink/stealthy_weapons.dm +++ b/code/datums/uplink/stealthy_weapons.dm @@ -11,7 +11,7 @@ /datum/uplink_item/item/stealthy_weapons/concealed_cane name = "Concealed Cane Sword" - item_cost = 10 + item_cost = 40 path = /obj/item/weapon/cane/concealed /datum/uplink_item/item/stealthy_weapons/detomatix diff --git a/code/datums/uplink/visible_weapons.dm b/code/datums/uplink/visible_weapons.dm index b939e953de..6c063ffb58 100644 --- a/code/datums/uplink/visible_weapons.dm +++ b/code/datums/uplink/visible_weapons.dm @@ -138,6 +138,11 @@ name = "Combat Shotgun" item_cost = 75 path = /obj/item/weapon/gun/projectile/shotgun/pump/combat + +/datum/uplink_item/item/visible_weapons/semishotgun + name = "Semi-Automatic Shotgun" + item_cost = 100 + path = /obj/item/weapon/gun/projectile/shotgun/semi /datum/uplink_item/item/visible_weapons/leveraction name = "Lever Action Rifle" diff --git a/code/datums/wires/wires.dm b/code/datums/wires/wires.dm index 83ebb65fa8..9a411c60ee 100644 --- a/code/datums/wires/wires.dm +++ b/code/datums/wires/wires.dm @@ -43,6 +43,7 @@ if(!GLOB.wire_color_directory[holder_type]) randomize() GLOB.wire_color_directory[holder_type] = colors + GLOB.wire_name_directory[holder_type] = proper_name else colors = GLOB.wire_color_directory[holder_type] diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index 7bbf96b28c..2dacb33732 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -1,807 +1,889 @@ -/obj/item/weapon/phone - name = "red phone" - desc = "Should anything ever go wrong..." - icon = 'icons/obj/items.dmi' - icon_state = "red_phone" - force = 3.0 - throwforce = 2.0 - throw_speed = 1 - throw_range = 4 - w_class = ITEMSIZE_SMALL - attack_verb = list("called", "rang") - hitsound = 'sound/weapons/ring.ogg' - drop_sound = 'sound/items/drop/device.ogg' - pickup_sound = 'sound/items/pickup/device.ogg' - -/obj/item/weapon/rsp - name = "\improper Rapid-Seed-Producer (RSP)" - desc = "A device used to rapidly deploy seeds." - icon = 'icons/obj/items.dmi' - icon_state = "rcd" - opacity = 0 - density = FALSE - anchored = FALSE - var/stored_matter = 0 - var/mode = 1 - w_class = ITEMSIZE_NORMAL - drop_sound = 'sound/items/drop/device.ogg' - pickup_sound = 'sound/items/pickup/device.ogg' - -/obj/item/weapon/soap - name = "soap" - desc = "A cheap bar of soap. Doesn't smell." - gender = PLURAL - icon = 'icons/obj/items.dmi' - icon_state = "soap" - flags = NOCONDUCT - w_class = ITEMSIZE_SMALL - slot_flags = SLOT_HOLSTER - throwforce = 0 - throw_speed = 4 - throw_range = 20 - -/obj/item/weapon/soap/nanotrasen - desc = "A NanoTrasen-brand bar of soap. Smells of phoron." - icon_state = "soapnt" - -/obj/item/weapon/soap/deluxe - icon_state = "soapdeluxe" - -/obj/item/weapon/soap/deluxe/New() - desc = "A deluxe Waffle Co. brand bar of soap. Smells of [pick("lavender", "vanilla", "strawberry", "chocolate" ,"space")]." - ..() - -/obj/item/weapon/soap/syndie - desc = "An untrustworthy bar of soap. Smells of fear." - icon_state = "soapsyndie" - -/obj/item/weapon/bikehorn - name = "bike horn" - desc = "A horn off of a bicycle." - icon = 'icons/obj/items.dmi' - icon_state = "bike_horn" - item_state = "bike_horn" - throwforce = 3 - w_class = ITEMSIZE_SMALL - slot_flags = SLOT_HOLSTER - throw_speed = 3 - throw_range = 15 - attack_verb = list("HONKED") - var/spam_flag = 0 - -/obj/item/weapon/c_tube - name = "cardboard tube" - desc = "A tube... of cardboard." - icon = 'icons/obj/items.dmi' - icon_state = "c_tube" - throwforce = 1 - w_class = ITEMSIZE_SMALL - throw_speed = 4 - throw_range = 5 - -/obj/item/weapon/disk - name = "disk" - icon = 'icons/obj/discs_vr.dmi' //VOREStation Edit - drop_sound = 'sound/items/drop/disk.ogg' - pickup_sound = 'sound/items/pickup/disk.ogg' - -/obj/item/weapon/disk/nuclear - name = "nuclear authentication disk" - desc = "Better keep this safe." - icon_state = "nucleardisk" - item_state = "card-id" - w_class = ITEMSIZE_SMALL - -/* -/obj/item/weapon/game_kit - name = "Gaming Kit" - icon = 'icons/obj/items.dmi' - icon_state = "game_kit" - var/selected = null - var/board_stat = null - var/data = "" - var/base_url = "http://svn.slurm.us/public/spacestation13/misc/game_kit" - item_state = "sheet-metal" - w_class = ITEMSIZE_HUGE -*/ - -/obj/item/weapon/gift - name = "gift" - desc = "A wrapped item." - icon = 'icons/obj/items.dmi' - icon_state = "gift3" - var/size = 3.0 - var/obj/item/gift = null - item_state = "gift" - w_class = ITEMSIZE_LARGE - -/*/obj/item/weapon/syndicate_uplink - name = "station bounced radio" - desc = "Remain silent about this..." - icon = 'icons/obj/radio.dmi' - icon_state = "radio" - var/temp = null - var/uses = 10.0 - var/selfdestruct = 0.0 - var/traitor_frequency = 0.0 - var/mob/currentUser = null - var/obj/item/device/radio/origradio = null - flags = ONBELT - w_class = ITEMSIZE_SMALL - item_state = "radio" - throw_speed = 4 - throw_range = 20 - matter = list(MAT_STEEL = 100) - origin_tech = list(TECH_MAGNET = 2, TECH_ILLEGAL = 3)*/ - -/obj/item/weapon/SWF_uplink - name = "station-bounced radio" - desc = "Used to communicate, it appears." - icon = 'icons/obj/radio.dmi' - icon_state = "radio" - var/temp = null - var/uses = 4.0 - var/selfdestruct = 0.0 - var/traitor_frequency = 0.0 - var/obj/item/device/radio/origradio = null - slot_flags = SLOT_BELT - item_state = "radio" - throwforce = 5 - w_class = ITEMSIZE_SMALL - throw_speed = 4 - throw_range = 20 - matter = list(MAT_STEEL = 100) - origin_tech = list(TECH_MAGNET = 1) - drop_sound = 'sound/items/drop/device.ogg' - pickup_sound = 'sound/items/pickup/device.ogg' - -/obj/item/weapon/staff - name = "wizards staff" - desc = "Apparently a staff used by the wizard." - icon = 'icons/obj/wizard.dmi' - icon_state = "staff" - item_icons = list( - slot_l_hand_str = 'icons/mob/items/lefthand_melee.dmi', - slot_r_hand_str = 'icons/mob/items/righthand_melee.dmi', - ) - force = 3.0 - throwforce = 5.0 - throw_speed = 1 - throw_range = 5 - w_class = ITEMSIZE_SMALL - attack_verb = list("bludgeoned", "whacked", "disciplined") - -/obj/item/weapon/staff/broom - name = "broom" - desc = "Used for sweeping, and flying into the night while cackling. Black cat not included." - icon = 'icons/obj/wizard.dmi' - icon_state = "broom" - -/obj/item/weapon/staff/gentcane - name = "Gentlemans Cane" - desc = "An ebony can with an ivory tip." - icon = 'icons/obj/weapons.dmi' - icon_state = "cane" - -/obj/item/weapon/staff/stick - name = "stick" - desc = "A great tool to drag someone else's drinks across the bar." - icon = 'icons/obj/weapons.dmi' - icon_state = "stick" - item_state = "cane" - force = 3.0 - throwforce = 5.0 - throw_speed = 1 - throw_range = 5 - w_class = ITEMSIZE_SMALL - -/obj/item/weapon/module - icon = 'icons/obj/module.dmi' - icon_state = "std_module" - item_state = "std_mod" - w_class = ITEMSIZE_SMALL - var/mtype = 1 // 1=electronic 2=hardware - drop_sound = 'sound/items/drop/component.ogg' - pickup_sound = 'sound/items/pickup/component.ogg' - -/obj/item/weapon/module/card_reader - name = "card reader module" - icon_state = "card_mod" - item_state = "std_mod" - desc = "An electronic module for reading data and ID cards." - -/obj/item/weapon/module/power_control - name = "power control module" - icon_state = "power_mod" - item_state = "std_mod" - desc = "Heavy-duty switching circuits for power control." - matter = list(MAT_STEEL = 50, MAT_GLASS = 50) - -/obj/item/weapon/module/id_auth - name = "\improper ID authentication module" - icon_state = "id_mod" - desc = "A module allowing secure authorization of ID cards." - -/obj/item/weapon/module/cell_power - name = "power cell regulator module" - icon_state = "power_mod" - item_state = "std_mod" - desc = "A converter and regulator allowing the use of power cells." - -/obj/item/weapon/module/cell_power - name = "power cell charger module" - icon_state = "power_mod" - item_state = "std_mod" - desc = "Charging circuits for power cells." - -/obj/item/device/camera_bug - name = "camera bug" - icon = 'icons/obj/device.dmi' - icon_state = "flash" - w_class = ITEMSIZE_TINY - item_state = "electronic" - throw_speed = 4 - throw_range = 20 - -/obj/item/weapon/camera_bug/attack_self(mob/usr as mob) - var/list/cameras = new/list() - for (var/obj/machinery/camera/C in cameranet.cameras) - if (C.bugged && C.status) - cameras.Add(C) - if (length(cameras) == 0) - to_chat(usr, "No bugged functioning cameras found.") - return - - var/list/friendly_cameras = new/list() - - for (var/obj/machinery/camera/C in cameras) - friendly_cameras.Add(C.c_tag) - - var/target = tgui_input_list(usr, "Select the camera to observe", "Select Camera", friendly_cameras) - if (!target) - return - for (var/obj/machinery/camera/C in cameras) - if (C.c_tag == target) - target = C - break - if (usr.stat == 2) return - - usr.client.eye = target - -/* -/obj/item/weapon/cigarpacket - name = "Pete's Cuban Cigars" - desc = "The most robust cigars on the planet." - icon = 'icons/obj/cigarettes.dmi' - icon_state = "cigarpacket" - item_state = "cigarpacket" - w_class = ITEMSIZE_TINY - throwforce = 2 - var/cigarcount = 6 - flags = ONBELT - */ - -/obj/item/weapon/pai_cable - desc = "A flexible coated cable with a universal jack on one end." - name = "data cable" - icon = 'icons/obj/power.dmi' - icon_state = "wire1" - - var/obj/machinery/machine - -/obj/item/weapon/pai_cable/Destroy() - machine = null - return ..() - -///////////////////////////////////////Stock Parts ///////////////////////////////// - -/obj/item/weapon/storage/part_replacer - name = "rapid part exchange device" - desc = "A special mechanical module made to store, sort, and apply standard machine parts." - icon = 'icons/obj/storage_vr.dmi' - icon_state = "RPED" - item_state = "RPED" - w_class = ITEMSIZE_HUGE - can_hold = list(/obj/item/weapon/stock_parts) - storage_slots = 50 - use_to_pickup = TRUE - allow_quick_gather = 1 - allow_quick_empty = 1 - collection_mode = 1 - display_contents_with_number = 1 - max_w_class = ITEMSIZE_NORMAL - max_storage_space = 100 - drop_sound = 'sound/items/drop/device.ogg' - pickup_sound = 'sound/items/pickup/device.ogg' - var/panel_req = TRUE - var/pshoom_or_beepboopblorpzingshadashwoosh = 'sound/items/rped.ogg' - var/reskin_ran = FALSE - var/unique_reskin = list("Soulless" = "RPED", - "Soulful" = "RPED_old") - -/obj/item/weapon/storage/part_replacer/proc/play_rped_sound() - //Plays the sound for RPED exhanging or installing parts. -/* if(alt_sound && prob(1)) - playsound(src, alt_sound, 40, 1) - else -*/ - playsound(src, pshoom_or_beepboopblorpzingshadashwoosh, 40, 1) - -/obj/item/weapon/storage/part_replacer/adv - name = "advanced rapid part exchange device" - desc = "A special mechanical module made to store, sort, and apply standard machine parts. This one has a greatly upgraded storage capacity, \ - and the ability to hold beakers." - can_hold = list(/obj/item/weapon/stock_parts, /obj/item/weapon/reagent_containers/glass/beaker, /obj/item/weapon/cell,) // YW EDIT Cell - storage_slots = 200 - max_storage_space = 400 - -/obj/item/weapon/storage/part_replacer/adv/discount_bluespace - name = "prototype bluespace rapid part exchange device" - icon_state = "DBRPED" - item_state = "DBRPED" - desc = "A special mechanical module made to store, sort, and apply standard machine parts. This one has a further increased storage capacity, \ - and the ability to work on machines with closed maintenance panels." - storage_slots = 400 - max_storage_space = 800 - panel_req = FALSE - pshoom_or_beepboopblorpzingshadashwoosh = 'sound/items/pshoom.ogg' - unique_reskin = list("Soulless" = "DBRPED", - "Soulful" = "DBRPED_old") - -/obj/item/weapon/storage/part_replacer/examine(mob/user) - . = ..() - if(!reskin_ran) - . += "[src]'s external casing can be modified via alt-click." - -/obj/item/weapon/storage/part_replacer/AltClick(mob/user) - . = ..() - if(!reskin_ran) - reskin_radial(user) - -/obj/item/weapon/storage/part_replacer/proc/reskin_radial(mob/M) - if(!LAZYLEN(unique_reskin)) - return - - var/list/items = list() - for(var/reskin_option in unique_reskin) - var/image/item_image = image(icon = src.icon, icon_state = unique_reskin[reskin_option]) - items += list("[reskin_option]" = item_image) - sortList(items) - - var/pick = show_radial_menu(M, src, items, radius = 38, require_near = TRUE) - if(!pick) - return - if(!unique_reskin[pick]) - return - icon_state = unique_reskin[pick] - item_state = unique_reskin[pick] - reskin_ran = TRUE - to_chat(M, "[src] is now '[pick]'.") - -/obj/item/weapon/storage/part_replacer/drop_contents() // hacky-feeling tier-based drop system - hide_from(usr) - var/turf/T = get_turf(src) - var/lowest_rating = INFINITY // We want the lowest-part tier rating in the RPED so we only drop the lowest-tier parts. - /* - * Why not just use the stock part's rating variable? - * Future-proofing for a potential future where stock parts aren't the only thing that can fit in an RPED. - * see: /tg/ and /vg/'s RPEDs fitting power cells, beakers, etc. - * 10/8/21 edit - It's Time. - */ - for(var/obj/item/B in contents) - if(B.rped_rating() < lowest_rating) - lowest_rating = B.rped_rating() - for(var/obj/item/B in contents) - if(B.rped_rating() > lowest_rating) - continue - remove_from_storage(B, T) - -/obj/item/weapon/stock_parts - name = "stock part" - desc = "What?" - gender = PLURAL - icon = 'icons/obj/stock_parts.dmi' - w_class = ITEMSIZE_SMALL - var/rating = 1 - drop_sound = 'sound/items/drop/component.ogg' - pickup_sound = 'sound/items/pickup/component.ogg' - -/obj/item/weapon/stock_parts/New() - src.pixel_x = rand(-5.0, 5) - src.pixel_y = rand(-5.0, 5) - ..() - -/obj/item/weapon/stock_parts/get_rating() - return rating - -//Rank 1 - -/obj/item/weapon/stock_parts/console_screen - name = "console screen" - desc = "Used in the construction of computers and other devices with a interactive console." - icon_state = "screen" - origin_tech = list(TECH_MATERIAL = 1) - rating = 5 // these are actually Really Important for some things?? - matter = list(MAT_GLASS = 200) - -/obj/item/weapon/stock_parts/capacitor - name = "capacitor" - desc = "A basic capacitor used in the construction of a variety of devices." - icon_state = "capacitor" - origin_tech = list(TECH_POWER = 1) - matter = list(MAT_STEEL = 50,MAT_GLASS = 50) - - var/charge = 0 - var/max_charge = 1000 - -/obj/item/weapon/stock_parts/capacitor/New() - . = ..() - max_charge *= rating - -/obj/item/weapon/stock_parts/capacitor/proc/charge(var/amount) - charge += amount - if(charge > max_charge) - charge = max_charge - -/obj/item/weapon/stock_parts/capacitor/proc/use(var/amount) - if(charge) - charge -= amount - if(charge < 0) - charge = 0 - -/obj/item/weapon/stock_parts/scanning_module - name = "scanning module" - desc = "A compact, high resolution scanning module used in the construction of certain devices." - icon_state = "scan_module" - origin_tech = list(TECH_MAGNET = 1) - matter = list(MAT_STEEL = 50,MAT_GLASS = 20) - -/obj/item/weapon/stock_parts/manipulator - name = "micro-manipulator" - desc = "A tiny little manipulator used in the construction of certain devices." - icon_state = "micro_mani" - origin_tech = list(TECH_MATERIAL = 1, TECH_DATA = 1) - matter = list(MAT_STEEL = 30) - -/obj/item/weapon/stock_parts/micro_laser - name = "micro-laser" - desc = "A tiny laser used in certain devices." - icon_state = "micro_laser" - origin_tech = list(TECH_MAGNET = 1) - matter = list(MAT_STEEL = 10,MAT_GLASS = 20) - -/obj/item/weapon/stock_parts/matter_bin - name = "matter bin" - desc = "A container for hold compressed matter awaiting re-construction." - icon_state = "matter_bin" - origin_tech = list(TECH_MATERIAL = 1) - matter = list(MAT_STEEL = 80) - -//Rank 2 - -/obj/item/weapon/stock_parts/capacitor/adv - name = "advanced capacitor" - desc = "An advanced capacitor used in the construction of a variety of devices." - icon_state = "capacitor_adv" - origin_tech = list(TECH_POWER = 3) - rating = 2 - matter = list(MAT_STEEL = 50,MAT_GLASS = 50) - -/obj/item/weapon/stock_parts/scanning_module/adv - name = "advanced scanning module" - desc = "A compact, high resolution scanning module used in the construction of certain devices." - icon_state = "scan_module_adv" - origin_tech = list(TECH_MAGNET = 3) - rating = 2 - matter = list(MAT_STEEL = 50,MAT_GLASS = 20) - -/obj/item/weapon/stock_parts/manipulator/nano - name = "nano-manipulator" - desc = "A tiny little manipulator used in the construction of certain devices." - icon_state = "nano_mani" - origin_tech = list(TECH_MATERIAL = 3, TECH_DATA = 2) - rating = 2 - matter = list(MAT_STEEL = 30) - -/obj/item/weapon/stock_parts/micro_laser/high - name = "high-power micro-laser" - desc = "A tiny laser used in certain devices." - icon_state = "high_micro_laser" - origin_tech = list(TECH_MAGNET = 3) - rating = 2 - matter = list(MAT_STEEL = 10,MAT_GLASS = 20) - -/obj/item/weapon/stock_parts/matter_bin/adv - name = "advanced matter bin" - desc = "A container for hold compressed matter awaiting re-construction." - icon_state = "advanced_matter_bin" - origin_tech = list(TECH_MATERIAL = 3) - rating = 2 - matter = list(MAT_STEEL = 80) - -//Rating 3 - -/obj/item/weapon/stock_parts/capacitor/super - name = "super capacitor" - desc = "A super-high capacity capacitor used in the construction of a variety of devices." - icon_state = "capacitor_super" - origin_tech = list(TECH_POWER = 5, TECH_MATERIAL = 4) - rating = 3 - matter = list(MAT_STEEL = 50,MAT_GLASS = 50) - -/obj/item/weapon/stock_parts/scanning_module/phasic - name = "phasic scanning module" - desc = "A compact, high resolution phasic scanning module used in the construction of certain devices." - icon_state = "scan_module_phasic" - origin_tech = list(TECH_MAGNET = 5) - rating = 3 - matter = list(MAT_STEEL = 50,MAT_GLASS = 20) - -/obj/item/weapon/stock_parts/manipulator/pico - name = "pico-manipulator" - desc = "A tiny little manipulator used in the construction of certain devices." - icon_state = "pico_mani" - origin_tech = list(TECH_MATERIAL = 5, TECH_DATA = 2) - rating = 3 - matter = list(MAT_STEEL = 30) - -/obj/item/weapon/stock_parts/micro_laser/ultra - name = "ultra-high-power micro-laser" - icon_state = "ultra_high_micro_laser" - desc = "A tiny laser used in certain devices." - origin_tech = list(TECH_MAGNET = 5) - rating = 3 - matter = list(MAT_STEEL = 10,MAT_GLASS = 20) - -/obj/item/weapon/stock_parts/matter_bin/super - name = "super matter bin" - desc = "A container for hold compressed matter awaiting re-construction." - icon_state = "super_matter_bin" - origin_tech = list(TECH_MATERIAL = 5) - rating = 3 - matter = list(MAT_STEEL = 80) - -// Rating 4 - Anomaly - -/obj/item/weapon/stock_parts/capacitor/hyper - name = "hyper capacitor" - desc = "A hyper-capacity capacitor used in the construction of a variety of devices." - icon_state = "capacitor_hyper" - origin_tech = list(TECH_POWER = 6, TECH_MATERIAL = 5, TECH_BLUESPACE = 1, TECH_ARCANE = 1) - rating = 4 - matter = list(MAT_STEEL = 80, MAT_GLASS = 40) - -/obj/item/weapon/stock_parts/scanning_module/hyper - name = "quantum scanning module" - desc = "A compact, near-perfect resolution quantum scanning module used in the construction of certain devices." - icon_state = "scan_module_hyper" - origin_tech = list(TECH_MAGNET = 6, TECH_BLUESPACE = 1, TECH_ARCANE = 1) - rating = 4 - matter = list(MAT_STEEL = 100,MAT_GLASS = 40) - -/obj/item/weapon/stock_parts/manipulator/hyper - name = "planck-manipulator" - desc = "A miniscule manipulator used in the construction of certain devices." - icon_state = "hyper_mani" - origin_tech = list(TECH_MATERIAL = 6, TECH_DATA = 3, TECH_ARCANE = 1) - rating = 4 - matter = list(MAT_STEEL = 30) - -/obj/item/weapon/stock_parts/micro_laser/hyper - name = "hyper-power micro-laser" - icon_state = "hyper_micro_laser" - desc = "A tiny laser used in certain devices." - origin_tech = list(TECH_MAGNET = 6, TECH_ARCANE = 1) - rating = 4 - matter = list(MAT_STEEL = 30, MAT_GLASS = 40) - -/obj/item/weapon/stock_parts/matter_bin/hyper - name = "hyper matter bin" - desc = "A container for holding compressed matter awaiting re-construction." - icon_state = "hyper_matter_bin" - origin_tech = list(TECH_MATERIAL = 6, TECH_ARCANE = 1) - rating = 4 - matter = list(MAT_STEEL = 100) - -// Rating 5 - Precursor - -/obj/item/weapon/stock_parts/capacitor/omni - name = "omni-capacitor" - desc = "A capacitor of immense capacity used in the construction of a variety of devices." - icon_state = "capacitor_omni" - origin_tech = list(TECH_POWER = 7, TECH_MATERIAL = 6, TECH_BLUESPACE = 3, TECH_PRECURSOR = 1) - rating = 5 - matter = list(MAT_STEEL = 80, MAT_GLASS = 40) - -/obj/item/weapon/stock_parts/scanning_module/omni - name = "omni-scanning module" - desc = "A compact, perfect resolution temporospatial scanning module used in the construction of certain devices." - icon_state = "scan_module_omni" - origin_tech = list(TECH_MAGNET = 7, TECH_BLUESPACE = 3, TECH_PRECURSOR = 1) - rating = 5 - matter = list(MAT_STEEL = 100,MAT_GLASS = 40) - -/obj/item/weapon/stock_parts/manipulator/omni - name = "omni-manipulator" - desc = "A strange, infinitesimal manipulator used in the construction of certain devices." - icon_state = "omni_mani" - origin_tech = list(TECH_MATERIAL = 7, TECH_DATA = 4, TECH_PRECURSOR = 1) - rating = 5 - matter = list(MAT_STEEL = 30) - -/obj/item/weapon/stock_parts/micro_laser/omni - name = "omni-power micro-laser" - icon_state = "omni_micro_laser" - desc = "A strange laser used in certain devices." - origin_tech = list(TECH_MAGNET = 7, TECH_PRECURSOR = 1) - rating = 5 - matter = list(MAT_STEEL = 30, MAT_GLASS = 40) - -/obj/item/weapon/stock_parts/matter_bin/omni - name = "omni-matter bin" - desc = "A strange container for holding compressed matter awaiting re-construction." - icon_state = "omni_matter_bin" - origin_tech = list(TECH_MATERIAL = 7, TECH_PRECURSOR = 1) - rating = 5 - matter = list(MAT_STEEL = 100) - - -// Subspace stock parts - -/obj/item/weapon/stock_parts/subspace/ansible - name = "subspace ansible" - icon_state = "subspace_ansible" - desc = "A compact module capable of sensing extradimensional activity." - origin_tech = list(TECH_DATA = 3, TECH_MAGNET = 5 ,TECH_MATERIAL = 4, TECH_BLUESPACE = 2) - matter = list(MAT_STEEL = 30,MAT_GLASS = 10) - -/obj/item/weapon/stock_parts/subspace/sub_filter - name = "hyperwave filter" - icon_state = "hyperwave_filter" - desc = "A tiny device capable of filtering and converting super-intense radiowaves." - origin_tech = list(TECH_DATA = 4, TECH_MAGNET = 2) - matter = list(MAT_STEEL = 30,MAT_GLASS = 10) - -/obj/item/weapon/stock_parts/subspace/amplifier - name = "subspace amplifier" - icon_state = "subspace_amplifier" - desc = "A compact micro-machine capable of amplifying weak subspace transmissions." - origin_tech = list(TECH_DATA = 3, TECH_MAGNET = 4, TECH_MATERIAL = 4, TECH_BLUESPACE = 2) - matter = list(MAT_STEEL = 30,MAT_GLASS = 10) - -/obj/item/weapon/stock_parts/subspace/treatment - name = "subspace treatment disk" - icon_state = "treatment_disk" - desc = "A compact micro-machine capable of stretching out hyper-compressed radio waves." - origin_tech = list(TECH_DATA = 3, TECH_MAGNET = 2, TECH_MATERIAL = 5, TECH_BLUESPACE = 2) - matter = list(MAT_STEEL = 30,MAT_GLASS = 10) - -/obj/item/weapon/stock_parts/subspace/analyzer - name = "subspace wavelength analyzer" - icon_state = "wavelength_analyzer" - desc = "A sophisticated analyzer capable of analyzing cryptic subspace wavelengths." - origin_tech = list(TECH_DATA = 3, TECH_MAGNET = 4, TECH_MATERIAL = 4, TECH_BLUESPACE = 2) - matter = list(MAT_STEEL = 30,MAT_GLASS = 10) - -/obj/item/weapon/stock_parts/subspace/crystal - name = "ansible crystal" - icon_state = "ansible_crystal" - desc = "A crystal made from pure glass used to transmit laser databursts to subspace." - origin_tech = list(TECH_MAGNET = 4, TECH_MATERIAL = 4, TECH_BLUESPACE = 2) - matter = list(MAT_GLASS = 50) - -/obj/item/weapon/stock_parts/subspace/transmitter - name = "subspace transmitter" - icon_state = "subspace_transmitter" - desc = "A large piece of equipment used to open a window into the subspace dimension." - origin_tech = list(TECH_MAGNET = 5, TECH_MATERIAL = 5, TECH_BLUESPACE = 3) - matter = list(MAT_STEEL = 50) - -/obj/item/weapon/ectoplasm - name = "ectoplasm" - desc = "Spooky!" - gender = PLURAL - icon = 'icons/obj/wizard.dmi' - icon_state = "ectoplasm2" - -/obj/item/weapon/research - name = "research debugging device" - desc = "Instant research tool. For testing purposes only." - icon = 'icons/obj/stock_parts.dmi' - icon_state = "smes_coil" - origin_tech = list(TECH_MATERIAL = 19, TECH_ENGINEERING = 19, TECH_PHORON = 19, TECH_POWER = 19, TECH_BLUESPACE = 19, TECH_BIO = 19, TECH_COMBAT = 19, TECH_MAGNET = 19, TECH_DATA = 19, TECH_ILLEGAL = 19, TECH_ARCANE = 19, TECH_PRECURSOR = 19) - -// Additional construction stock parts - -/obj/item/weapon/stock_parts/gear - name = "gear" - desc = "A gear used for construction." - icon = 'icons/obj/stock_parts.dmi' - icon_state = "gear" - origin_tech = list(TECH_ENGINEERING = 1) - matter = list(MAT_STEEL = 50) - -/obj/item/weapon/stock_parts/motor - name = "motor" - desc = "A motor used for construction." - icon = 'icons/obj/stock_parts.dmi' - icon_state = "motor" - origin_tech = list(TECH_ENGINEERING = 1) - matter = list(MAT_STEEL = 60, MAT_GLASS = 10) - -/obj/item/weapon/stock_parts/spring - name = "spring" - desc = "A spring used for construction." - icon = 'icons/obj/stock_parts.dmi' - icon_state = "spring" - origin_tech = list(TECH_ENGINEERING = 1) - matter = list(MAT_STEEL = 40) - -/obj/effect/spawner/parts - name = "nondescript parts bundle that shouldn't exist" - desc = "this qdels itself lol! if you're reading this you're codediving or Someone fucked up" - var/list/items - -/obj/effect/spawner/parts/Initialize(mapload) - ..() - if(items && items.len) - var/turf/T = get_turf(src) - for(var/path in items) - for(var/i in 1 to 5) - new path(T) - return INITIALIZE_HINT_QDEL - -/obj/effect/spawner/parts/t1 - name = "basic parts bundle" - desc = "5 of each T1 part, no more and no less." - items = list( - /obj/item/weapon/stock_parts/matter_bin, - /obj/item/weapon/stock_parts/manipulator, - /obj/item/weapon/stock_parts/capacitor, - /obj/item/weapon/stock_parts/scanning_module, - /obj/item/weapon/stock_parts/micro_laser - ) - -/obj/effect/spawner/parts/t2 - name = "advanced parts bundle" - desc = "5 of each T2 part, no more and no less." - items = list( - /obj/item/weapon/stock_parts/matter_bin/adv, - /obj/item/weapon/stock_parts/manipulator/nano, - /obj/item/weapon/stock_parts/capacitor/adv, - /obj/item/weapon/stock_parts/scanning_module/adv, - /obj/item/weapon/stock_parts/micro_laser/high - ) - -/obj/effect/spawner/parts/t3 - name = "super parts bundle" - desc = "5 of each T3 part, no more and no less." - items = list( - /obj/item/weapon/stock_parts/matter_bin/super, - /obj/item/weapon/stock_parts/manipulator/pico, - /obj/item/weapon/stock_parts/capacitor/super, - /obj/item/weapon/stock_parts/scanning_module/phasic, - /obj/item/weapon/stock_parts/micro_laser/ultra - ) - -/obj/effect/spawner/parts/t4 - name = "hyper parts bundle" - desc = "5 of each T4 part, no more and no less." - items = list( - /obj/item/weapon/stock_parts/matter_bin/hyper, - /obj/item/weapon/stock_parts/manipulator/hyper, - /obj/item/weapon/stock_parts/capacitor/hyper, - /obj/item/weapon/stock_parts/scanning_module/hyper, - /obj/item/weapon/stock_parts/micro_laser/hyper - ) - -/obj/effect/spawner/parts/t5 - name = "omni parts bundle" - desc = "5 of each T5 part, no more and no less." - items = list( - /obj/item/weapon/stock_parts/matter_bin/omni, - /obj/item/weapon/stock_parts/manipulator/omni, - /obj/item/weapon/stock_parts/capacitor/omni, - /obj/item/weapon/stock_parts/scanning_module/omni, - /obj/item/weapon/stock_parts/micro_laser/omni - ) +/obj/item/weapon/phone + name = "red phone" + desc = "Should anything ever go wrong..." + icon = 'icons/obj/items.dmi' + icon_state = "red_phone" + force = 3.0 + throwforce = 2.0 + throw_speed = 1 + throw_range = 4 + w_class = ITEMSIZE_SMALL + attack_verb = list("called", "rang") + hitsound = 'sound/weapons/ring.ogg' + drop_sound = 'sound/items/drop/device.ogg' + pickup_sound = 'sound/items/pickup/device.ogg' + +/obj/item/weapon/rsp + name = "\improper Rapid-Seed-Producer (RSP)" + desc = "A device used to rapidly deploy seeds." + icon = 'icons/obj/items.dmi' + icon_state = "rcd" + opacity = 0 + density = FALSE + anchored = FALSE + var/stored_matter = 0 + var/mode = 1 + w_class = ITEMSIZE_NORMAL + drop_sound = 'sound/items/drop/device.ogg' + pickup_sound = 'sound/items/pickup/device.ogg' + +/obj/item/weapon/soap + name = "soap" + desc = "A cheap bar of soap. Smells of lye." + gender = PLURAL + icon = 'icons/obj/soap.dmi' + icon_state = "soap" + flags = NOCONDUCT + w_class = ITEMSIZE_SMALL + slot_flags = SLOT_HOLSTER + throwforce = 0 + throw_speed = 4 + throw_range = 20 + +/obj/item/weapon/soap/nanotrasen + desc = "A NanoTrasen-brand bar of soap. Smells of phoron, a years-old marketing gimmick." + icon_state = "soapnt" + +/obj/item/weapon/soap/deluxe + icon_state = "soapdeluxe" + +/obj/item/weapon/soap/deluxe/New() + desc = "A deluxe Waffle Co. brand bar of soap. Smells of [pick("lavender", "vanilla", "strawberry", "chocolate" ,"space")]." + ..() + +/obj/item/weapon/soap/syndie + desc = "An untrustworthy bar of soap. Smells of fear." + icon_state = "soapsyndie" + +/obj/item/weapon/soap/syndie + desc = "An dubious bar of soap. Smells of lyes." + icon_state = "soapsyndie" + +/obj/item/weapon/soap/space_soap + desc = "Smells like hot metal and walnuts." + icon_state = "space_soap" + +/obj/item/weapon/soap/water_soap + desc = "Smells like chlorine." + icon_state = "water_soap" + +/obj/item/weapon/soap/fire_soap + desc = "Smells like a campfire." + icon_state = "fire_soap" + +/obj/item/weapon/soap/rainbow_soap + desc = "Smells sickly sweet." + icon_state = "rainbow_soap" + +/obj/item/weapon/soap/diamond_soap + desc = "Smells like saffron and vanilla." + icon_state = "diamond_soap" + +/obj/item/weapon/soap/uranium_soap + desc = "Smells not great... Not terrible." + icon_state = "uranium_soap" + +/obj/item/weapon/soap/silver_soap + desc = "Smells like birch and amaranth." + icon_state = "silver_soap" + +/obj/item/weapon/soap/brown_soap + desc = "Smells like cinnamon and cognac." + icon_state = "brown_soap" + +/obj/item/weapon/soap/white_soap + desc = "Smells like nutmeg and oats." + icon_state = "white_soap" + +/obj/item/weapon/soap/grey_soap + desc = "Smells like bergamot and lilies." + icon_state = "grey_soap" + +/obj/item/weapon/soap/pink_soap + desc = "Smells like bubblegum." + icon_state = "pink_soap" + +/obj/item/weapon/soap/purple_soap + desc = "Smells like lavender." + icon_state = "purple_soap" + +/obj/item/weapon/soap/blue_soap + desc = "Smells like cardamom." + icon_state = "blue_soap" + +/obj/item/weapon/soap/cyan_soap + desc = "Smells like bluebells and peaches." + icon_state = "cyan_soap" + +/obj/item/weapon/soap/green_soap + desc = "Smells like a freshly mowed lawn." + icon_state = "green_soap" + +/obj/item/weapon/soap/yellow_soap + desc = "Smells like citron and ginger." + icon_state = "yellow_soap" + +/obj/item/weapon/soap/orange_soap + desc = "Smells like oranges and dark chocolate." + icon_state = "orange_soap" + +/obj/item/weapon/soap/red_soap + desc = "Smells like cherries." + icon_state = "red_soap" + +/obj/item/weapon/soap/golden_soap + desc = "Smells like honey." + icon_state = "golden_soap" + + +/obj/item/weapon/bikehorn + name = "bike horn" + desc = "A horn off of a bicycle." + icon = 'icons/obj/items.dmi' + icon_state = "bike_horn" + item_state = "bike_horn" + throwforce = 3 + w_class = ITEMSIZE_SMALL + slot_flags = SLOT_HOLSTER + throw_speed = 3 + throw_range = 15 + attack_verb = list("HONKED") + var/spam_flag = 0 + +/obj/item/weapon/c_tube + name = "cardboard tube" + desc = "A tube... of cardboard." + icon = 'icons/obj/items.dmi' + icon_state = "c_tube" + throwforce = 1 + w_class = ITEMSIZE_SMALL + throw_speed = 4 + throw_range = 5 + +/obj/item/weapon/disk + name = "disk" + icon = 'icons/obj/discs_vr.dmi' //VOREStation Edit + drop_sound = 'sound/items/drop/disk.ogg' + pickup_sound = 'sound/items/pickup/disk.ogg' + +/obj/item/weapon/disk/nuclear + name = "nuclear authentication disk" + desc = "Better keep this safe." + icon_state = "nucleardisk" + item_state = "card-id" + w_class = ITEMSIZE_SMALL + +/* +/obj/item/weapon/game_kit + name = "Gaming Kit" + icon = 'icons/obj/items.dmi' + icon_state = "game_kit" + var/selected = null + var/board_stat = null + var/data = "" + var/base_url = "http://svn.slurm.us/public/spacestation13/misc/game_kit" + item_state = "sheet-metal" + w_class = ITEMSIZE_HUGE +*/ + +/obj/item/weapon/gift + name = "gift" + desc = "A wrapped item." + icon = 'icons/obj/items.dmi' + icon_state = "gift3" + var/size = 3.0 + var/obj/item/gift = null + item_state = "gift" + w_class = ITEMSIZE_LARGE + +/*/obj/item/weapon/syndicate_uplink + name = "station bounced radio" + desc = "Remain silent about this..." + icon = 'icons/obj/radio.dmi' + icon_state = "radio" + var/temp = null + var/uses = 10.0 + var/selfdestruct = 0.0 + var/traitor_frequency = 0.0 + var/mob/currentUser = null + var/obj/item/device/radio/origradio = null + flags = ONBELT + w_class = ITEMSIZE_SMALL + item_state = "radio" + throw_speed = 4 + throw_range = 20 + matter = list(MAT_STEEL = 100) + origin_tech = list(TECH_MAGNET = 2, TECH_ILLEGAL = 3)*/ + +/obj/item/weapon/SWF_uplink + name = "station-bounced radio" + desc = "Used to communicate, it appears." + icon = 'icons/obj/radio.dmi' + icon_state = "radio" + var/temp = null + var/uses = 4.0 + var/selfdestruct = 0.0 + var/traitor_frequency = 0.0 + var/obj/item/device/radio/origradio = null + slot_flags = SLOT_BELT + item_state = "radio" + throwforce = 5 + w_class = ITEMSIZE_SMALL + throw_speed = 4 + throw_range = 20 + matter = list(MAT_STEEL = 100) + origin_tech = list(TECH_MAGNET = 1) + drop_sound = 'sound/items/drop/device.ogg' + pickup_sound = 'sound/items/pickup/device.ogg' + +/obj/item/weapon/staff + name = "wizards staff" + desc = "Apparently a staff used by the wizard." + icon = 'icons/obj/wizard.dmi' + icon_state = "staff" + item_icons = list( + slot_l_hand_str = 'icons/mob/items/lefthand_melee.dmi', + slot_r_hand_str = 'icons/mob/items/righthand_melee.dmi', + ) + force = 3.0 + throwforce = 5.0 + throw_speed = 1 + throw_range = 5 + w_class = ITEMSIZE_SMALL + attack_verb = list("bludgeoned", "whacked", "disciplined") + +/obj/item/weapon/staff/broom + name = "broom" + desc = "Used for sweeping, and flying into the night while cackling. Black cat not included." + icon = 'icons/obj/wizard.dmi' + icon_state = "broom" + +/obj/item/weapon/staff/gentcane + name = "Gentlemans Cane" + desc = "An ebony can with an ivory tip." + icon = 'icons/obj/weapons.dmi' + icon_state = "cane" + +/obj/item/weapon/staff/stick + name = "stick" + desc = "A great tool to drag someone else's drinks across the bar." + icon = 'icons/obj/weapons.dmi' + icon_state = "stick" + item_state = "cane" + force = 3.0 + throwforce = 5.0 + throw_speed = 1 + throw_range = 5 + w_class = ITEMSIZE_SMALL + +/obj/item/weapon/module + icon = 'icons/obj/module.dmi' + icon_state = "std_module" + item_state = "std_mod" + w_class = ITEMSIZE_SMALL + var/mtype = 1 // 1=electronic 2=hardware + drop_sound = 'sound/items/drop/component.ogg' + pickup_sound = 'sound/items/pickup/component.ogg' + +/obj/item/weapon/module/card_reader + name = "card reader module" + icon_state = "card_mod" + item_state = "std_mod" + desc = "An electronic module for reading data and ID cards." + +/obj/item/weapon/module/power_control + name = "power control module" + icon_state = "power_mod" + item_state = "std_mod" + desc = "Heavy-duty switching circuits for power control." + matter = list(MAT_STEEL = 50, MAT_GLASS = 50) + +/obj/item/weapon/module/id_auth + name = "\improper ID authentication module" + icon_state = "id_mod" + desc = "A module allowing secure authorization of ID cards." + +/obj/item/weapon/module/cell_power + name = "power cell regulator module" + icon_state = "power_mod" + item_state = "std_mod" + desc = "A converter and regulator allowing the use of power cells." + +/obj/item/weapon/module/cell_power + name = "power cell charger module" + icon_state = "power_mod" + item_state = "std_mod" + desc = "Charging circuits for power cells." + +/obj/item/device/camera_bug + name = "camera bug" + icon = 'icons/obj/device.dmi' + icon_state = "flash" + w_class = ITEMSIZE_TINY + item_state = "electronic" + throw_speed = 4 + throw_range = 20 + +/obj/item/weapon/camera_bug/attack_self(mob/usr as mob) + var/list/cameras = new/list() + for (var/obj/machinery/camera/C in cameranet.cameras) + if (C.bugged && C.status) + cameras.Add(C) + if (length(cameras) == 0) + to_chat(usr, "No bugged functioning cameras found.") + return + + var/list/friendly_cameras = new/list() + + for (var/obj/machinery/camera/C in cameras) + friendly_cameras.Add(C.c_tag) + + var/target = tgui_input_list(usr, "Select the camera to observe", "Select Camera", friendly_cameras) + if (!target) + return + for (var/obj/machinery/camera/C in cameras) + if (C.c_tag == target) + target = C + break + if (usr.stat == 2) return + + usr.client.eye = target + +/* +/obj/item/weapon/cigarpacket + name = "Pete's Cuban Cigars" + desc = "The most robust cigars on the planet." + icon = 'icons/obj/cigarettes.dmi' + icon_state = "cigarpacket" + item_state = "cigarpacket" + w_class = ITEMSIZE_TINY + throwforce = 2 + var/cigarcount = 6 + flags = ONBELT + */ + +/obj/item/weapon/pai_cable + desc = "A flexible coated cable with a universal jack on one end." + name = "data cable" + icon = 'icons/obj/power.dmi' + icon_state = "wire1" + + var/obj/machinery/machine + +/obj/item/weapon/pai_cable/Destroy() + machine = null + return ..() + +///////////////////////////////////////Stock Parts ///////////////////////////////// + +/obj/item/weapon/storage/part_replacer + name = "rapid part exchange device" + desc = "A special mechanical module made to store, sort, and apply standard machine parts." + icon = 'icons/obj/storage_vr.dmi' + icon_state = "RPED" + item_state = "RPED" + w_class = ITEMSIZE_HUGE + can_hold = list(/obj/item/weapon/stock_parts) + storage_slots = 50 + use_to_pickup = TRUE + allow_quick_gather = 1 + allow_quick_empty = 1 + collection_mode = 1 + display_contents_with_number = 1 + max_w_class = ITEMSIZE_NORMAL + max_storage_space = 100 + drop_sound = 'sound/items/drop/device.ogg' + pickup_sound = 'sound/items/pickup/device.ogg' + var/panel_req = TRUE + var/pshoom_or_beepboopblorpzingshadashwoosh = 'sound/items/rped.ogg' + var/reskin_ran = FALSE + var/unique_reskin = list("Soulless" = "RPED", + "Soulful" = "RPED_old") + +/obj/item/weapon/storage/part_replacer/proc/play_rped_sound() + //Plays the sound for RPED exhanging or installing parts. +/* if(alt_sound && prob(1)) + playsound(src, alt_sound, 40, 1) + else +*/ + playsound(src, pshoom_or_beepboopblorpzingshadashwoosh, 40, 1) + +/obj/item/weapon/storage/part_replacer/adv + name = "advanced rapid part exchange device" + desc = "A special mechanical module made to store, sort, and apply standard machine parts. This one has a greatly upgraded storage capacity, \ + and the ability to hold beakers." + can_hold = list(/obj/item/weapon/stock_parts, /obj/item/weapon/reagent_containers/glass/beaker, /obj/item/weapon/cell,) // YW EDIT Cell + storage_slots = 200 + max_storage_space = 400 + +/obj/item/weapon/storage/part_replacer/adv/discount_bluespace + name = "prototype bluespace rapid part exchange device" + icon_state = "DBRPED" + item_state = "DBRPED" + desc = "A special mechanical module made to store, sort, and apply standard machine parts. This one has a further increased storage capacity, \ + and the ability to work on machines with closed maintenance panels." + storage_slots = 400 + max_storage_space = 800 + panel_req = FALSE + pshoom_or_beepboopblorpzingshadashwoosh = 'sound/items/pshoom.ogg' + unique_reskin = list("Soulless" = "DBRPED", + "Soulful" = "DBRPED_old") + +/obj/item/weapon/storage/part_replacer/examine(mob/user) + . = ..() + if(!reskin_ran) + . += "[src]'s external casing can be modified via alt-click." + +/obj/item/weapon/storage/part_replacer/AltClick(mob/user) + . = ..() + if(!reskin_ran) + reskin_radial(user) + +/obj/item/weapon/storage/part_replacer/proc/reskin_radial(mob/M) + if(!LAZYLEN(unique_reskin)) + return + + var/list/items = list() + for(var/reskin_option in unique_reskin) + var/image/item_image = image(icon = src.icon, icon_state = unique_reskin[reskin_option]) + items += list("[reskin_option]" = item_image) + sortList(items) + + var/pick = show_radial_menu(M, src, items, radius = 38, require_near = TRUE) + if(!pick) + return + if(!unique_reskin[pick]) + return + icon_state = unique_reskin[pick] + item_state = unique_reskin[pick] + reskin_ran = TRUE + to_chat(M, "[src] is now '[pick]'.") + +/obj/item/weapon/storage/part_replacer/drop_contents() // hacky-feeling tier-based drop system + hide_from(usr) + var/turf/T = get_turf(src) + var/lowest_rating = INFINITY // We want the lowest-part tier rating in the RPED so we only drop the lowest-tier parts. + /* + * Why not just use the stock part's rating variable? + * Future-proofing for a potential future where stock parts aren't the only thing that can fit in an RPED. + * see: /tg/ and /vg/'s RPEDs fitting power cells, beakers, etc. + * 10/8/21 edit - It's Time. + */ + for(var/obj/item/B in contents) + if(B.rped_rating() < lowest_rating) + lowest_rating = B.rped_rating() + for(var/obj/item/B in contents) + if(B.rped_rating() > lowest_rating) + continue + remove_from_storage(B, T) + + +/obj/item/weapon/stock_parts + name = "stock part" + desc = "What?" + gender = PLURAL + icon = 'icons/obj/stock_parts.dmi' + w_class = ITEMSIZE_SMALL + var/rating = 1 + drop_sound = 'sound/items/drop/component.ogg' + pickup_sound = 'sound/items/pickup/component.ogg' + +/obj/item/weapon/stock_parts/New() + src.pixel_x = rand(-5.0, 5) + src.pixel_y = rand(-5.0, 5) + ..() + +/obj/item/weapon/stock_parts/get_rating() + return rating + +//Rank 1 + +/obj/item/weapon/stock_parts/console_screen + name = "console screen" + desc = "Used in the construction of computers and other devices with a interactive console." + icon_state = "screen" + origin_tech = list(TECH_MATERIAL = 1) + rating = 5 // these are actually Really Important for some things?? + matter = list(MAT_GLASS = 200) + +/obj/item/weapon/stock_parts/capacitor + name = "capacitor" + desc = "A basic capacitor used in the construction of a variety of devices." + icon_state = "capacitor" + origin_tech = list(TECH_POWER = 1) + matter = list(MAT_STEEL = 50,MAT_GLASS = 50) + + var/charge = 0 + var/max_charge = 1000 + +/obj/item/weapon/stock_parts/capacitor/New() + . = ..() + max_charge *= rating + +/obj/item/weapon/stock_parts/capacitor/proc/charge(var/amount) + charge += amount + if(charge > max_charge) + charge = max_charge + +/obj/item/weapon/stock_parts/capacitor/proc/use(var/amount) + if(charge) + charge -= amount + if(charge < 0) + charge = 0 + +/obj/item/weapon/stock_parts/scanning_module + name = "scanning module" + desc = "A compact, high resolution scanning module used in the construction of certain devices." + icon_state = "scan_module" + origin_tech = list(TECH_MAGNET = 1) + matter = list(MAT_STEEL = 50,MAT_GLASS = 20) + +/obj/item/weapon/stock_parts/manipulator + name = "micro-manipulator" + desc = "A tiny little manipulator used in the construction of certain devices." + icon_state = "micro_mani" + origin_tech = list(TECH_MATERIAL = 1, TECH_DATA = 1) + matter = list(MAT_STEEL = 30) + +/obj/item/weapon/stock_parts/micro_laser + name = "micro-laser" + desc = "A tiny laser used in certain devices." + icon_state = "micro_laser" + origin_tech = list(TECH_MAGNET = 1) + matter = list(MAT_STEEL = 10,MAT_GLASS = 20) + +/obj/item/weapon/stock_parts/matter_bin + name = "matter bin" + desc = "A container for hold compressed matter awaiting re-construction." + icon_state = "matter_bin" + origin_tech = list(TECH_MATERIAL = 1) + matter = list(MAT_STEEL = 80) + +//Rank 2 + +/obj/item/weapon/stock_parts/capacitor/adv + name = "advanced capacitor" + desc = "An advanced capacitor used in the construction of a variety of devices." + icon_state = "capacitor_adv" + origin_tech = list(TECH_POWER = 3) + rating = 2 + matter = list(MAT_STEEL = 50,MAT_GLASS = 50) + +/obj/item/weapon/stock_parts/scanning_module/adv + name = "advanced scanning module" + desc = "A compact, high resolution scanning module used in the construction of certain devices." + icon_state = "scan_module_adv" + origin_tech = list(TECH_MAGNET = 3) + rating = 2 + matter = list(MAT_STEEL = 50,MAT_GLASS = 20) + +/obj/item/weapon/stock_parts/manipulator/nano + name = "nano-manipulator" + desc = "A tiny little manipulator used in the construction of certain devices." + icon_state = "nano_mani" + origin_tech = list(TECH_MATERIAL = 3, TECH_DATA = 2) + rating = 2 + matter = list(MAT_STEEL = 30) + +/obj/item/weapon/stock_parts/micro_laser/high + name = "high-power micro-laser" + desc = "A tiny laser used in certain devices." + icon_state = "high_micro_laser" + origin_tech = list(TECH_MAGNET = 3) + rating = 2 + matter = list(MAT_STEEL = 10,MAT_GLASS = 20) + +/obj/item/weapon/stock_parts/matter_bin/adv + name = "advanced matter bin" + desc = "A container for hold compressed matter awaiting re-construction." + icon_state = "advanced_matter_bin" + origin_tech = list(TECH_MATERIAL = 3) + rating = 2 + matter = list(MAT_STEEL = 80) + +//Rating 3 + +/obj/item/weapon/stock_parts/capacitor/super + name = "super capacitor" + desc = "A super-high capacity capacitor used in the construction of a variety of devices." + icon_state = "capacitor_super" + origin_tech = list(TECH_POWER = 5, TECH_MATERIAL = 4) + rating = 3 + matter = list(MAT_STEEL = 50,MAT_GLASS = 50) + +/obj/item/weapon/stock_parts/scanning_module/phasic + name = "phasic scanning module" + desc = "A compact, high resolution phasic scanning module used in the construction of certain devices." + icon_state = "scan_module_phasic" + origin_tech = list(TECH_MAGNET = 5) + rating = 3 + matter = list(MAT_STEEL = 50,MAT_GLASS = 20) + +/obj/item/weapon/stock_parts/manipulator/pico + name = "pico-manipulator" + desc = "A tiny little manipulator used in the construction of certain devices." + icon_state = "pico_mani" + origin_tech = list(TECH_MATERIAL = 5, TECH_DATA = 2) + rating = 3 + matter = list(MAT_STEEL = 30) + +/obj/item/weapon/stock_parts/micro_laser/ultra + name = "ultra-high-power micro-laser" + icon_state = "ultra_high_micro_laser" + desc = "A tiny laser used in certain devices." + origin_tech = list(TECH_MAGNET = 5) + rating = 3 + matter = list(MAT_STEEL = 10,MAT_GLASS = 20) + +/obj/item/weapon/stock_parts/matter_bin/super + name = "super matter bin" + desc = "A container for hold compressed matter awaiting re-construction." + icon_state = "super_matter_bin" + origin_tech = list(TECH_MATERIAL = 5) + rating = 3 + matter = list(MAT_STEEL = 80) + +// Rating 4 - Anomaly + +/obj/item/weapon/stock_parts/capacitor/hyper + name = "hyper capacitor" + desc = "A hyper-capacity capacitor used in the construction of a variety of devices." + icon_state = "capacitor_hyper" + origin_tech = list(TECH_POWER = 6, TECH_MATERIAL = 5, TECH_BLUESPACE = 1, TECH_ARCANE = 1) + rating = 4 + matter = list(MAT_STEEL = 80, MAT_GLASS = 40) + +/obj/item/weapon/stock_parts/scanning_module/hyper + name = "quantum scanning module" + desc = "A compact, near-perfect resolution quantum scanning module used in the construction of certain devices." + icon_state = "scan_module_hyper" + origin_tech = list(TECH_MAGNET = 6, TECH_BLUESPACE = 1, TECH_ARCANE = 1) + rating = 4 + matter = list(MAT_STEEL = 100,MAT_GLASS = 40) + +/obj/item/weapon/stock_parts/manipulator/hyper + name = "planck-manipulator" + desc = "A miniscule manipulator used in the construction of certain devices." + icon_state = "hyper_mani" + origin_tech = list(TECH_MATERIAL = 6, TECH_DATA = 3, TECH_ARCANE = 1) + rating = 4 + matter = list(MAT_STEEL = 30) + +/obj/item/weapon/stock_parts/micro_laser/hyper + name = "hyper-power micro-laser" + icon_state = "hyper_micro_laser" + desc = "A tiny laser used in certain devices." + origin_tech = list(TECH_MAGNET = 6, TECH_ARCANE = 1) + rating = 4 + matter = list(MAT_STEEL = 30, MAT_GLASS = 40) + +/obj/item/weapon/stock_parts/matter_bin/hyper + name = "hyper matter bin" + desc = "A container for holding compressed matter awaiting re-construction." + icon_state = "hyper_matter_bin" + origin_tech = list(TECH_MATERIAL = 6, TECH_ARCANE = 1) + rating = 4 + matter = list(MAT_STEEL = 100) + +// Rating 5 - Precursor + +/obj/item/weapon/stock_parts/capacitor/omni + name = "omni-capacitor" + desc = "A capacitor of immense capacity used in the construction of a variety of devices." + icon_state = "capacitor_omni" + origin_tech = list(TECH_POWER = 7, TECH_MATERIAL = 6, TECH_BLUESPACE = 3, TECH_PRECURSOR = 1) + rating = 5 + matter = list(MAT_STEEL = 80, MAT_GLASS = 40) + +/obj/item/weapon/stock_parts/scanning_module/omni + name = "omni-scanning module" + desc = "A compact, perfect resolution temporospatial scanning module used in the construction of certain devices." + icon_state = "scan_module_omni" + origin_tech = list(TECH_MAGNET = 7, TECH_BLUESPACE = 3, TECH_PRECURSOR = 1) + rating = 5 + matter = list(MAT_STEEL = 100,MAT_GLASS = 40) + +/obj/item/weapon/stock_parts/manipulator/omni + name = "omni-manipulator" + desc = "A strange, infinitesimal manipulator used in the construction of certain devices." + icon_state = "omni_mani" + origin_tech = list(TECH_MATERIAL = 7, TECH_DATA = 4, TECH_PRECURSOR = 1) + rating = 5 + matter = list(MAT_STEEL = 30) + +/obj/item/weapon/stock_parts/micro_laser/omni + name = "omni-power micro-laser" + icon_state = "omni_micro_laser" + desc = "A strange laser used in certain devices." + origin_tech = list(TECH_MAGNET = 7, TECH_PRECURSOR = 1) + rating = 5 + matter = list(MAT_STEEL = 30, MAT_GLASS = 40) + +/obj/item/weapon/stock_parts/matter_bin/omni + name = "omni-matter bin" + desc = "A strange container for holding compressed matter awaiting re-construction." + icon_state = "omni_matter_bin" + origin_tech = list(TECH_MATERIAL = 7, TECH_PRECURSOR = 1) + rating = 5 + matter = list(MAT_STEEL = 100) + + +// Subspace stock parts + +/obj/item/weapon/stock_parts/subspace/ansible + name = "subspace ansible" + icon_state = "subspace_ansible" + desc = "A compact module capable of sensing extradimensional activity." + origin_tech = list(TECH_DATA = 3, TECH_MAGNET = 5 ,TECH_MATERIAL = 4, TECH_BLUESPACE = 2) + matter = list(MAT_STEEL = 30,MAT_GLASS = 10) + +/obj/item/weapon/stock_parts/subspace/sub_filter + name = "hyperwave filter" + icon_state = "hyperwave_filter" + desc = "A tiny device capable of filtering and converting super-intense radiowaves." + origin_tech = list(TECH_DATA = 4, TECH_MAGNET = 2) + matter = list(MAT_STEEL = 30,MAT_GLASS = 10) + +/obj/item/weapon/stock_parts/subspace/amplifier + name = "subspace amplifier" + icon_state = "subspace_amplifier" + desc = "A compact micro-machine capable of amplifying weak subspace transmissions." + origin_tech = list(TECH_DATA = 3, TECH_MAGNET = 4, TECH_MATERIAL = 4, TECH_BLUESPACE = 2) + matter = list(MAT_STEEL = 30,MAT_GLASS = 10) + +/obj/item/weapon/stock_parts/subspace/treatment + name = "subspace treatment disk" + icon_state = "treatment_disk" + desc = "A compact micro-machine capable of stretching out hyper-compressed radio waves." + origin_tech = list(TECH_DATA = 3, TECH_MAGNET = 2, TECH_MATERIAL = 5, TECH_BLUESPACE = 2) + matter = list(MAT_STEEL = 30,MAT_GLASS = 10) + +/obj/item/weapon/stock_parts/subspace/analyzer + name = "subspace wavelength analyzer" + icon_state = "wavelength_analyzer" + desc = "A sophisticated analyzer capable of analyzing cryptic subspace wavelengths." + origin_tech = list(TECH_DATA = 3, TECH_MAGNET = 4, TECH_MATERIAL = 4, TECH_BLUESPACE = 2) + matter = list(MAT_STEEL = 30,MAT_GLASS = 10) + +/obj/item/weapon/stock_parts/subspace/crystal + name = "ansible crystal" + icon_state = "ansible_crystal" + desc = "A crystal made from pure glass used to transmit laser databursts to subspace." + origin_tech = list(TECH_MAGNET = 4, TECH_MATERIAL = 4, TECH_BLUESPACE = 2) + matter = list(MAT_GLASS = 50) + +/obj/item/weapon/stock_parts/subspace/transmitter + name = "subspace transmitter" + icon_state = "subspace_transmitter" + desc = "A large piece of equipment used to open a window into the subspace dimension." + origin_tech = list(TECH_MAGNET = 5, TECH_MATERIAL = 5, TECH_BLUESPACE = 3) + matter = list(MAT_STEEL = 50) + +/obj/item/weapon/ectoplasm + name = "ectoplasm" + desc = "Spooky!" + gender = PLURAL + icon = 'icons/obj/wizard.dmi' + icon_state = "ectoplasm2" + +/obj/item/weapon/research + name = "research debugging device" + desc = "Instant research tool. For testing purposes only." + icon = 'icons/obj/stock_parts.dmi' + icon_state = "smes_coil" + origin_tech = list(TECH_MATERIAL = 19, TECH_ENGINEERING = 19, TECH_PHORON = 19, TECH_POWER = 19, TECH_BLUESPACE = 19, TECH_BIO = 19, TECH_COMBAT = 19, TECH_MAGNET = 19, TECH_DATA = 19, TECH_ILLEGAL = 19, TECH_ARCANE = 19, TECH_PRECURSOR = 19) + +// Additional construction stock parts + +/obj/item/weapon/stock_parts/gear + name = "gear" + desc = "A gear used for construction." + icon = 'icons/obj/stock_parts.dmi' + icon_state = "gear" + origin_tech = list(TECH_ENGINEERING = 1) + matter = list(MAT_STEEL = 50) + +/obj/item/weapon/stock_parts/motor + name = "motor" + desc = "A motor used for construction." + icon = 'icons/obj/stock_parts.dmi' + icon_state = "motor" + origin_tech = list(TECH_ENGINEERING = 1) + matter = list(MAT_STEEL = 60, MAT_GLASS = 10) + +/obj/item/weapon/stock_parts/spring + name = "spring" + desc = "A spring used for construction." + icon = 'icons/obj/stock_parts.dmi' + icon_state = "spring" + origin_tech = list(TECH_ENGINEERING = 1) + matter = list(MAT_STEEL = 40) + +/obj/effect/spawner/parts + name = "nondescript parts bundle that shouldn't exist" + desc = "this qdels itself lol! if you're reading this you're codediving or Someone fucked up" + var/list/items + +/obj/effect/spawner/parts/Initialize(mapload) + ..() + if(items && items.len) + var/turf/T = get_turf(src) + for(var/path in items) + for(var/i in 1 to 5) + new path(T) + return INITIALIZE_HINT_QDEL + +/obj/effect/spawner/parts/t1 + name = "basic parts bundle" + desc = "5 of each T1 part, no more and no less." + items = list( + /obj/item/weapon/stock_parts/matter_bin, + /obj/item/weapon/stock_parts/manipulator, + /obj/item/weapon/stock_parts/capacitor, + /obj/item/weapon/stock_parts/scanning_module, + /obj/item/weapon/stock_parts/micro_laser + ) + +/obj/effect/spawner/parts/t2 + name = "advanced parts bundle" + desc = "5 of each T2 part, no more and no less." + items = list( + /obj/item/weapon/stock_parts/matter_bin/adv, + /obj/item/weapon/stock_parts/manipulator/nano, + /obj/item/weapon/stock_parts/capacitor/adv, + /obj/item/weapon/stock_parts/scanning_module/adv, + /obj/item/weapon/stock_parts/micro_laser/high + ) + +/obj/effect/spawner/parts/t3 + name = "super parts bundle" + desc = "5 of each T3 part, no more and no less." + items = list( + /obj/item/weapon/stock_parts/matter_bin/super, + /obj/item/weapon/stock_parts/manipulator/pico, + /obj/item/weapon/stock_parts/capacitor/super, + /obj/item/weapon/stock_parts/scanning_module/phasic, + /obj/item/weapon/stock_parts/micro_laser/ultra + ) + +/obj/effect/spawner/parts/t4 + name = "hyper parts bundle" + desc = "5 of each T4 part, no more and no less." + items = list( + /obj/item/weapon/stock_parts/matter_bin/hyper, + /obj/item/weapon/stock_parts/manipulator/hyper, + /obj/item/weapon/stock_parts/capacitor/hyper, + /obj/item/weapon/stock_parts/scanning_module/hyper, + /obj/item/weapon/stock_parts/micro_laser/hyper + ) + +/obj/effect/spawner/parts/t5 + name = "omni parts bundle" + desc = "5 of each T5 part, no more and no less." + items = list( + /obj/item/weapon/stock_parts/matter_bin/omni, + /obj/item/weapon/stock_parts/manipulator/omni, + /obj/item/weapon/stock_parts/capacitor/omni, + /obj/item/weapon/stock_parts/scanning_module/omni, + /obj/item/weapon/stock_parts/micro_laser/omni + ) diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index d0cdeb0187..5125b09278 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -465,7 +465,7 @@ var/list/mob/living/forced_ambiance_list = new /area/proc/prison_break(break_lights = TRUE, open_doors = TRUE, open_blast_doors = TRUE) var/obj/machinery/power/apc/theAPC = get_apc() - if(theAPC.operating) + if(theAPC && theAPC.operating) if(break_lights) for(var/obj/machinery/power/apc/temp_apc in src) temp_apc.overload_lighting(70) diff --git a/code/game/area/areas_vr.dm b/code/game/area/areas_vr.dm index e356063e2a..f932674566 100644 --- a/code/game/area/areas_vr.dm +++ b/code/game/area/areas_vr.dm @@ -5,6 +5,9 @@ var/block_suit_sensors = FALSE //If mob size is limited in the area. var/turf/ceiling_type + // Size of the area in open turfs, only calculated for indoors areas. + var/areasize = 0 + /area/Entered(var/atom/movable/AM, oldLoc) . = ..() if(enter_message && isliving(AM)) @@ -29,3 +32,41 @@ var/turf/TA = GetAbove(T) if(isopenspace(TA)) TA.ChangeTurf(ceiling_type, TRUE, TRUE, TRUE) + +/** + * Setup an area (with the given name) + * + * Sets the area name, sets all status var's to false and adds the area to the sorted area list + * //NOTE: Virgo does not have a sorted area list. + */ +/area/proc/setup(a_name) + name = a_name + power_equip = FALSE + power_light = FALSE + power_environ = FALSE + always_unpowered = FALSE + update_areasize() + +/area/proc/update_areasize() + if(outdoors) + return FALSE + areasize = 0 + for(var/turf/simulated/floor/T in contents) + areasize++ + +/proc/rename_area(a, new_name) + var/area/A = get_area(a) + var/prevname = "[A.name]" + set_area_machinery(A, new_name, prevname) + A.name = new_name + A.update_areasize() + return TRUE + +/area/proc/power_check() + if(!requires_power || !apc) + power_light = 0 + power_equip = 0 + power_environ = 0 + power_change() // all machines set to current power level, also updates lighting icon + if(no_spoilers) + set_spoiler_obfuscation(TRUE) \ No newline at end of file diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index ef50823c48..40b4ea9d4e 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -637,4 +637,4 @@ return selfimage /atom/movable/proc/get_cell() - return + return \ No newline at end of file diff --git a/code/game/gamemodes/newobjective.dm b/code/game/gamemodes/newobjective.dm index c52e51d5b5..1b3a1147a1 100644 --- a/code/game/gamemodes/newobjective.dm +++ b/code/game/gamemodes/newobjective.dm @@ -749,7 +749,7 @@ datum blueprints - steal_target = /obj/item/blueprints + steal_target = /obj/item/areaeditor/blueprints explanation_text = "Steal the station's blueprints." weight = 20 diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 9b6b532f96..2818e3e7b4 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -431,7 +431,7 @@ var/global/list/all_objectives = list() "a site manager's jumpsuit" = /obj/item/clothing/under/rank/captain, "a functional AI" = /obj/item/device/aicard, "a pair of magboots" = /obj/item/clothing/shoes/magboots, - "the station blueprints" = /obj/item/blueprints, + "the station blueprints" = /obj/item/areaeditor/blueprints, "a nasa voidsuit" = /obj/item/clothing/suit/space/void, "28 moles of phoron (full tank)" = /obj/item/weapon/tank, "a sample of slime extract" = /obj/item/slime_extract, diff --git a/code/game/jobs/job/job.dm b/code/game/jobs/job/job.dm index 509572aa98..cf09d52861 100644 --- a/code/game/jobs/job/job.dm +++ b/code/game/jobs/job/job.dm @@ -147,7 +147,7 @@ var/mob/living/carbon/human/dummy/mannequin/mannequin = get_mannequin("#job_icon") dress_mannequin(mannequin) mannequin.dir = SOUTH - COMPILE_OVERLAYS(mannequin) + mannequin.ImmediateOverlayUpdate() var/icon/preview_icon = getFlatIcon(mannequin) preview_icon.Scale(preview_icon.Width() * 2, preview_icon.Height() * 2) // Scaling here to prevent blurring in the browser. diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm index 2c8f6dd8b8..f4c016785d 100644 --- a/code/game/jobs/job_controller.dm +++ b/code/game/jobs/job_controller.dm @@ -393,7 +393,7 @@ var/global/datum/controller/occupations/job_master //Equip custom gear loadout. var/list/custom_equip_slots = list() var/list/custom_equip_leftovers = list() - if(H.client.prefs.gear && H.client.prefs.gear.len && !(job.mob_type & JOB_SILICON)) + if(H.client && H.client.prefs && H.client.prefs.gear && H.client.prefs.gear.len && !(job.mob_type & JOB_SILICON)) for(var/thing in H.client.prefs.gear) var/datum/gear/G = gear_datums[thing] if(!G) //Not a real gear datum (maybe removed, as this is loaded from their savefile) diff --git a/code/game/machinery/air_alarm.dm b/code/game/machinery/air_alarm.dm index ca40f0dc53..82d6fa0f6f 100644 --- a/code/game/machinery/air_alarm.dm +++ b/code/game/machinery/air_alarm.dm @@ -154,6 +154,12 @@ update_icon() +/obj/machinery/alarm/proc/update_area() + alarm_area = get_area(src) + area_uid = "\ref[alarm_area]" + if(name == "alarm") + name = "[alarm_area.name] Air Alarm" + /obj/machinery/alarm/Initialize() . = ..() set_frequency(frequency) @@ -540,9 +546,9 @@ var/list/list/environment_data = list() data["environment_data"] = environment_data - + DECLARE_TLV_VALUES - + var/pressure = environment.return_pressure() LOAD_TLV_VALUES(TLV["pressure"], pressure) environment_data.Add(list(list( @@ -551,7 +557,7 @@ "unit" = "kPa", "danger_level" = TEST_TLV_VALUES ))) - + var/temperature = environment.temperature LOAD_TLV_VALUES(TLV["temperature"], temperature) environment_data.Add(list(list( @@ -573,7 +579,7 @@ "unit" = "%", "danger_level" = TEST_TLV_VALUES ))) - + if(!locked || issilicon(user) || data["remoteUser"]) var/list/list/vents = list() data["vents"] = vents @@ -595,7 +601,7 @@ "extdefault"= (info["external"] == ONE_ATMOSPHERE), "intdefault"= (info["internal"] == 0), ))) - + var/list/list/scrubbers = list() data["scrubbers"] = scrubbers @@ -622,7 +628,7 @@ data["scrubbers"] = scrubbers data["mode"] = mode - + var/list/list/modes = list() data["modes"] = modes modes[++modes.len] = list("name" = "Filtering - Scrubs out contaminants", "mode" = AALARM_MODE_SCRUBBING, "selected" = mode == AALARM_MODE_SCRUBBING, "danger" = 0) @@ -682,7 +688,7 @@ else target_temperature = input_temperature + T0C return TRUE - + // Account for remote users here. // Yes, this is kinda snowflaky; however, I would argue it would be far more snowflakey // to include "custom hrefs" and all the other bullshit that nano states have just for the diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm index 4efec263f8..1d45a3e508 100644 --- a/code/game/machinery/computer/Operating.dm +++ b/code/game/machinery/computer/Operating.dm @@ -184,7 +184,7 @@ /obj/machinery/computer/operating/proc/build_surgery_list(mob/user) if(!istype(victim)) return null - + . = list() for(var/limb in victim.organs_by_name) @@ -281,6 +281,7 @@ /datum/surgery_step/cavity, /datum/surgery_step/limb, /datum/surgery_step/brainstem, + /datum/surgery_step/generic/ripper, ) good_surgeries = surgery_steps for(var/datum/surgery_step/S in good_surgeries) diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index 35a060863e..0226d0bc66 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -189,7 +189,7 @@ var/mob/M = grab.affecting qdel(grab) put_mob(M) - + return /obj/machinery/atmospherics/unary/cryo_cell/MouseDrop_T(var/mob/target, var/mob/user) //Allows borgs to put people into cryo without external assistance @@ -226,6 +226,9 @@ if(occupant.bodytemperature < 225) if(occupant.getToxLoss()) occupant.adjustToxLoss(max(-1, -20/occupant.getToxLoss())) + if(occupant.radiation || occupant.accumulated_rads) + occupant.radiation -= 25 + occupant.accumulated_rads -= 25 var/heal_brute = occupant.getBruteLoss() ? min(1, 20/occupant.getBruteLoss()) : 0 var/heal_fire = occupant.getFireLoss() ? min(1, 20/occupant.getFireLoss()) : 0 occupant.heal_organ_damage(heal_brute,heal_fire) diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index c0c23f9420..a4052b75bc 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -475,8 +475,8 @@ //Handle job slot/tater cleanup. var/job = to_despawn.mind.assigned_role - job_master.FreeRole(job) + to_despawn.mind.assigned_role = null if(to_despawn.mind.objectives.len) qdel(to_despawn.mind.objectives) @@ -526,12 +526,14 @@ //VOREStation Edit Start var/depart_announce = TRUE + var/departing_job = to_despawn.mind.role_alt_title + if(istype(to_despawn, /mob/living/dominated_brain)) depart_announce = FALSE if(depart_announce) - announce.autosay("[to_despawn.real_name], [to_despawn.mind.role_alt_title], [on_store_message]", "[on_store_name]", announce_channel, using_map.get_map_levels(z, TRUE, om_range = DEFAULT_OVERMAP_RANGE)) + announce.autosay("[to_despawn.real_name][departing_job ? ", [departing_job], " : " "][on_store_message]", "[on_store_name]", announce_channel, using_map.get_map_levels(z, TRUE, om_range = DEFAULT_OVERMAP_RANGE)) visible_message("\The [initial(name)] [on_store_visible_message_1] [to_despawn.real_name] [on_store_visible_message_2]", 3) //VOREStation Edit End diff --git a/code/game/machinery/frame.dm b/code/game/machinery/frame.dm index d651ad2025..6c71e63207 100644 --- a/code/game/machinery/frame.dm +++ b/code/game/machinery/frame.dm @@ -81,31 +81,6 @@ frame_class = FRAME_CLASS_MACHINE frame_size = 4 -/datum/frame/frame_types/oven - name = "Oven" - frame_class = FRAME_CLASS_MACHINE - frame_size = 4 - -/datum/frame/frame_types/fryer - name = "Fryer" - frame_class = FRAME_CLASS_MACHINE - frame_size = 4 - -/datum/frame/frame_types/grill - name = "Grill" - frame_class = FRAME_CLASS_MACHINE - frame_size = 4 - -/datum/frame/frame_types/cerealmaker - name = "Cereal Maker" - frame_class = FRAME_CLASS_MACHINE - frame_size = 4 - -/datum/frame/frame_types/candymachine - name = "Candy Machine" - frame_class = FRAME_CLASS_MACHINE - frame_size = 4 - /datum/frame/frame_types/fax name = "Fax" frame_class = FRAME_CLASS_MACHINE @@ -221,7 +196,7 @@ frame_style = FRAME_STYLE_WALL x_offset = 28 y_offset = 28 - + /datum/frame/frame_types/arfgs name = "ARF Generator" frame_class = FRAME_CLASS_MACHINE diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm index 1e1fff180e..be37e988b8 100644 --- a/code/game/machinery/navbeacon.dm +++ b/code/game/machinery/navbeacon.dm @@ -150,7 +150,7 @@ Transponder Codes: