powder that makes you say yes

This commit is contained in:
Bib Bob
2022-10-08 22:41:28 -05:00
544 changed files with 24792 additions and 19856 deletions

View File

@@ -53,7 +53,8 @@ Mostly for chomp exclusive stuff, otherwise if you need to modify a base file fo
* For multi-line removals: Use a block comment (/\* xxx \*/) to comment out the existing code block (do not modify whitespace more than necessary) and at the start, it should contain /\* CHOMP Removal - "Reason" * For multi-line removals: Use a block comment (/\* xxx \*/) to comment out the existing code block (do not modify whitespace more than necessary) and at the start, it should contain /\* CHOMP Removal - "Reason"
* If it is something like a bugfix that Polaris or Vorestation would want (the codebase we use), you may want to consider coding it there as well. They may want any general gameplay bugfixes, and things that are obviously intended to work one way, but do not. They do not have any of our fluff species (vulp, akula, fenn, etc) so do not make PRs related to that, or any vore content to them. * If it is something like a bugfix that Polaris or Vorestation would want (the codebase we use), you may want to consider coding it there as well. They may want any general gameplay bugfixes, and things that are obviously intended to work one way, but do not. They do not have any of our fluff species (vulp, akula, fenn, etc) so do not make PRs related to that, or any vore content to them.
* Change whitespace as little as possible. Do not randomly add/remove whitespace. * Change whitespace as little as possible. Do not randomly add/remove whitespace.
* Any new files should have "_ch" at the end. For example, "life_ch.dm". Just make them in the same location as the file they are related to. * Any new files should preferrably go into the modular_chomp folder following the file structure of where it would be placed normally. The old method was to have "_ch" at the end. For example, "life_ch.dm".
* Do not make changes to base icon files. New icon files should go into modular_chomp and code should be changed to point to the new file.
* Map changes must be in tgm format. See the [Mapmerge2 Readme] for details, or use [StrongDMM] which can automatically save maps as tgm. * Map changes must be in tgm format. See the [Mapmerge2 Readme] for details, or use [StrongDMM] which can automatically save maps as tgm.
The `attempt_ch()` proc has been added for your convienence. It allows a many-line change to become a single-line change in the existing Polaris files, preserving mergeability and allowing better code separation while preventing your new code from causing runtimes that stop the original code from running. If you are wanting to inject new procedures into an existing proc, called `update_atoms()` for example, you would create `update_atoms_ch()` in a nearby `_ch.dm` file, and then call to it from a single line in the original `update_atoms()` with `attempt_ch()`. The `attempt_ch()` proc has been added for your convienence. It allows a many-line change to become a single-line change in the existing Polaris files, preserving mergeability and allowing better code separation while preventing your new code from causing runtimes that stop the original code from running. If you are wanting to inject new procedures into an existing proc, called `update_atoms()` for example, you would create `update_atoms_ch()` in a nearby `_ch.dm` file, and then call to it from a single line in the original `update_atoms()` with `attempt_ch()`.

View File

@@ -11,8 +11,13 @@ on:
paths: paths:
- 'maps/**' - 'maps/**'
permissions: {}
jobs: jobs:
generate_maps: generate_maps:
permissions:
contents: write # to push to branch
pull-requests: write # to create pull requests (repo-sync/pull-request)
name: 'Generate NanoMaps' name: 'Generate NanoMaps'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:

View File

@@ -7,7 +7,6 @@
"oderwat.indent-rainbow", "oderwat.indent-rainbow",
"rexebin.darkpurple-black", "rexebin.darkpurple-black",
"dbaeumer.vscode-eslint", "dbaeumer.vscode-eslint",
"editorconfig.editorconfig",
"donkie.vscode-tgstation-test-adapter", "donkie.vscode-tgstation-test-adapter",
"icrawl.discord-vscode", "icrawl.discord-vscode",
"esbenp.prettier-vscode" "esbenp.prettier-vscode"

View File

@@ -94,6 +94,13 @@
assign_uid() assign_uid()
id_tag = num2text(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() /obj/machinery/atmospherics/unary/vent_pump/Destroy()
unregister_radio(src, frequency) unregister_radio(src, frequency)
if(initial_loc) if(initial_loc)

View File

@@ -43,6 +43,12 @@
assign_uid() assign_uid()
id_tag = num2text(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() /obj/machinery/atmospherics/unary/vent_scrubber/Destroy()
unregister_radio(src, frequency) unregister_radio(src, frequency)
if(initial_loc) if(initial_loc)

View File

@@ -161,16 +161,14 @@
if(istype(target, /turf/simulated)) if(istype(target, /turf/simulated))
var/turf/simulated/modeled_location = target 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 if (modeled_location.special_temperature)
//assuming aluminium with thermal conductivity 235 W * K / m, Copper (400), Silver (430), steel (50), gold (320) air.temperature += thermal_conductivity * (modeled_location.special_temperature - air.temperature)
var/heat_gain = 23500 * 100 * delta_temp if (air.temperature < TCMB)
air.add_thermal_energy(heat_gain) air.temperature = TCMB
if(network) if (network)
network.update = 1 network.update = TRUE
if(modeled_location.blocks_air) if(modeled_location.blocks_air)
if((modeled_location.heat_capacity>0) && (partial_heat_capacity>0)) if((modeled_location.heat_capacity>0) && (partial_heat_capacity>0))

View File

@@ -0,0 +1,2 @@
#define SMITE_PIE "Pie Splat"
#define SMITE_SPICE "Spicy Air"

View File

@@ -400,10 +400,6 @@
///called when removing a given item from a mob, from mob/living/carbon/remove_embedded_object(mob/living/carbon/target, /obj/item) ///called when removing a given item from a mob, from mob/living/carbon/remove_embedded_object(mob/living/carbon/target, /obj/item)
#define COMSIG_CARBON_EMBED_REMOVAL "item_embed_remove_safe" #define COMSIG_CARBON_EMBED_REMOVAL "item_embed_remove_safe"
// /mob/living/simple_animal/hostile signals
#define COMSIG_HOSTILE_ATTACKINGTARGET "hostile_attackingtarget"
#define COMPONENT_HOSTILE_NO_ATTACK (1<<0)
// /obj signals // /obj signals
///from base of obj/deconstruct(): (disassembled) ///from base of obj/deconstruct(): (disassembled)

View File

@@ -54,6 +54,8 @@
#define MAT_PLATINUM "platinum" #define MAT_PLATINUM "platinum"
#define MAT_TRITIUM "tritium" #define MAT_TRITIUM "tritium"
#define MAT_DEUTERIUM "deuterium" #define MAT_DEUTERIUM "deuterium"
#define MAT_CONCRETE "concrete"
#define MAT_PLASTEELREBAR "plasteel rebar"
#define DEFAULT_TABLE_MATERIAL MAT_PLASTIC #define DEFAULT_TABLE_MATERIAL MAT_PLASTIC

View File

@@ -40,9 +40,10 @@
#define NIF_SIZECHANGE 33 #define NIF_SIZECHANGE 33
#define NIF_SOULCATCHER 34 #define NIF_SOULCATCHER 34
#define NIF_WORLDBEND 35 #define NIF_WORLDBEND 35
#define NIF_MALWARE 36
// Must be equal to the highest number above // Must be equal to the highest number above
#define TOTAL_NIF_SOFTWARE 35 #define TOTAL_NIF_SOFTWARE 36
////////////////////// //////////////////////
// NIF flag list hints // NIF flag list hints

View File

@@ -28,3 +28,12 @@
#define OUTDOORS_NO 0 // Ditto. #define OUTDOORS_NO 0 // Ditto.
#define OUTDOORS_AREA -1 // If a turf has this, it will defer to the area's settings on init. #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. // 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) \
)

View File

@@ -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
* <https://github.com/SpaceManiac/SpacemanDMM/tree/suite-1.7/src/dreamchecker>
*/
// The SPACEMAN_DMM define is set by the linter and other tooling when it runs.
#ifdef SPACEMAN_DMM #ifdef SPACEMAN_DMM
#define RETURN_TYPE(X) set SpacemanDMM_return_type = X #define RETURN_TYPE(X) set SpacemanDMM_return_type = X
#define SHOULD_CALL_PARENT(X) set SpacemanDMM_should_call_parent = X #define SHOULD_CALL_PARENT(X) set SpacemanDMM_should_call_parent = X

View File

@@ -2,7 +2,8 @@ GLOBAL_LIST_INIT(speech_toppings, list("|" = "i", "+" = "b", "_" = "u"))
GLOBAL_LIST_EMPTY(meteor_list) GLOBAL_LIST_EMPTY(meteor_list)
/// List of wire colors for each object type of that round. One for airlocks, one for vendors, etc. /// 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() // Reference list for disposal sort junctions. Filled up by sorting junction's New()
GLOBAL_LIST_EMPTY(tagger_locations) GLOBAL_LIST_EMPTY(tagger_locations)

View File

@@ -43,7 +43,7 @@ var/global/list/item_vore_blacklist = list(
/obj/item/weapon/gun, /obj/item/weapon/gun,
/obj/item/weapon/pinpointer, /obj/item/weapon/pinpointer,
/obj/item/clothing/shoes/magboots, /obj/item/clothing/shoes/magboots,
/obj/item/blueprints, /obj/item/areaeditor/blueprints,
/obj/item/clothing/head/helmet/space, /obj/item/clothing/head/helmet/space,
/obj/item/weapon/disk/nuclear, /obj/item/weapon/disk/nuclear,
/obj/item/clothing/suit/storage/hooded/wintercoat/roiz) /obj/item/clothing/suit/storage/hooded/wintercoat/roiz)
@@ -850,3 +850,95 @@ var/global/list/xenobio_rainbow_extracts = list(
/obj/item/slime_extract/emerald = 3, /obj/item/slime_extract/emerald = 3,
/obj/item/slime_extract/light_pink = 1, /obj/item/slime_extract/light_pink = 1,
/obj/item/slime_extract/rainbow = 1) /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 //CHOMP Comment - Actually these are causing compilation error.
// /area/surface/cave, //SC
// /area/tether/surfacebase/outside, //CHOMP Edit Downstreams, uncomment these if you are using these maps
// /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 //CHOMP Comment - Actually these are causing compilation error.
// /area/surface/cave, //SC
//TETHER STUFF BELOW THIS //CHOMP Edit Downstreams, uncomment these if you are using these maps
// /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
))

View File

@@ -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 for(var/turf/T in N) turfs += T
return turfs 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. //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. //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) /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 atoms += A
return atoms 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. /datum/coords //Simple datum for storing coordinates.
var/x_pos = null var/x_pos = null
var/y_pos = null var/y_pos = null

View File

@@ -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)]"

View File

@@ -167,6 +167,9 @@
vis_contents -= hover_overlays_cache[hovering_choice] vis_contents -= hover_overlays_cache[hovering_choice]
hovering_choice = choice hovering_choice = choice
if(!choice)
return
var/obj/effect/overlay/zone_sel/overlay_object = hover_overlays_cache[choice] var/obj/effect/overlay/zone_sel/overlay_object = hover_overlays_cache[choice]
if(!overlay_object) if(!overlay_object)
overlay_object = new overlay_object = new
@@ -174,7 +177,6 @@
hover_overlays_cache[choice] = overlay_object hover_overlays_cache[choice] = overlay_object
vis_contents += overlay_object vis_contents += overlay_object
/obj/effect/overlay/zone_sel /obj/effect/overlay/zone_sel
icon = 'icons/mob/zone_sel.dmi' icon = 'icons/mob/zone_sel.dmi'
mouse_opacity = MOUSE_OPACITY_TRANSPARENT mouse_opacity = MOUSE_OPACITY_TRANSPARENT
@@ -240,7 +242,7 @@
update_icon() update_icon()
/obj/screen/zone_sel/update_icon() /obj/screen/zone_sel/update_icon()
cut_overlay(selecting_appearance) cut_overlays()
selecting_appearance = mutable_appearance('icons/mob/zone_sel.dmi', "[selecting]") selecting_appearance = mutable_appearance('icons/mob/zone_sel.dmi', "[selecting]")
add_overlay(selecting_appearance) add_overlay(selecting_appearance)
@@ -985,4 +987,4 @@
else //"0" is still length 1 so this means it's over 999 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, "o9")
overlays += image('icons/mob/screen_ammo.dmi', src, "t9") overlays += image('icons/mob/screen_ammo.dmi', src, "t9")
overlays += image('icons/mob/screen_ammo.dmi', src, "h9") overlays += image('icons/mob/screen_ammo.dmi', src, "h9")

View File

@@ -39,7 +39,7 @@ SUBSYSTEM_DEF(ai)
if(!L?.loc) if(!L?.loc)
continue 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() A.handle_strategicals()
else else
slept_mobs++ slept_mobs++

View File

@@ -32,17 +32,18 @@ SUBSYSTEM_DEF(lighting)
MC_SPLIT_TICK MC_SPLIT_TICK
var/list/queue = sources_queue var/list/queue = sources_queue
var/i = 0 var/i = 0
for (i in 1 to length(queue)) if(length(queue))
var/datum/light_source/L = queue[i] for(i in 1 to length(queue))
var/datum/light_source/L = queue[i]
L.update_corners() L.update_corners()
L.needs_update = LIGHTING_NO_UPDATE L.needs_update = LIGHTING_NO_UPDATE
if(init_tick_checks) if(init_tick_checks)
CHECK_TICK CHECK_TICK
else if (MC_TICK_CHECK) else if (MC_TICK_CHECK)
break break
if (i) if (i)
queue.Cut(1, i+1) queue.Cut(1, i+1)
i = 0 i = 0

View File

@@ -15,7 +15,7 @@ SUBSYSTEM_DEF(mobs)
var/list/currentrun = list() var/list/currentrun = list()
var/log_extensively = FALSE var/log_extensively = FALSE
var/list/timelog = list() var/list/timelog = list()
var/slept_mobs = 0 var/slept_mobs = 0
var/list/process_z = list() var/list/process_z = list()
@@ -40,10 +40,10 @@ SUBSYSTEM_DEF(mobs)
if(!M || QDELETED(M)) if(!M || QDELETED(M))
mob_list -= M mob_list -= M
continue 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++ slept_mobs++
continue continue
M.Life(times_fired) M.Life(times_fired)
if (MC_TICK_CHECK) if (MC_TICK_CHECK)
@@ -58,14 +58,14 @@ SUBSYSTEM_DEF(mobs)
log_world(msg) log_world(msg)
return return
msg += "Lists: currentrun: [currentrun.len], mob_list: [mob_list.len]\n" msg += "Lists: currentrun: [currentrun.len], mob_list: [mob_list.len]\n"
if(!currentrun.len) if(!currentrun.len)
msg += "!!The subsystem just finished the mob_list list, and currentrun is empty (or has never run).\n" 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" 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] 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" msg += "Tail entry: [describeThis(D)] (this is likely the item AFTER the problem item)\n"
var/position = mob_list.Find(D) var/position = mob_list.Find(D)
if(!position) if(!position)
msg += "Unable to find context of tail entry in mob_list list.\n" msg += "Unable to find context of tail entry in mob_list list.\n"

View File

@@ -34,7 +34,7 @@ PROCESSING_SUBSYSTEM_DEF(instruments)
/datum/controller/subsystem/processing/instruments/proc/initialize_instrument_data() /datum/controller/subsystem/processing/instruments/proc/initialize_instrument_data()
for(var/datum/instrument/I as anything in subtypesof(/datum/instrument)) for(var/datum/instrument/I as anything in subtypesof(/datum/instrument))
if(initial(I.abstract_type) == I) if(initial(I.instrument_type) == I)
continue continue
I = new I I = new I
I.Initialize() I.Initialize()

View File

@@ -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
)

View File

@@ -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()

View File

@@ -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
)

View File

@@ -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

View File

@@ -77,6 +77,20 @@
containertype = /obj/structure/closet/crate/focalpoint containertype = /obj/structure/closet/crate/focalpoint
containername = "advanced hull shield generator crate" containername = "advanced hull shield generator crate"
/datum/supply_pack/eng/point_defense_cannon_circuit
name = "Point Defense Turret Circuit"
contains = list(/obj/item/weapon/circuitboard/pointdefense = 2)
cost = 20
containertype = /obj/structure/closet/crate/heph
containername = "point defense turret circuit crate"
/datum/supply_pack/eng/point_defense_control_circuit
name = "Point Defense Controller Circuit"
contains = list(/obj/item/weapon/circuitboard/pointdefense_control = 1)
cost = 30
containertype = /obj/structure/closet/crate/heph
containername = "point defense mainframe circuit crate"
/datum/supply_pack/eng/electrical /datum/supply_pack/eng/electrical
name = "Electrical maintenance crate" name = "Electrical maintenance crate"
contains = list( contains = list(

View File

@@ -47,7 +47,7 @@
cost = 10 cost = 10
containertype = /obj/structure/closet/crate/gilthari containertype = /obj/structure/closet/crate/gilthari
containername = "crate of bar supplies" containername = "crate of bar supplies"
/datum/supply_pack/hospitality/cookingoil /datum/supply_pack/hospitality/cookingoil
name = "Cooking oil tank crate" name = "Cooking oil tank crate"
contains = list(/obj/structure/reagent_dispensers/cookingoil) contains = list(/obj/structure/reagent_dispensers/cookingoil)
@@ -96,6 +96,15 @@
containertype = /obj/structure/closet/crate/centauri containertype = /obj/structure/closet/crate/centauri
containername = "Painting equipment" 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/ /datum/supply_pack/randomised/hospitality/
group = "Hospitality" group = "Hospitality"

View File

@@ -83,4 +83,11 @@
containertype = /obj/structure/closet/crate/grayson containertype = /obj/structure/closet/crate/grayson
containername = "Linoleum crate" containername = "Linoleum crate"
cost = 15 cost = 15
contains = list(/obj/fiftyspawner/linoleum) 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"

View File

@@ -75,6 +75,19 @@
containername = "Shotgun crate" containername = "Shotgun crate"
access = access_armory access = access_armory
/* VOREStation edit -- This is a bad idea. -- So is this. /* 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 /datum/supply_pack/munitions/erifle
name = "Weapons - Energy marksman" name = "Weapons - Energy marksman"
contains = list(/obj/item/weapon/gun/energy/sniperrifle = 2) contains = list(/obj/item/weapon/gun/energy/sniperrifle = 2)
@@ -307,4 +320,4 @@
cost = 500 cost = 500
containertype = /obj/structure/closet/crate/secure containertype = /obj/structure/closet/crate/secure
containername = "Light machine gun crate" containername = "Light machine gun crate"
access = access_armory access = access_armory

View File

@@ -18,11 +18,6 @@
name = "SweatMAX Vendor Refill Cartridge" name = "SweatMAX Vendor Refill Cartridge"
cost = 10 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 /datum/supply_pack/vending_refills/weeb
contains = list(/obj/item/weapon/refill_cartridge/autoname/food/weeb) contains = list(/obj/item/weapon/refill_cartridge/autoname/food/weeb)
name = "Nippon-tan Vendor Refill Cartridge" name = "Nippon-tan Vendor Refill Cartridge"
@@ -122,7 +117,6 @@
num_contained = 5 num_contained = 5
contains = list(/obj/item/weapon/refill_cartridge/autoname/food/snack, 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/fitness,
/obj/item/weapon/refill_cartridge/autoname/food/hotfood,
/obj/item/weapon/refill_cartridge/autoname/food/weeb, /obj/item/weapon/refill_cartridge/autoname/food/weeb,
/obj/item/weapon/refill_cartridge/autoname/food/sol, /obj/item/weapon/refill_cartridge/autoname/food/sol,
/obj/item/weapon/refill_cartridge/autoname/food/snix, /obj/item/weapon/refill_cartridge/autoname/food/snix,

View File

@@ -266,4 +266,13 @@
cost = 150 cost = 150
containertype = /obj/structure/closet/crate/oculum containertype = /obj/structure/closet/crate/oculum
containername = "Vox Engineering Hardsuit" containername = "Vox Engineering Hardsuit"
/datum/supply_pack/voidsuits/voxsec
name = "Vox Security Hardsuit"
contains = list (/obj/item/weapon/rig/vox/security)
cost = 90
containertype = /obj/structure/closet/crate/secure/heph
containername = "Vox security Rigsuit Crate"
access = access_security
//ChompEdit End //ChompEdit End

View File

@@ -6,25 +6,25 @@
/datum/uplink_item/item/armor/combat /datum/uplink_item/item/armor/combat
name = "Combat Armor Set" name = "Combat Armor Set"
item_cost = 60 item_cost = 30
path = /obj/item/weapon/storage/box/syndie_kit/combat_armor path = /obj/item/weapon/storage/box/syndie_kit/combat_armor
/datum/uplink_item/item/armor/heavy_vest /datum/uplink_item/item/armor/heavy_vest
name = "Heavy Armor Vest" name = "Heavy Armor Vest"
item_cost = 40 item_cost = 20
path = /obj/item/clothing/suit/storage/vest/heavy/merc path = /obj/item/clothing/suit/storage/vest/heavy/merc
/datum/uplink_item/item/armor/gorlexsuit /datum/uplink_item/item/armor/gorlexsuit
name = "Mercenary Voidsuit" name = "Mercenary Voidsuit"
item_cost = 40 item_cost = 20
path = /obj/item/weapon/storage/box/syndie_kit/voidsuit path = /obj/item/weapon/storage/box/syndie_kit/voidsuit
/datum/uplink_item/item/armor/gorlexsuit_fire /datum/uplink_item/item/armor/gorlexsuit_fire
name = "Mercenary Voidsuit (Fire)" name = "Mercenary Voidsuit (Fire)"
item_cost = 40 item_cost = 20
path = /obj/item/weapon/storage/box/syndie_kit/voidsuit/fire path = /obj/item/weapon/storage/box/syndie_kit/voidsuit/fire
/datum/uplink_item/item/armor/combat /datum/uplink_item/item/armor/combat
name = "Combat Platecarrier Set" name = "Combat Platecarrier Set"
item_cost = 60 item_cost = 30
path = /obj/item/clothing/suit/armor/pcarrier/merc path = /obj/item/clothing/suit/armor/pcarrier/merc

View File

@@ -6,88 +6,108 @@
/datum/uplink_item/item/medical/onegativeblood /datum/uplink_item/item/medical/onegativeblood
name = "O- Blood Pack" name = "O- Blood Pack"
item_cost = 5 item_cost = 1
path = /obj/item/weapon/reagent_containers/blood/OMinus path = /obj/item/weapon/reagent_containers/blood/OMinus
/datum/uplink_item/item/medical/sinpockets /datum/uplink_item/item/medical/sinpockets
name = "Box of Sin-Pockets" name = "Box of Sin-Pockets"
item_cost = 5 item_cost = 1
path = /obj/item/weapon/storage/box/sinpockets path = /obj/item/weapon/storage/box/sinpockets
/datum/uplink_item/item/medical/ambrosiaseeds /datum/uplink_item/item/medical/ambrosiaseeds
name = "Box of 7x ambrosia seed packets" name = "Box of 7x ambrosia seed packets"
item_cost = 5 item_cost = 1
path = /obj/item/weapon/storage/box/ambrosia path = /obj/item/weapon/storage/box/ambrosia
/datum/uplink_item/item/medical/clotting /datum/uplink_item/item/medical/clotting
name = "Clotting Medicine injector" name = "Clotting Medicine injector"
item_cost = 10 item_cost = 5
path = /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/clotting path = /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/clotting
/datum/uplink_item/item/medical/clotting_case /datum/uplink_item/item/medical/clotting_case
name = "Clotting Medicine 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." 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 path = /obj/item/weapon/storage/quickdraw/syringe_case/clotting
/datum/uplink_item/item/medical/bonemeds /datum/uplink_item/item/medical/bonemeds
name = "Bone Repair injector" name = "Bone Repair injector"
item_cost = 10 item_cost = 5
path = /obj/item/weapon/reagent_containers/hypospray/autoinjector/bonemed path = /obj/item/weapon/reagent_containers/hypospray/autoinjector/bonemed
/datum/uplink_item/item/medical/clonemeds /datum/uplink_item/item/medical/clonemeds
name = "Clone injector" name = "Clone injector"
item_cost = 15 item_cost = 5
path = /obj/item/weapon/reagent_containers/hypospray/autoinjector/clonemed path = /obj/item/weapon/reagent_containers/hypospray/autoinjector/clonemed
/datum/uplink_item/item/medical/bonemeds_case /datum/uplink_item/item/medical/bonemeds_case
name = "Bone Repair 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." 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 path = /obj/item/weapon/storage/quickdraw/syringe_case/bonemed
/datum/uplink_item/item/medical/clonemeds_case /datum/uplink_item/item/medical/clonemeds_case
name = "Clone 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." 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 path = /obj/item/weapon/storage/quickdraw/syringe_case/clonemed
/datum/uplink_item/item/medical/ambrosiadeusseeds /datum/uplink_item/item/medical/ambrosiadeusseeds
name = "Box of 7x ambrosia deus seed packets" name = "Box of 7x ambrosia deus seed packets"
item_cost = 10 item_cost = 5
path = /obj/item/weapon/storage/box/ambrosiadeus path = /obj/item/weapon/storage/box/ambrosiadeus
/datum/uplink_item/item/medical/freezer /datum/uplink_item/item/medical/freezer
name = "Portable Freezer" name = "Portable Freezer"
item_cost = 10 item_cost = 1
path = /obj/item/weapon/storage/box/freezer path = /obj/item/weapon/storage/box/freezer
/datum/uplink_item/item/medical/monkeycubes /datum/uplink_item/item/medical/monkeycubes
name = "Box, Monkey Cubes" name = "Box, Monkey Cubes"
item_cost = 10 item_cost = 1
path = /obj/item/weapon/storage/box/monkeycubes path = /obj/item/weapon/storage/box/monkeycubes
/datum/uplink_item/item/medical/farwacubes /datum/uplink_item/item/medical/farwacubes
name = "Box, Farwa Cubes" name = "Box, Farwa Cubes"
item_cost = 10 item_cost = 1
path = /obj/item/weapon/storage/box/monkeycubes path = /obj/item/weapon/storage/box/monkeycubes
/datum/uplink_item/item/medical/neaeracubes /datum/uplink_item/item/medical/neaeracubes
name = "Box, Neaera Cubes" name = "Box, Neaera Cubes"
item_cost = 10 item_cost = 1
path = /obj/item/weapon/storage/box/monkeycubes/neaeracubes path = /obj/item/weapon/storage/box/monkeycubes/neaeracubes
/datum/uplink_item/item/medical/stokcubes /datum/uplink_item/item/medical/stokcubes
name = "Box, Stok Cubes" name = "Box, Stok Cubes"
item_cost = 10 item_cost = 1
path = /obj/item/weapon/storage/box/monkeycubes/stokcubes path = /obj/item/weapon/storage/box/monkeycubes/stokcubes
/datum/uplink_item/item/medical/surgery /datum/uplink_item/item/medical/surgery
name = "Surgery kit" name = "Surgery kit"
item_cost = 45 item_cost = 5
path = /obj/item/weapon/storage/firstaid/surgery 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 /datum/uplink_item/item/medical/combat
name = "Combat medical kit" name = "Combat medical kit"
item_cost = 60 item_cost = 20
path = /obj/item/weapon/storage/firstaid/combat path = /obj/item/weapon/storage/firstaid/combat

View File

@@ -139,6 +139,11 @@
item_cost = 75 item_cost = 75
path = /obj/item/weapon/gun/projectile/shotgun/pump/combat 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 /datum/uplink_item/item/visible_weapons/leveraction
name = "Lever Action Rifle" name = "Lever Action Rifle"
item_cost = 50 item_cost = 50

View File

@@ -43,6 +43,7 @@
if(!GLOB.wire_color_directory[holder_type]) if(!GLOB.wire_color_directory[holder_type])
randomize() randomize()
GLOB.wire_color_directory[holder_type] = colors GLOB.wire_color_directory[holder_type] = colors
GLOB.wire_name_directory[holder_type] = proper_name
else else
colors = GLOB.wire_color_directory[holder_type] colors = GLOB.wire_color_directory[holder_type]

View File

@@ -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 = FALSE) //CHOMP Edit set blast doors to FALSE /area/proc/prison_break(break_lights = TRUE, open_doors = TRUE, open_blast_doors = FALSE) //CHOMP Edit set blast doors to FALSE
var/obj/machinery/power/apc/theAPC = get_apc() var/obj/machinery/power/apc/theAPC = get_apc()
if(theAPC.operating) if(theAPC && theAPC.operating)
if(break_lights) if(break_lights)
for(var/obj/machinery/power/apc/temp_apc in src) for(var/obj/machinery/power/apc/temp_apc in src)
temp_apc.overload_lighting(70) temp_apc.overload_lighting(70)

View File

@@ -5,6 +5,9 @@
var/block_suit_sensors = FALSE //If mob size is limited in the area. var/block_suit_sensors = FALSE //If mob size is limited in the area.
var/turf/ceiling_type 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) /area/Entered(var/atom/movable/AM, oldLoc)
. = ..() . = ..()
if(enter_message && isliving(AM)) if(enter_message && isliving(AM))
@@ -29,3 +32,41 @@
var/turf/TA = GetAbove(T) var/turf/TA = GetAbove(T)
if(isopenspace(TA)) if(isopenspace(TA))
TA.ChangeTurf(ceiling_type, TRUE, TRUE, TRUE) 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)

View File

@@ -13,7 +13,7 @@
/obj/effect/meteor/big=3, /obj/effect/meteor/big=3,
/obj/effect/meteor/flaming=1, /obj/effect/meteor/flaming=1,
/obj/effect/meteor/irradiated=3 /obj/effect/meteor/irradiated=3
) )
//for threatening meteor event //for threatening meteor event
/var/list/meteors_threatening = list( /var/list/meteors_threatening = list(
@@ -109,13 +109,13 @@
desc = "You should probably run instead of gawking at this." desc = "You should probably run instead of gawking at this."
icon = 'icons/obj/meteor.dmi' icon = 'icons/obj/meteor.dmi'
icon_state = "small" icon_state = "small"
density = 1 density = TRUE
anchored = 1 anchored = TRUE
var/hits = 4 var/hits = 4
var/hitpwr = 2 //Level of ex_act to be called on hit. var/hitpwr = 2 //Level of ex_act to be called on hit.
var/dest var/dest
pass_flags = PASSTABLE pass_flags = PASSTABLE
var/heavy = 0 var/heavy = FALSE
var/z_original var/z_original
var/meteordrop = /obj/item/weapon/ore/iron var/meteordrop = /obj/item/weapon/ore/iron
@@ -147,7 +147,7 @@
get_hit() get_hit()
/obj/effect/meteor/Destroy() /obj/effect/meteor/Destroy()
walk(src,0) //this cancels the walk_towards() proc walk(src,FALSE) //this cancels the walk_towards() proc
GLOB.meteor_list -= src GLOB.meteor_list -= src
return ..() return ..()
@@ -162,10 +162,10 @@
ram_turf(get_turf(A)) ram_turf(get_turf(A))
get_hit() get_hit()
else else
die(0) die(FALSE)
/obj/effect/meteor/CanPass(atom/movable/mover, turf/target) /obj/effect/meteor/CanPass(atom/movable/mover, turf/target)
return istype(mover, /obj/effect/meteor) ? 1 : ..() return istype(mover, /obj/effect/meteor) ? TRUE : ..()
/obj/effect/meteor/proc/ram_turf(var/turf/T) /obj/effect/meteor/proc/ram_turf(var/turf/T)
//first bust whatever is in the turf //first bust whatever is in the turf
@@ -190,9 +190,9 @@
/obj/effect/meteor/proc/get_hit() /obj/effect/meteor/proc/get_hit()
hits-- hits--
if(hits <= 0) if(hits <= 0)
die(1) die(TRUE)
/obj/effect/meteor/proc/die(var/explode = 1) /obj/effect/meteor/proc/die(var/explode = TRUE)
make_debris() make_debris()
meteor_effect(explode) meteor_effect(explode)
qdel(src) qdel(src)
@@ -206,6 +206,18 @@
return return
..() ..()
/obj/effect/meteor/bullet_act(var/obj/item/projectile/Proj)
if(Proj.excavation_amount)
get_hit()
if(!QDELETED(src))
wall_power -= Proj.excavation_amount + Proj.damage + (Proj.hitscan * 25) // Instant-impact projectiles are inherently better at dealing with meteors.
if(wall_power <= 0)
die(FALSE) // If you kill the meteor, then it dies.
return
return
/obj/effect/meteor/proc/make_debris() /obj/effect/meteor/proc/make_debris()
for(var/throws = dropamt, throws > 0, throws--) for(var/throws = dropamt, throws > 0, throws--)
var/obj/item/O = new meteordrop(get_turf(src)) var/obj/item/O = new meteordrop(get_turf(src))
@@ -330,4 +342,4 @@
/obj/effect/meteor/tunguska/Bump() /obj/effect/meteor/tunguska/Bump()
..() ..()
if(prob(20)) if(prob(20))
explosion(src.loc,2,4,6,8) explosion(src.loc,2,4,6,8)

View File

@@ -749,7 +749,7 @@ datum
blueprints blueprints
steal_target = /obj/item/blueprints steal_target = /obj/item/areaeditor/blueprints
explanation_text = "Steal the station's blueprints." explanation_text = "Steal the station's blueprints."
weight = 20 weight = 20

View File

@@ -431,7 +431,7 @@ var/global/list/all_objectives = list()
"a site manager's jumpsuit" = /obj/item/clothing/under/rank/captain, "a site manager's jumpsuit" = /obj/item/clothing/under/rank/captain,
"a functional AI" = /obj/item/device/aicard, "a functional AI" = /obj/item/device/aicard,
"a pair of magboots" = /obj/item/clothing/shoes/magboots, "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, "a nasa voidsuit" = /obj/item/clothing/suit/space/void,
"28 moles of phoron (full tank)" = /obj/item/weapon/tank, "28 moles of phoron (full tank)" = /obj/item/weapon/tank,
"a sample of slime extract" = /obj/item/slime_extract, "a sample of slime extract" = /obj/item/slime_extract,

View File

@@ -393,7 +393,7 @@ var/global/datum/controller/occupations/job_master
//Equip custom gear loadout. //Equip custom gear loadout.
var/list/custom_equip_slots = list() var/list/custom_equip_slots = list()
var/list/custom_equip_leftovers = 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) for(var/thing in H.client.prefs.gear)
var/datum/gear/G = gear_datums[thing] var/datum/gear/G = gear_datums[thing]
if(!G) //Not a real gear datum (maybe removed, as this is loaded from their savefile) if(!G) //Not a real gear datum (maybe removed, as this is loaded from their savefile)

View File

@@ -154,6 +154,12 @@
update_icon() 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() /obj/machinery/alarm/Initialize()
. = ..() . = ..()
set_frequency(frequency) set_frequency(frequency)
@@ -540,9 +546,9 @@
var/list/list/environment_data = list() var/list/list/environment_data = list()
data["environment_data"] = environment_data data["environment_data"] = environment_data
DECLARE_TLV_VALUES DECLARE_TLV_VALUES
var/pressure = environment.return_pressure() var/pressure = environment.return_pressure()
LOAD_TLV_VALUES(TLV["pressure"], pressure) LOAD_TLV_VALUES(TLV["pressure"], pressure)
environment_data.Add(list(list( environment_data.Add(list(list(
@@ -551,7 +557,7 @@
"unit" = "kPa", "unit" = "kPa",
"danger_level" = TEST_TLV_VALUES "danger_level" = TEST_TLV_VALUES
))) )))
var/temperature = environment.temperature var/temperature = environment.temperature
LOAD_TLV_VALUES(TLV["temperature"], temperature) LOAD_TLV_VALUES(TLV["temperature"], temperature)
environment_data.Add(list(list( environment_data.Add(list(list(
@@ -573,7 +579,7 @@
"unit" = "%", "unit" = "%",
"danger_level" = TEST_TLV_VALUES "danger_level" = TEST_TLV_VALUES
))) )))
if(!locked || issilicon(user) || data["remoteUser"]) if(!locked || issilicon(user) || data["remoteUser"])
var/list/list/vents = list() var/list/list/vents = list()
data["vents"] = vents data["vents"] = vents
@@ -595,7 +601,7 @@
"extdefault"= (info["external"] == ONE_ATMOSPHERE), "extdefault"= (info["external"] == ONE_ATMOSPHERE),
"intdefault"= (info["internal"] == 0), "intdefault"= (info["internal"] == 0),
))) )))
var/list/list/scrubbers = list() var/list/list/scrubbers = list()
data["scrubbers"] = scrubbers data["scrubbers"] = scrubbers
@@ -622,7 +628,7 @@
data["scrubbers"] = scrubbers data["scrubbers"] = scrubbers
data["mode"] = mode data["mode"] = mode
var/list/list/modes = list() var/list/list/modes = list()
data["modes"] = modes data["modes"] = modes
modes[++modes.len] = list("name" = "Filtering - Scrubs out contaminants", "mode" = AALARM_MODE_SCRUBBING, "selected" = mode == AALARM_MODE_SCRUBBING, "danger" = 0) 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 else
target_temperature = input_temperature + T0C target_temperature = input_temperature + T0C
return TRUE return TRUE
// Account for remote users here. // Account for remote users here.
// Yes, this is kinda snowflaky; however, I would argue it would be far more snowflakey // 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 // to include "custom hrefs" and all the other bullshit that nano states have just for the

View File

@@ -189,7 +189,7 @@
var/mob/M = grab.affecting var/mob/M = grab.affecting
qdel(grab) qdel(grab)
put_mob(M) put_mob(M)
return 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 /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.bodytemperature < 225)
if(occupant.getToxLoss()) if(occupant.getToxLoss())
occupant.adjustToxLoss(max(-1, -20/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_brute = occupant.getBruteLoss() ? min(1, 20/occupant.getBruteLoss()) : 0
var/heal_fire = occupant.getFireLoss() ? min(1, 20/occupant.getFireLoss()) : 0 var/heal_fire = occupant.getFireLoss() ? min(1, 20/occupant.getFireLoss()) : 0
occupant.heal_organ_damage(heal_brute,heal_fire) occupant.heal_organ_damage(heal_brute,heal_fire)

View File

@@ -475,8 +475,8 @@
//Handle job slot/tater cleanup. //Handle job slot/tater cleanup.
var/job = to_despawn.mind.assigned_role var/job = to_despawn.mind.assigned_role
job_master.FreeRole(job) job_master.FreeRole(job)
to_despawn.mind.assigned_role = null
if(to_despawn.mind.objectives.len) if(to_despawn.mind.objectives.len)
qdel(to_despawn.mind.objectives) qdel(to_despawn.mind.objectives)

View File

@@ -149,6 +149,41 @@
M.close() M.close()
return return
//CHOMP Add start
/obj/machinery/button/remote/blast_door/bear
name = "stuffed bear"
icon = 'icons/obj/stationobjs_vr.dmi'
icon_state = "stuffedbear"
desc = "A stuffed and mounted bear. Quite a statement piece, but holds a curious glare."
density = 1
/obj/machinery/button/remote/blast_door/bear/attack_hand(mob/user as mob) //code to stop bear ever reverting to standard button sprites
if(..())
return
add_fingerprint(user)
if(stat & (NOPOWER|BROKEN))
return
if(!allowed(user) && (wires & 1))
to_chat(user, "<span class='warning'>Access Denied</span>")
flick("doorctrl-denied",src)
return
use_power(5)
icon_state = "stuffedbear"
desiredstate = !desiredstate
trigger(user)
spawn(15)
update_icon()
/obj/machinery/button/remote/blast_door/bear/update_icon()
if(stat & NOPOWER)
icon_state = "stuffedbear"
else
icon_state = "stuffedbear"
//CHOMP Add end
/* /*
Emitter remote control Emitter remote control
*/ */

View File

@@ -319,6 +319,15 @@
density = FALSE density = FALSE
opacity = 0 opacity = 0
/obj/machinery/door/blast/regular/bookcase //CHOMP Add code block
name = "bookcase"
desc = "On closer inspection, the array of books is decorative and built into the frame."
icon_state = "bookcase1"
icon_state_open = "bookcase0"
icon_state_opening = "bookcasec0"
icon_state_closed = "bookcase1"
icon_state_closing = "bookcasec1"
// SUBTYPE: Shutters // SUBTYPE: Shutters
// Nicer looking, and also weaker, shutters. Found in kitchen and similar areas. // Nicer looking, and also weaker, shutters. Found in kitchen and similar areas.
/obj/machinery/door/blast/shutters /obj/machinery/door/blast/shutters
@@ -456,4 +465,4 @@
#undef BLAST_DOOR_CRUSH_DAMAGE #undef BLAST_DOOR_CRUSH_DAMAGE
#undef SHUTTER_CRUSH_DAMAGE #undef SHUTTER_CRUSH_DAMAGE

View File

@@ -81,31 +81,6 @@
frame_class = FRAME_CLASS_MACHINE frame_class = FRAME_CLASS_MACHINE
frame_size = 4 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 /datum/frame/frame_types/fax
name = "Fax" name = "Fax"
frame_class = FRAME_CLASS_MACHINE frame_class = FRAME_CLASS_MACHINE
@@ -221,7 +196,7 @@
frame_style = FRAME_STYLE_WALL frame_style = FRAME_STYLE_WALL
x_offset = 28 x_offset = 28
y_offset = 28 y_offset = 28
/datum/frame/frame_types/arfgs /datum/frame/frame_types/arfgs
name = "ARF Generator" name = "ARF Generator"
frame_class = FRAME_CLASS_MACHINE frame_class = FRAME_CLASS_MACHINE

View File

@@ -150,7 +150,7 @@ Transponder Codes:<UL>"}
usr.set_machine(src) usr.set_machine(src)
if(href_list["locedit"]) if(href_list["locedit"])
var/newloc = sanitize(tgui_input_text(usr, "Enter New Location", "Navigation Beacon", location)) var/newloc = sanitize(tgui_input_text(usr, "Enter New Location", "Navigation Beacon", location, MAX_NAME_LEN))
if(newloc) if(newloc)
location = newloc location = newloc
updateDialog() updateDialog()
@@ -158,12 +158,14 @@ Transponder Codes:<UL>"}
else if(href_list["edit"]) else if(href_list["edit"])
var/codekey = href_list["code"] var/codekey = href_list["code"]
var/newkey = tgui_input_text(usr, "Enter Transponder Code Key", "Navigation Beacon", codekey) var/newkey = tgui_input_text(usr, "Enter Transponder Code Key", "Navigation Beacon", codekey, MAX_NAME_LEN)
newkey = sanitize(newkey,MAX_NAME_LEN)
if(!newkey) if(!newkey)
return return
var/codeval = codes[codekey] var/codeval = codes[codekey]
var/newval = tgui_input_text(usr, "Enter Transponder Code Value", "Navigation Beacon", codeval) var/newval = tgui_input_text(usr, "Enter Transponder Code Value", "Navigation Beacon", codeval, MAX_NAME_LEN)
newval = sanitize(newval,MAX_NAME_LEN)
if(!newval) if(!newval)
newval = codekey newval = codekey
return return
@@ -180,11 +182,13 @@ Transponder Codes:<UL>"}
else if(href_list["add"]) else if(href_list["add"])
var/newkey = tgui_input_text(usr, "Enter New Transponder Code Key", "Navigation Beacon") var/newkey = tgui_input_text(usr, "Enter New Transponder Code Key", "Navigation Beacon", null, MAX_NAME_LEN)
newkey = sanitize(newkey,MAX_NAME_LEN)
if(!newkey) if(!newkey)
return return
var/newval = tgui_input_text(usr, "Enter New Transponder Code Value", "Navigation Beacon") var/newval = tgui_input_text(usr, "Enter New Transponder Code Value", "Navigation Beacon", null, MAX_NAME_LEN)
newval = sanitize(newval,MAX_NAME_LEN)
if(!newval) if(!newval)
newval = "1" newval = "1"
return return

View File

@@ -10,6 +10,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
/obj/machinery/pointdefense_control /obj/machinery/pointdefense_control
name = "fire assist mainframe" name = "fire assist mainframe"
desc = "A specialized computer designed to synchronize a variety of weapon systems and a vessel's astronav data." desc = "A specialized computer designed to synchronize a variety of weapon systems and a vessel's astronav data."
description_info = "To connect the mainframe to turrets, use a multitool to set the ident tag to that of the turrets."
icon = 'icons/obj/pointdefense.dmi' icon = 'icons/obj/pointdefense.dmi'
icon_state = "control" icon_state = "control"
power_channel = EQUIP // CHOMPStation Edit Starts power_channel = EQUIP // CHOMPStation Edit Starts
@@ -97,7 +98,8 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
/obj/machinery/pointdefense_control/attackby(var/obj/item/W, var/mob/user) /obj/machinery/pointdefense_control/attackby(var/obj/item/W, var/mob/user)
if(W?.is_multitool()) if(W?.is_multitool())
var/new_ident = tgui_input_text(user, "Enter a new ident tag.", "[src]", id_tag) var/new_ident = tgui_input_text(user, "Enter a new ident tag.", "[src]", id_tag, MAX_NAME_LEN)
new_ident = sanitize(new_ident,MAX_NAME_LEN)
if(new_ident && new_ident != id_tag && user.Adjacent(src) && CanInteract(user, GLOB.tgui_physical_state)) if(new_ident && new_ident != id_tag && user.Adjacent(src) && CanInteract(user, GLOB.tgui_physical_state))
// Check for duplicate controllers with this ID // Check for duplicate controllers with this ID
for(var/obj/machinery/pointdefense_control/PC as anything in GLOB.pointdefense_controllers) for(var/obj/machinery/pointdefense_control/PC as anything in GLOB.pointdefense_controllers)
@@ -125,7 +127,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
icon = 'icons/obj/pointdefense.dmi' icon = 'icons/obj/pointdefense.dmi'
icon_state = "pointdefense2" icon_state = "pointdefense2"
desc = "A Kuiper pattern anti-meteor battery. Capable of destroying most threats in a single salvo." desc = "A Kuiper pattern anti-meteor battery. Capable of destroying most threats in a single salvo."
description_info = "Must have the same ident tag as a fire assist mainframe on the same facility." description_info = "Must have the same ident tag as a fire assist mainframe on the same facility. Use a multitool to set the ident tag."
density = TRUE density = TRUE
anchored = TRUE anchored = TRUE
circuit = /obj/item/weapon/circuitboard/pointdefense circuit = /obj/item/weapon/circuitboard/pointdefense
@@ -137,7 +139,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
var/last_shot = 0 var/last_shot = 0
var/kill_range = 18 var/kill_range = 18
var/rotation_speed = 4.5 SECONDS //How quickly we turn to face threats var/rotation_speed = 4.5 SECONDS //How quickly we turn to face threats
var/engaging = FALSE var/weakref/engaging = null // The meteor we're shooting at
var/id_tag = null var/id_tag = null
/obj/machinery/pointdefense/Initialize() /obj/machinery/pointdefense/Initialize()
@@ -146,17 +148,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
if(ispath(circuit)) if(ispath(circuit))
circuit = new circuit(src) circuit = new circuit(src)
default_apply_parts() default_apply_parts()
// if(anchored)
// connect_to_network()
update_icon() update_icon()
var/image/I = image(icon, icon_state = "[icon_state]_under")
I.appearance_flags |= RESET_TRANSFORM
underlays += I
// /obj/machinery/pointdefense/examine(mob/user)
// . = ..()
// if(powernet)
// . += "It is connected to a power cable below."
/obj/machinery/pointdefense/get_description_interaction() /obj/machinery/pointdefense/get_description_interaction()
. = ..() . = ..()
@@ -169,38 +161,12 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
else else
icon_state = initial(icon_state) icon_state = initial(icon_state)
/obj/machinery/pointdefense/default_unfasten_wrench(var/mob/user, var/obj/item/weapon/W, var/time)
if((. = ..()))
src.transform = null // Reset rotation if we're anchored/unanchored
////////// This machine is willing to take power from cables OR APCs. Handle NOPOWER stat specially here! ////////
/*
/obj/machinery/pointdefense/connect_to_network()
if((. = ..()))
stat &= ~NOPOWER // We now ignore APC power
update_icon()
/obj/machinery/pointdefense/disconnect_from_network()
if((. = ..()))
power_change() // We're back on APC power.
/obj/machinery/pointdefense/power_change() /obj/machinery/pointdefense/power_change()
if(powernet)
return // We don't care, we are cable powered anyway
var/old_stat = stat var/old_stat = stat
..() ..()
if(old_stat != stat) if(old_stat != stat)
update_icon() update_icon()
// Decide where to get the power to fire from
/obj/machinery/pointdefense/use_power_oneoff(var/amount, var/chan = -1)
if(powernet)
return draw_power(amount)
else if(powered(chan))
use_power(amount, chan)
return amount
return 0 */
// Find controller with the same tag on connected z levels (if any) // Find controller with the same tag on connected z levels (if any)
/obj/machinery/pointdefense/proc/get_controller() /obj/machinery/pointdefense/proc/get_controller()
if(!id_tag) if(!id_tag)
@@ -212,7 +178,8 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
/obj/machinery/pointdefense/attackby(var/obj/item/W, var/mob/user) /obj/machinery/pointdefense/attackby(var/obj/item/W, var/mob/user)
if(W?.is_multitool()) if(W?.is_multitool())
var/new_ident = tgui_input_text(user, "Enter a new ident tag.", "[src]", id_tag) var/new_ident = tgui_input_text(user, "Enter a new ident tag.", "[src]", id_tag, MAX_NAME_LEN)
new_ident = sanitize(new_ident,MAX_NAME_LEN)
if(new_ident && new_ident != id_tag && user.Adjacent(src) && CanInteract(user, GLOB.tgui_physical_state)) if(new_ident && new_ident != id_tag && user.Adjacent(src) && CanInteract(user, GLOB.tgui_physical_state))
to_chat(user, "<span class='notice'>You register [src] with the [new_ident] network.</span>") to_chat(user, "<span class='notice'>You register [src] with the [new_ident] network.</span>")
id_tag = new_ident id_tag = new_ident
@@ -223,8 +190,6 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
return return
if(default_part_replacement(user, W)) if(default_part_replacement(user, W))
return return
if(default_unfasten_wrench(user, W, 40))
return
return ..() return ..()
//Guns cannot shoot through hull or generally dense turfs. //Guns cannot shoot through hull or generally dense turfs.
@@ -237,8 +202,9 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
/obj/machinery/pointdefense/proc/Shoot(var/weakref/target) /obj/machinery/pointdefense/proc/Shoot(var/weakref/target)
var/obj/effect/meteor/M = target.resolve() var/obj/effect/meteor/M = target.resolve()
if(!istype(M)) if(!istype(M))
engaging = null
return return
engaging = TRUE engaging = target
var/Angle = round(Get_Angle(src,M)) var/Angle = round(Get_Angle(src,M))
var/matrix/rot_matrix = matrix() var/matrix/rot_matrix = matrix()
rot_matrix.Turn(Angle) rot_matrix.Turn(Angle)
@@ -248,47 +214,38 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
set_dir(ATAN2(transform.b, transform.a) > 0 ? NORTH : SOUTH) set_dir(ATAN2(transform.b, transform.a) > 0 ? NORTH : SOUTH)
/obj/machinery/pointdefense/proc/finish_shot(var/weakref/target) /obj/machinery/pointdefense/proc/finish_shot(var/weakref/target)
//Cleanup from list
var/obj/machinery/pointdefense_control/PC = get_controller() var/obj/machinery/pointdefense_control/PC = get_controller()
if(istype(PC)) engaging = null
PC.targets -= target PC.targets -= target
engaging = FALSE
last_shot = world.time last_shot = world.time
var/obj/effect/meteor/M = target.resolve() var/obj/effect/meteor/M = target.resolve()
if(!istype(M)) if(!istype(M))
return return
/*if(use_power_oneoff(active_power_usage) < active_power_usage)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
visible_message("[src] sputters as browns out while attempting to fire.")
flick(src, "[initial(icon_state)]_off")
return */
//We throw a laser but it doesnt have to hit for meteor to explode //We throw a laser but it doesnt have to hit for meteor to explode
var/obj/item/projectile/beam/pointdefense/beam = new(get_turf(src)) var/obj/item/projectile/beam/pointdefense/beam = new(get_turf(src))
playsound(src, 'sound/weapons/mandalorian.ogg', 75, 1) playsound(src, 'sound/weapons/mandalorian.ogg', 75, 1)
use_power_oneoff(idle_power_usage * 10)
beam.launch_projectile(target = M.loc, user = src) beam.launch_projectile(target = M.loc, user = src)
M.make_debris()
qdel(M)
/obj/machinery/pointdefense/process() /obj/machinery/pointdefense/process()
..() ..()
if(!anchored || stat & (BROKEN)) if(stat & (BROKEN))
return return
if(!active) if(!active)
return return
/*
var/desiredir = ATAN2(transform.b, transform.a) > 0 ? NORTH : SOUTH var/desiredir = ATAN2(transform.b, transform.a) > 0 ? NORTH : SOUTH
if(dir != desiredir) if(dir != desiredir)
set_dir(desiredir) set_dir(desiredir)
*/
if(LAZYLEN(GLOB.meteor_list) > 0) if(LAZYLEN(GLOB.meteor_list) > 0)
find_and_shoot() find_and_shoot()
/obj/machinery/pointdefense/proc/find_and_shoot() /obj/machinery/pointdefense/proc/find_and_shoot()
// There ARE meteors to shoot
if(LAZYLEN(GLOB.meteor_list) == 0) if(LAZYLEN(GLOB.meteor_list) == 0)
return return
// We can shoot
if(engaging || ((world.time - last_shot) < charge_cooldown)) if(engaging || ((world.time - last_shot) < charge_cooldown))
return return
@@ -296,29 +253,42 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
if(!istype(PC) || !PC.powered(EQUIP)) if(!istype(PC) || !PC.powered(EQUIP))
return return
var/list/connected_z_levels = GetConnectedZlevels(get_z(src)) // Compile list of known targets
for(var/obj/effect/meteor/M in GLOB.meteor_list) var/list/existing_targets = list()
var/already_targeted = FALSE for(var/weakref/WR in PC.targets)
for(var/weakref/WR in PC.targets) var/obj/effect/meteor/M = WR.resolve()
var/obj/effect/meteor/m = WR.resolve() existing_targets += M
if(m == M)
already_targeted = TRUE
break
if(!istype(m))
PC.targets -= WR
if(already_targeted) // First, try and acquire new targets
continue var/list/potential_targets = GLOB.meteor_list.Copy() - existing_targets
for(var/obj/effect/meteor/M in potential_targets)
if(!(M.z in connected_z_levels)) if(targeting_check(M))
continue
if(get_dist(M, src) > kill_range)
continue
if(!emagged && space_los(M))
var/weakref/target = weakref(M) var/weakref/target = weakref(M)
PC.targets += target PC.targets += target
engaging = target
Shoot(target) Shoot(target)
return return
// Then, focus fire on existing targets
for(var/obj/effect/meteor/M in existing_targets)
if(targeting_check(M))
var/weakref/target = weakref(M)
engaging = target
Shoot(target)
return
/obj/machinery/pointdefense/proc/targeting_check(var/obj/effect/meteor/M)
// Target in range
var/list/connected_z_levels = GetConnectedZlevels(get_z(src))
if(!(M.z in connected_z_levels))
return FALSE
if(get_dist(M, src) > kill_range)
return FALSE
// If we can shoot it, then shoot
if(emagged || !space_los(M))
return FALSE
return TRUE
/obj/machinery/pointdefense/RefreshParts() /obj/machinery/pointdefense/RefreshParts()
. = ..() . = ..()
@@ -354,32 +324,3 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
active = FALSE active = FALSE
update_icon() update_icon()
return TRUE return TRUE
//
// Projectile Beam Definitions
//
/obj/item/projectile/beam/pointdefense
name = "point defense salvo"
icon_state = "laser"
damage = 15
damage_type = ELECTROCUTE //You should be safe inside a voidsuit
sharp = FALSE //"Wide" spectrum beam
light_color = COLOR_GOLD
muzzle_type = /obj/effect/projectile/muzzle/pointdefense
tracer_type = /obj/effect/projectile/tracer/pointdefense
impact_type = /obj/effect/projectile/impact/pointdefense
/obj/effect/projectile/tracer/pointdefense
icon = 'icons/obj/projectiles_vr.dmi'
icon_state = "beam_pointdef"
/obj/effect/projectile/muzzle/pointdefense
icon = 'icons/obj/projectiles_vr.dmi'
icon_state = "muzzle_pointdef"
/obj/effect/projectile/impact/pointdefense
icon = 'icons/obj/projectiles_vr.dmi'
icon_state = "impact_pointdef"

View File

@@ -903,7 +903,6 @@
var/check_weapons var/check_weapons
var/check_anomalies var/check_anomalies
var/check_all var/check_all
var/check_down
var/ailock var/ailock
/obj/machinery/porta_turret/proc/setState(var/datum/turret_checks/TC) /obj/machinery/porta_turret/proc/setState(var/datum/turret_checks/TC)
@@ -919,7 +918,6 @@
check_weapons = TC.check_weapons check_weapons = TC.check_weapons
check_anomalies = TC.check_anomalies check_anomalies = TC.check_anomalies
check_all = TC.check_all check_all = TC.check_all
check_down = TC.check_down
ailock = TC.ailock ailock = TC.ailock
power_change() power_change()

View File

@@ -10,7 +10,7 @@
active_power_usage = 40000 //40 kW active_power_usage = 40000 //40 kW
var/efficiency = 40000 //will provide the modified power rate when upgraded var/efficiency = 40000 //will provide the modified power rate when upgraded
var/obj/item/charging = null var/obj/item/charging = null
var/list/allowed_devices = list(/obj/item/weapon/gun/energy, /obj/item/weapon/melee/baton, /obj/item/modular_computer, /obj/item/weapon/computer_hardware/battery_module, /obj/item/weapon/cell, /obj/item/device/suit_cooling_unit/emergency, /obj/item/device/flashlight, /obj/item/device/electronic_assembly, /obj/item/weapon/weldingtool/electric, /obj/item/ammo_magazine/smart, /obj/item/device/flash, /obj/item/device/defib_kit, /obj/item/ammo_casing/microbattery, /obj/item/device/paicard, /obj/item/ammo_magazine/cell_mag, /obj/item/weapon/gun/projectile/cell_loaded) // CHOMPedit: medigun stuff var/list/allowed_devices = list(/obj/item/weapon/gun/energy, /obj/item/weapon/melee/baton, /obj/item/modular_computer, /obj/item/weapon/computer_hardware/battery_module, /obj/item/weapon/cell, /obj/item/device/suit_cooling_unit/emergency, /obj/item/device/flashlight, /obj/item/device/electronic_assembly, /obj/item/weapon/weldingtool/electric, /obj/item/ammo_magazine/smart, /obj/item/device/flash, /obj/item/device/defib_kit, /obj/item/ammo_casing/microbattery, /obj/item/device/paicard, /obj/item/ammo_magazine/cell_mag, /obj/item/weapon/gun/projectile/cell_loaded, /obj/item/device/personal_shield_generator) // CHOMPedit: medigun stuff
var/icon_state_charged = "recharger2" var/icon_state_charged = "recharger2"
var/icon_state_charging = "recharger1" var/icon_state_charging = "recharger1"
var/icon_state_idle = "recharger0" //also when unpowered var/icon_state_idle = "recharger0" //also when unpowered
@@ -28,7 +28,8 @@
. += "[charging ? "[charging]" : "Nothing"] is in [src]." . += "[charging ? "[charging]" : "Nothing"] is in [src]."
if(charging) if(charging)
var/obj/item/weapon/cell/C = charging.get_cell() var/obj/item/weapon/cell/C = charging.get_cell()
. += "Current charge: [C.charge] / [C.maxcharge]" if(C) // Sometimes we get things without cells in it.
. += "Current charge: [C.charge] / [C.maxcharge]"
/obj/machinery/recharger/attackby(obj/item/weapon/G as obj, mob/user as mob) /obj/machinery/recharger/attackby(obj/item/weapon/G as obj, mob/user as mob)
var/allowed = 0 var/allowed = 0

View File

@@ -100,12 +100,13 @@
// Also recharge their internal battery. // Also recharge their internal battery.
if(H.isSynthetic() && H.nutrition < 500) //VOREStation Edit if(H.isSynthetic() && H.nutrition < 500) //VOREStation Edit
H.nutrition = min(H.nutrition+10, 500) //VOREStation Edit H.nutrition = min(H.nutrition+(10*(1-H.species.synthetic_food_coeff)), 500) //VOREStation Edit
cell.use(7000/450*10) cell.use(7000/450*10)
// And clear up radiation // And clear up radiation
if(H.radiation > 0) if(H.radiation > 0 || H.accumulated_rads > 0)
H.radiation = max(H.radiation - rand(5, 15), 0) H.radiation = max(H.radiation - 25, 0)
H.accumulated_rads = max(H.accumulated_rads - 25, 0)
if(H.wearing_rig) // stepping into a borg charger to charge your rig and fix your shit if(H.wearing_rig) // stepping into a borg charger to charge your rig and fix your shit
var/obj/item/weapon/rig/wornrig = H.get_rig() var/obj/item/weapon/rig/wornrig = H.get_rig()

View File

@@ -46,7 +46,7 @@
for(var/c in SelectedServer.log_entries) for(var/c in SelectedServer.log_entries)
i++ i++
var/datum/comm_log_entry/C = c var/datum/comm_log_entry/C = c
// This is necessary to prevent leaking information to the clientside // This is necessary to prevent leaking information to the clientside
var/static/list/acceptable_params = list("uspeech", "intelligible", "message", "name", "race", "job", "timecode") var/static/list/acceptable_params = list("uspeech", "intelligible", "message", "name", "race", "job", "timecode")
var/list/parameters = list() var/list/parameters = list()
@@ -74,7 +74,7 @@
if(!ui) if(!ui)
ui = new(user, src, "TelecommsLogBrowser", name) ui = new(user, src, "TelecommsLogBrowser", name)
ui.open() ui.open()
/obj/machinery/computer/telecomms/server/tgui_act(action, params) /obj/machinery/computer/telecomms/server/tgui_act(action, params)
if(..()) if(..())
return TRUE return TRUE
@@ -128,7 +128,8 @@
. = TRUE . = TRUE
if("network") if("network")
var/newnet = tgui_input_text(usr, "Which network do you want to view?", "Comm Monitor", network) var/newnet = tgui_input_text(usr, "Which network do you want to view?", "Comm Monitor", network, 15)
newnet = sanitize(newnet,15)
if(newnet && ((usr in range(1, src) || issilicon(usr)))) if(newnet && ((usr in range(1, src) || issilicon(usr))))
if(length(newnet) > 15) if(length(newnet) > 15)
@@ -139,7 +140,7 @@
set_temp("NEW NETWORK TAG SET IN ADDRESS \[[network]\]", "good") set_temp("NEW NETWORK TAG SET IN ADDRESS \[[network]\]", "good")
. = TRUE . = TRUE
if("cleartemp") if("cleartemp")
temp = null temp = null
. = TRUE . = TRUE

View File

@@ -41,7 +41,7 @@
/obj/machinery/telecomms/tgui_data(mob/user) /obj/machinery/telecomms/tgui_data(mob/user)
var/list/data = list() var/list/data = list()
data["temp"] = temp data["temp"] = temp
data["on"] = on data["on"] = on
@@ -81,7 +81,7 @@
"index" = i, "index" = i,
))) )))
data["linked"] = linked data["linked"] = linked
var/list/filter = list() var/list/filter = list()
for(var/x in freq_listening) for(var/x in freq_listening)
filter.Add(list(list( filter.Add(list(list(
@@ -213,7 +213,7 @@
/obj/machinery/telecomms/bus/Options_Act(action, params) /obj/machinery/telecomms/bus/Options_Act(action, params)
if(..()) if(..())
return TRUE return TRUE
switch(action) switch(action)
if("change_freq") if("change_freq")
. = TRUE . = TRUE
@@ -267,7 +267,7 @@
/obj/machinery/telecomms/receiver/Options_Act(action, params) /obj/machinery/telecomms/receiver/Options_Act(action, params)
if(..()) if(..())
return TRUE return TRUE
switch(action) switch(action)
if("range") if("range")
var/new_range = params["range"] var/new_range = params["range"]
@@ -296,6 +296,7 @@
if("network") if("network")
var/newnet = tgui_input_text(usr, "Specify the new network for this machine. This will break all current links.", src, network) var/newnet = tgui_input_text(usr, "Specify the new network for this machine. This will break all current links.", src, network)
newnet = sanitize(newnet,15)
if(newnet && canAccess(usr)) if(newnet && canAccess(usr))
if(length(newnet) > 15) if(length(newnet) > 15)

View File

@@ -100,7 +100,8 @@
. = TRUE . = TRUE
if("network") if("network")
var/newnet = tgui_input_text(usr, "Which network do you want to view?", "Comm Monitor", network) var/newnet = tgui_input_text(usr, "Which network do you want to view?", "Comm Monitor", network, 15)
newnet = sanitize(newnet,15) //Honestly, I'd be amazed if someone managed to do HTML in 15 chars.
if(newnet && ((usr in range(1, src) || issilicon(usr)))) if(newnet && ((usr in range(1, src) || issilicon(usr))))
if(length(newnet) > 15) if(length(newnet) > 15)
set_temp("FAILED: NETWORK TAG STRING TOO LENGTHY", "bad") set_temp("FAILED: NETWORK TAG STRING TOO LENGTHY", "bad")
@@ -108,7 +109,7 @@
network = newnet network = newnet
machinelist = list() machinelist = list()
set_temp("NEW NETWORK TAG SET IN ADDRESS \[[network]\]", "good") set_temp("NEW NETWORK TAG SET IN ADDRESS \[[network]\]", "good")
. = TRUE . = TRUE
if("cleartemp") if("cleartemp")

View File

@@ -192,7 +192,8 @@
if(href_list["network"]) if(href_list["network"])
var/newnet = tgui_input_text(usr, "Which network do you want to view?", "Comm Monitor", network) var/newnet = tgui_input_text(usr, "Which network do you want to view?", "Comm Monitor", network, 15)
newnet = sanitize(newnet,15)
if(newnet && ((usr in range(1, src) || issilicon(usr)))) if(newnet && ((usr in range(1, src) || issilicon(usr))))
if(length(newnet) > 15) if(length(newnet) > 15)

View File

@@ -194,7 +194,6 @@
TC.check_weapons = check_weapons TC.check_weapons = check_weapons
TC.check_anomalies = check_anomalies TC.check_anomalies = check_anomalies
TC.check_all = check_all TC.check_all = check_all
TC.check_down = check_down
TC.ailock = ailock TC.ailock = ailock
if(istype(control_area)) if(istype(control_area))

View File

@@ -48,7 +48,8 @@
if(ore_box) if(ore_box)
for(var/obj/item/weapon/ore/ore in range(chassis,1)) for(var/obj/item/weapon/ore/ore in range(chassis,1))
if(get_dir(chassis,ore)&chassis.dir) if(get_dir(chassis,ore)&chassis.dir)
ore.forceMove(ore_box) ore_box.stored_ore[ore.material]++
qdel(ore)
else if(isliving(target)) else if(isliving(target))
drill_mob(target, chassis.occupant) drill_mob(target, chassis.occupant)
return 1 return 1

View File

@@ -38,7 +38,8 @@
if(ore_box) if(ore_box)
for(var/obj/item/weapon/ore/ore in range(1, src)) for(var/obj/item/weapon/ore/ore in range(1, src))
if(ore.Adjacent(src) && ((get_dir(src, ore) & dir) || ore.loc == loc)) //we can reach it and it's in front of us? grab it! if(ore.Adjacent(src) && ((get_dir(src, ore) & dir) || ore.loc == loc)) //we can reach it and it's in front of us? grab it!
ore.forceMove(ore_box) ore_box.stored_ore[ore.material]++
qdel(ore)
/obj/mecha/working/ripley/Destroy() /obj/mecha/working/ripley/Destroy()
for(var/atom/movable/A in src.cargo) for(var/atom/movable/A in src.cargo)

View File

@@ -31,6 +31,12 @@
desc = "A banner with the symbol of the Solar Confederate Government." desc = "A banner with the symbol of the Solar Confederate Government."
catalogue_data = list(/datum/category_item/catalogue/information/organization/solgov) catalogue_data = list(/datum/category_item/catalogue/information/organization/solgov)
/obj/item/weapon/banner/altevian
name = "\improper Altevian Hegemony Banner"
icon_state = "banner-altevian"
desc = "A banner that flies for the pride of the hegemony."
//catalogue_data = list(/datum/category_item/catalogue/information/organization/altevian_hegemony) // TODO?
//VOREStation Removal //CHOMP re-addition. Seriously? You commented this out for your lore? What's wrong with JUST NOT SPAWNING IT or something. //VOREStation Removal //CHOMP re-addition. Seriously? You commented this out for your lore? What's wrong with JUST NOT SPAWNING IT or something.
/obj/item/weapon/banner/virgov /obj/item/weapon/banner/virgov
name = "\improper VirGov banner" name = "\improper VirGov banner"

View File

@@ -25,4 +25,4 @@
C.name = name C.name = name
qdel(src) return INITIALIZE_HINT_QDEL

View File

@@ -24,6 +24,18 @@
icon_state = "smoke" icon_state = "smoke"
duration = 50 duration = 50
/obj/effect/temp_visual/glitch
icon_state = "glitch"
duration = 5
/obj/effect/temp_visual/confuse
icon_state = "confuse"
duration = 5
/obj/effect/temp_visual/pre_confuse
icon_state = "pre_confuse"
duration = 5
/obj/effect/temp_visual/impact_effect /obj/effect/temp_visual/impact_effect
icon_state = "impact_bullet" icon_state = "impact_bullet"
plane = PLANE_LIGHTING_ABOVE // So they're visible even in a shootout in maint. plane = PLANE_LIGHTING_ABOVE // So they're visible even in a shootout in maint.

View File

@@ -94,4 +94,6 @@
light_range = 2 light_range = 2
light_power = 0.5 light_power = 0.5
light_color = "#80F5FF" light_color = "#80F5FF"
//VOREStation edit ends //VOREStation edit ends
/obj/effect/projectile/impact/pointdefense
icon_state = "impact_pointdef"

View File

@@ -106,4 +106,6 @@
light_range = 2 light_range = 2
light_power = 0.5 light_power = 0.5
light_color = "#80F5FF" light_color = "#80F5FF"
//VOREStation edit ends //VOREStation edit ends
/obj/effect/projectile/muzzle/pointdefense
icon_state = "muzzle_pointdef"

View File

@@ -134,3 +134,5 @@
light_power = 0.5 light_power = 0.5
light_color = "#80F5FF" light_color = "#80F5FF"
//VOREStation edit ends //VOREStation edit ends
/obj/effect/projectile/tracer/pointdefense
icon_state = "beam_pointdef"

View File

@@ -106,7 +106,7 @@
var/drop_sound = "generic_drop" var/drop_sound = "generic_drop"
var/tip_timer // reference to timer id for a tooltip we might open soon var/tip_timer // reference to timer id for a tooltip we might open soon
var/no_random_knockdown = FALSE //stops item from being able to randomly knock people down in combat var/no_random_knockdown = FALSE //stops item from being able to randomly knock people down in combat
/obj/item/Initialize(mapload) //CHOMPedit I stg I'm going to overwrite these many uncommented edits. /obj/item/Initialize(mapload) //CHOMPedit I stg I'm going to overwrite these many uncommented edits.
@@ -222,9 +222,12 @@
/obj/item/attack_hand(mob/living/user as mob) /obj/item/attack_hand(mob/living/user as mob)
if (!user) return if (!user) return
if(anchored) if(anchored) // Start CHOMPStation Edit
to_chat(user, span("notice", "\The [src] won't budge, you can't pick it up!")) if(hascall(src, "attack_self"))
return return src.attack_self(user)
else
to_chat ("This is anchored and you can't lift it.")
return // End CHOMPStation Edit
if (hasorgans(user)) if (hasorgans(user))
var/mob/living/carbon/human/H = user var/mob/living/carbon/human/H = user
var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] var/obj/item/organ/external/temp = H.organs_by_name["r_hand"]

View File

@@ -0,0 +1,940 @@
#define BP_MAX_ROOM_SIZE 300
// WARNING: ESOTERIC BULLSHIT INSIDE OF THIS FILE.
// This is a port of /tg/'s blueprints that also have Virgo modifications as well.
// However it is heavily modified and lacking the 't-ray' scanner functionality that /TG/ has. We have our own t-rays after all.
// This works and uses a bunch of really odd hacks and trickery to get it to all function.
// If you're looking at this a few years from now and going 'What the hell were they thinking' just know that this was the best we had at the time.
// Now that I've scared away half the people looking at this file, here's the relevant info:
// Banning areas: Go to global_lists_vr, jump to the BUILDABLE_AREA_TYPES and read the comments left there.
// These areas are defined here so they can be blacklisted in global_lists_vr
/area/tether/elevator
name = "Tether Elevator"
/area/tether/surfacebase/outside
name = "Outside - Surface"
/area/groundbase/unexplored/outdoors
name = "\improper Rascal's Pass"
/area/groundbase/mining
name = "Mining"
/area/groundbase/unexplored/rock
name = "\improper Rascal's Pass"
/area/maintenance/groundbase/level1
name = "Groundbase Level One Maint"
/area/submap/groundbase/wilderness
name = "Groundbase Wilderness"
/area/offmap/aerostat/surface
name = "Aerostat Surface"
/area/tether_away/beach
name = "\improper Away Mission - Virgo 4 Beach"
/area/tether_away/cave
name = "Tether Away Cave"
/area/offmap/aerostat/surface
name = "Aerostat Surface"
/area/submap/virgo2
name = "Submap Area"
/area/submap/casino_event
name = "\improper Space Casino"
//TG blueprints.
#define AREA_ERRNONE 0
#define AREA_STATION 1
#define AREA_SPACE 2
#define AREA_SPECIAL 3
/obj/item/areaeditor
name = "area modification item"
icon = 'icons/obj/items.dmi'
icon_state = "blueprints"
attack_verb = list("attacked", "bapped", "hit")
in_use = FALSE
preserve_item = 1
var/uses_charges = 0 // If the area editor has limited uses.
var/initial_charges = 10
var/charges = 10 // The amount of uses the area editor has.
var/station_master = 1 // If the areaeditor can add charges to others.
var/wire_schematics = 0 // If the areaeditor can see wires.
var/can_override = 0 // If you want the areaeditor to override the 'Don't make a new area where one already exists' logic. Only given to CE blueprints.
var/can_create_areas_in = AREA_SPACE // Must be standing in space to create
var/can_create_areas_into = AREA_SPACE // New areas will only overwrite space area turfs.
var/can_expand_areas_in = AREA_STATION // Must be standing in station to expand
var/can_expand_areas_into = AREA_SPACE // Can expand station areas only into space.
var/can_rename_areas_in = AREA_STATION // Only station areas can be reanamed
var/const/ROOM_ERR_LOLWAT = 0 // Don't touch these three consts or BYOND will literally tear out your throat
var/const/ROOM_ERR_SPACE = -1
var/const/ROOM_ERR_TOOLARGE = -2
var/const/ROOM_ERR_FORBIDDEN = -3
var/list/areaColor_turfs = list()
var/legend = 0 //If viewing wires or not.
/obj/item/areaeditor/examine(mob/user)
. =..()
if(uses_charges && !isnull(charges))
. += "There appears to be enough space for a total of [charges] more changes!"
if(!charges)
. += "There seems to be no more room for any more edits!"
/obj/item/areaeditor/attackby(obj/item/W, mob/user, params)
if(uses_charges && (charges < initial_charges) && istype(W, /obj/item/areaeditor)) //Do we have a reason to add charges? And is it something that COULD add charges?
var/missing_charges = initial_charges-charges
var/obj/item/areaeditor/blueprint = W
if(blueprint.station_master) //Master can refill.
charges = initial_charges
to_chat(user, span_notice("You add some more writing material to the [src] with the [blueprint]!"))
return
else if(blueprint.uses_charges && blueprint.charges) //Getting from another with limited charges.
var/to_add = tgui_input_number(user, "How many charges do you want to add to the [src]?", "[blueprint]", missing_charges)
if(!isnull(to_add) && blueprint.charges >= to_add)
to_chat(user, span_notice("You add some more writing material to the [src] with the [blueprint]!"))
blueprint.charges -= to_add
charges += to_add
return
else
to_chat(user, span_notice("You decide not to add any more material to the [src]"))
return
else if(!blueprint.uses_charges || !blueprint.charges) // The item it's being hit by doesn't use charges OR doesn't have any charges.
to_chat(user, span_warning("You can't add find any suitable material to add from the [blueprint]!"))
else
..()
/obj/item/areaeditor/attack_self(mob/user) //Convert this to TGUI some time.
add_fingerprint(user)
. = "<BODY><HTML><head><title>[src]</title></head> \
<h2>[station_name()] [src.name]</h2>"
switch(get_area_type())
if(AREA_SPACE)
. += "<p>According to the [src.name], you are now in an unclaimed territory.</p>"
if(AREA_SPECIAL)
. += "<p>This place is not noted on the [src.name].</p>"
return //If we're in a special area, no modifying.
if(!uses_charges || (uses_charges && charges)) //No charges OR it has charges available.
. += "<p><a href='?src=[REF(src)];create_area=1'>Create or modify an existing area (3x3 space) (1 Charge)</a></p>"
. += "<p><a href='?src=[REF(src)];create_area_whole=1'>Create new area or merge two areas. (Whole Room.) (5 Charges)</a></p>"
. += "There is a note on the corner of the [src.name]: Use 3x3 for fine-tuning and including walls into your area!"
if(uses_charges)
if(!charges) //We're out!
. += "Your [src.name] has been completely filled! You would need to get some extra blueprint paper from the CE's blueprints to expand further!"
else
. += "Your [src.name] seems like it has enough room for [charges] more edits!"
/obj/item/areaeditor/Topic(href, href_list)
if(..())
return TRUE
if ((usr.restrained() || usr.stat || usr.get_active_hand() != src))
return
if(href_list["create_area"])
if(in_use)
return
var/area/A = get_area(usr)
if(A.flags & BLUE_SHIELDED)
to_chat(usr, span_warning("You cannot edit restricted areas."))
return
in_use = TRUE
create_area(usr, src)
in_use = FALSE
if(href_list["create_area_whole"])
if(in_use)
return
in_use = TRUE
var/area/A = create_area_whole(usr, src)
if(A && (A.flags & BLUE_SHIELDED))
to_chat(usr, span_warning("You cannot edit restricted areas."))
in_use = FALSE
return
in_use = FALSE
updateUsrDialog()
//Station Wire Tool.
/obj/item/wire_reader //Not really a blueprint, but it's included here as such.
name = "wire schematics"
desc = "A blueprint detailing the various internal wiring of machinery around the station."
icon = 'icons/obj/items.dmi'
icon_state = "blueprints"
attack_verb = list("attacked", "bapped", "hit")
preserve_item = 1
var/legend = 1
/obj/item/wire_reader/attack_self(mob/user) //Convert this to TGUI some time.
add_fingerprint(user)
. = "<BODY><HTML><head><title>[src]</title></head> \
<h2>[station_name()] [src.name]</h2>"
if(legend == TRUE)
. += view_station_wire_devices(user);
else
//legend is a wireset
. += "<a href='?src=[REF(src)];view_legend=1'><< Back</a>"
. += view_station_wire_set(user, legend)
var/datum/browser/popup = new(user, "blueprints", "[src]", 700, 500)
popup.set_content(.)
popup.open()
onclose(user, "blueprints")
/obj/item/wire_reader/Topic(href, href_list)
if(..())
return
if(href_list["view_wireset"])
legend = href_list["view_wireset"];
if(href_list["view_legend"])
legend = TRUE
attack_self(usr)
/obj/item/wire_reader/proc/view_station_wire_devices(mob/user)
var/message = "<br>You examine the wire legend.<br>"
for(var/wireset in GLOB.wire_color_directory)
//if(istype(wireset,/datum/wires/grid_checker))//Uncomment this in if you want the grid checker minigame to not be revealed here.
// continue
message += "<br><a href='?src=[REF(src)];view_wireset=[wireset]'>[GLOB.wire_name_directory[wireset]]</a>"
message += "</p>"
return message
/obj/item/wire_reader/proc/view_station_wire_set(mob/user, wireset)
//for some reason you can't use wireset directly as a derefencer so this is the next best :/
for(var/device in GLOB.wire_color_directory)
if("[device]" == wireset) //I know... don't change it...
var/message = "<p><b>[GLOB.wire_name_directory[device]]:</b>"
for(var/Col in GLOB.wire_color_directory[device])
var/wire_name = GLOB.wire_color_directory[device][Col]
if(!findtext(wire_name, WIRE_DUD_PREFIX)) //don't show duds
message += "<p><span style='color: [Col]'>[Col]</span>: [wire_name]</p>"
message += "</p>"
return message
return ""
//Station blueprints!!!
/obj/item/areaeditor/blueprints
name = "station blueprints"
desc = "Blueprints of the station. There is a \"Classified\" stamp and several coffee stains on it."
//var/list/image/showing = list() //For viewing pipes. Unused.
//var/client/viewing //For viewing pipes. Unused.
can_override = 1 //In case there is a reason for building in a non-blacklisted, non-buildable area.
/obj/item/areaeditor/blueprints/engineers
name = "writing blueprints"
desc = "A piece of paper that allows for expansion of the station and creaiton of new areas. There is a \"For Official Use Only\" stamp on it. NOT to be mistaken with the staion blueprints."
station_master = 0
uses_charges = 1
can_override = 0
/obj/item/areaeditor/blueprints/Destroy()
//clear_viewer()
return ..()
/obj/item/areaeditor/blueprints/attack_self(mob/user)
. = ..()
var/area/A = get_area(user)
if(!legend)
if(get_area_type() == AREA_STATION)
. += "<p>According to \the [src], you are now in <b>\"[html_encode(A.name)]\"</b>.</p>"
. += "<p><a href='?src=[REF(src)];edit_area=1'>Change area name</a></p>" //You can change the name without charges.
if(wire_schematics)
. += "<p><a href='?src=[REF(src)];view_legend=1'>View wire colour legend</a></p>"
else
if(legend == TRUE)
. += "<a href='?src=[REF(src)];exit_legend=1'><< Back</a>"
. += view_wire_devices(user);
else
//legend is a wireset
. += "<a href='?src=[REF(src)];view_legend=1'><< Back</a>"
. += view_wire_set(user, legend)
var/datum/browser/popup = new(user, "blueprints", "[src]", 700, 500)
popup.set_content(.)
popup.open()
onclose(user, "blueprints")
/obj/item/areaeditor/blueprints/Topic(href, href_list)
if(..())
return
if(href_list["edit_area"])
if(get_area_type()!=AREA_STATION)
return
if(in_use)
return
in_use = TRUE
edit_area()
in_use = FALSE
if(href_list["exit_legend"])
legend = FALSE;
if(href_list["view_legend"])
if(wire_schematics) //No href hacks allow for you, my friend!
legend = TRUE;
if(href_list["view_wireset"])
if(wire_schematics) //No href hacks allow for you, my friend!
legend = href_list["view_wireset"];
attack_self(usr)
//Code for viewing pipes or whatnot. Think t-ray scanner.
//Code for viewing pipes or whatnot. Think t-ray scanner.
//Code for viewing pipes or whatnot. Think t-ray scanner.
/*
/obj/item/areaeditor/blueprints/proc/get_images(turf/central_turf, viewsize)
. = list()
var/list/dimensions = getviewsize(viewsize)
var/horizontal_radius = dimensions[1] / 2
var/vertical_radius = dimensions[2] / 2
for(var/turf/nearby_turf as anything in RECT_TURFS(horizontal_radius, vertical_radius, central_turf))
if(nearby_turf.blueprint_data)
. += nearby_turf.blueprint_data
*/
/*
/obj/item/areaeditor/blueprints/proc/set_viewer(mob/user, message = "")
if(user?.client)
if(viewing)
clear_viewer()
viewing = user.client
showing = get_images(get_turf(viewing.eye || user), viewing.view)
viewing.images |= showing
if(message)
to_chat(user, message)
*/
/*
/obj/item/areaeditor/blueprints/proc/clear_viewer(mob/user, message = "")
if(viewing)
viewing.images -= showing
viewing = null
showing.Cut()
if(message)
to_chat(user, message)
*/
/obj/item/areaeditor/blueprints/dropped(mob/user)
..()
//clear_viewer()
if(areaColor_turfs.len)
seeAreaColors_remove()
legend = FALSE
/obj/item/areaeditor/proc/get_area_type(area/A)
if (!A)
A = get_area(usr)
if(A.outdoors)
return AREA_SPACE
for (var/type in BUILDABLE_AREA_TYPES)
if ( istype(A,type) )
return AREA_SPACE
for (var/type in SPECIALS)
if ( istype(A,type) )
return AREA_SPECIAL
return AREA_STATION
/obj/item/areaeditor/blueprints/proc/view_wire_devices(mob/user)
var/message = "<br>You examine the wire legend.<br>"
for(var/wireset in GLOB.wire_color_directory)
//if(istype(wireset,/datum/wires/grid_checker))//Uncomment this in if you want the grid checker minigame to not be revealed here.
// continue
message += "<br><a href='?src=[REF(src)];view_wireset=[wireset]'>[GLOB.wire_name_directory[wireset]]</a>"
message += "</p>"
return message
/obj/item/areaeditor/blueprints/proc/view_wire_set(mob/user, wireset)
//for some reason you can't use wireset directly as a derefencer so this is the next best :/
for(var/device in GLOB.wire_color_directory)
if("[device]" == wireset) //I know... don't change it...
var/message = "<p><b>[GLOB.wire_name_directory[device]]:</b>"
for(var/Col in GLOB.wire_color_directory[device])
var/wire_name = GLOB.wire_color_directory[device][Col]
if(!findtext(wire_name, WIRE_DUD_PREFIX)) //don't show duds
message += "<p><span style='color: [Col]'>[Col]</span>: [wire_name]</p>"
message += "</p>"
return message
return ""
/obj/item/areaeditor/proc/edit_area()
var/area/A = get_area(usr)
var/prevname = "[A.name]"
var/str = tgui_input_text(usr, "New area name", "Area Creation", max_length = MAX_NAME_LEN)
str = sanitize(str,MAX_NAME_LEN)
if(!str || !length(str) || str==prevname) //cancel
return
if(length(str) > 50)
to_chat(usr, span_warning("The given name is too long. The area's name is unchanged."))
return
rename_area(A, str)
to_chat(usr, span_notice("You rename the '[prevname]' to '[str]'."))
log_and_message_admins("has changed the area '[prevname]' title to '[str]'.")
A.update_areasize()
interact()
return TRUE
//Blueprint Subtypes
/obj/item/areaeditor/blueprints/cyborg
name = "station schematics"
desc = "A digital copy of the station blueprints stored in your memory."
/proc/set_area_machinery(area/area, title, oldtitle)
if(!oldtitle) // or replacetext goes to infinite loop
return
for(var/obj/machinery/alarm/airpanel in area)
airpanel.name = replacetext(airpanel.name,oldtitle,title)
airpanel.update_area()
for(var/obj/machinery/power/apc/apcpanel in area)
apcpanel.name = replacetext(apcpanel.name,oldtitle,title)
apcpanel.update_area() //DECIDE IF THIS IS WANTED OR NOT. This can mean that the APC will overwrite the current APC the area being expanded has since areas cant have multiple APCs.
for(var/obj/machinery/atmospherics/unary/vent_scrubber/scrubber in area)
scrubber.name = replacetext(scrubber.name,oldtitle,title)
scrubber.update_area()
for(var/obj/machinery/atmospherics/unary/vent_pump/vent in area)
vent.name = replacetext(vent.name,oldtitle,title)
vent.update_area()
for(var/obj/machinery/door/door in area)
door.name = replacetext(door.name,oldtitle,title)
for(var/obj/machinery/firealarm/firepanel in area)
firepanel.name = replacetext(firepanel.name,oldtitle,title)
area.update_areasize()
//TODO: much much more. Unnamed airlocks, cameras, etc.
/proc/detect_room(turf/origin, list/break_if_found, max_size=INFINITY)
if(origin.blocks_air)
return list(origin)
. = list()
var/list/checked_turfs = list()
var/list/found_turfs = list(origin)
while(length(found_turfs))
var/turf/sourceT = found_turfs[1]
found_turfs.Cut(1, 2)
var/dir_flags = checked_turfs[sourceT]
for(var/dir in GLOB.alldirs)
if(length(.) > max_size)
return
if(dir_flags & dir) // This means we've checked this dir before, probably from the other turf
continue
var/turf/checkT = get_step(sourceT, dir)
if(!checkT)
continue
checked_turfs[sourceT] |= dir
checked_turfs[checkT] |= turn(dir, 180)
.[sourceT] |= dir
.[checkT] |= turn(dir, 180)
if(break_if_found[checkT.type] || break_if_found[checkT.loc.type])
return FALSE
//The below checks to make sure air can pass between the two turfs. If not, it can't be added to the area.
//This means walls can not be added to an area. The turf must first be added and then the wall.
//UNCOMMENT THIS IF YOU WANT THE BLUEPRINTS TO NOT ADD WALLS TO AN AREA.
//I personally think adding walls to an area is a big deal, so this is commented out.
//BEGIN ESOTERIC BULLSHIT
//log_debug("Origin: [origin.c_airblock(checkT)] SourceT: [sourceT.c_airblock(checkT)] 0=NB 1=AB 2=ZB, 3=B")
/*
if(origin.c_airblock(checkT)) //If everything breaks and it doesn't want to work, turn on the above debug and check this line. C.L. 0 = not blocked.
continue
*/
//END ESOTERIC BULLSHIT
found_turfs += checkT // Since checkT is connected, add it to the list to be processed
if(found_turfs.len)
found_turfs += origin //If this isn't done, it just adds the 8 tiles around the user.
return found_turfs
/proc/create_area(mob/creator, var/obj/item/areaeditor/AO)
if(AO && istype(AO,/obj/item/areaeditor))
if(AO.uses_charges && AO.charges < 1)
to_chat(creator, span_warning("You need more paper before you can even think of editing this area!"))
return
var/list/turfs = detect_room(get_turf(creator), area_or_turf_fail_types, BP_MAX_ROOM_SIZE*2)
if(!turfs)
to_chat(creator, span_warning("The new area must have a floor and not a part of a shuttle."))
return
if(length(turfs) > BP_MAX_ROOM_SIZE)
to_chat(creator, span_warning("The room you're in is too big. It is [length(turfs) >= BP_MAX_ROOM_SIZE *2 ? "more than 100" : ((length(turfs) / BP_MAX_ROOM_SIZE)-1)*100]% larger than allowed."))
return
var/list/areas = list("New Area" = /area)
var/annoy_admins = 0
for(var/i in 1 to length(turfs))
var/area/place = get_area(turfs[i])
if(blacklisted_areas[place.type])
continue
if(!place.requires_power || (place.flags & BLUE_SHIELDED))
continue // No expanding powerless rooms etc
areas[place.name] = place
var/area_choice = tgui_input_list(creator, "Choose an area to expand or make a new area", "Area Expansion", areas)
if(isnull(area_choice))
to_chat(creator, span_warning("No choice selected. No adjustments made."))
return
area_choice = areas[area_choice]
var/area/newA
var/area/oldA = get_area(get_turf(creator))
if(!isarea(area_choice))
var/str = tgui_input_text(creator, "New area name", "Blueprint Editing", max_length = MAX_NAME_LEN)
str = sanitize(str,MAX_NAME_LEN)
if(!str || !length(str)) //cancel
return
if(length(str) > 50)
to_chat(creator, "<span class='warning'>Name too long.</span>")
return
for(var/area/A in world) //Check to make sure we're not making a duplicate name. Sanity.
if(A.name == str)
to_chat(creator, "<span class='warning'>An area in the world alreay has this name.</span>")
return
annoy_admins = 1 //They just made a new area entirely.
newA = new area_choice
newA.setup(str)
newA.has_gravity = oldA.has_gravity
else
newA = area_choice
for(var/i in 1 to length(turfs)) //Fix lighting. Praise the lord.
var/turf/thing = turfs[i]
newA.contents += thing
thing.change_area(oldA, newA)
set_area_machinery(newA, newA.name, oldA.name)// Change the name and area defines of all the machinery to the correct area.
oldA.power_check() //Simply makes the area turn the power off if you nicked an APC from it.
to_chat(creator, span_notice("You have created a new area, named [newA.name]. It is now weather proof, and constructing an APC will allow it to be powered."))
if(annoy_admins)
message_admins("[key_name(creator, creator.client)] just made a new area called [newA.name] ](<A HREF='?_src_=holder;adminmoreinfo=\ref[creator]'>?</A>) at ([creator.x],[creator.y],[creator.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[creator.x];Y=[creator.y];Z=[creator.z]'>JMP</a>)",0,1)
log_game("[key_name(creator, creator.client)] just made a new area called [newA.name]")
if(AO && istype(AO,/obj/item/areaeditor))
if(AO.uses_charges)
AO.charges -= 1
return TRUE
// USED FOR VARIANT ROOM CREATION.
// OLD CODE. DON'T TOUCH OR 100 RABID SQUIRRELS WILL DEVOUR YOU.
// I say old code, but it truly isn't. It's a bastardization of the new create_area code and the old create_area code.
// In essence, it does a few things: Ensure no blacklisted areas are nearby, get the nearby areas (to allow merging), and allow you to make a whole near area.
/obj/item/areaeditor/proc/create_area_whole(mob/creator, var/override = 0) //Gets the entire enclosed space and makes a new area out of it. Can overwrite old areas.
if(uses_charges && charges < 5)
to_chat(creator, span_warning("You need more paper before you can even think of editing this area!"))
return
var/res = detect_room_ex(get_turf(creator), can_create_areas_into, area_or_turf_fail_types)
if(!res)
to_chat(creator, span_warning("There is an area forbidden from being edited here! Use the fine-tune area creator! (3x3)"))
return
if(!istype(res,/list))
switch(res)
if(ROOM_ERR_SPACE)
to_chat(creator, "<span class='warning'>The new area must be completely airtight!</span>")
return
if(ROOM_ERR_TOOLARGE)
to_chat(creator, "<span class='warning'>The new area too large!</span>")
return
if(ROOM_ERR_FORBIDDEN)
to_chat(creator, "<span class='warning'>There is an area forbidden from being edited here!</span>")
return
else
to_chat(creator, "<span class='warning'>Error! Please notify administration!</span>")
return
var/list/turf/turfs = res
var/list/areas = list("New Area" = /area) //The list of areas surrounding the user.
var/area/newA //The new area
var/area/oldA = get_area(get_turf(creator)) //The old area (area currently standing in)
var/str //What the new area is named.
var/can_make_new_area = 1 //If they can make a new area here or not.
var/list/nearby_turfs_to_check = detect_room(get_turf(creator), area_or_turf_fail_types, BP_MAX_ROOM_SIZE*2) //Get the nearby areas.
if(!nearby_turfs_to_check)
to_chat(creator, span_warning("The new area must have a floor and not a part of a shuttle."))
return
if(length(turfs) > BP_MAX_ROOM_SIZE)
to_chat(creator, span_warning("The room you're in is too big. It is [length(turfs) >= BP_MAX_ROOM_SIZE *2 ? "more than 100" : ((length(turfs) / BP_MAX_ROOM_SIZE)-1)*100]% larger than allowed."))
return
for(var/i in 1 to length(nearby_turfs_to_check))
var/area/place = get_area(nearby_turfs_to_check[i])
if(blacklisted_areas[place.type])
if(!creator.lastarea != place) //Stops them from merging a blacklisted area to make it larger. Allows them to merge a blacklisted area into an allowed area. (Expansion!)
continue
if(!BUILDABLE_AREA_TYPES[place.type]) //TODOTODOTODO
can_make_new_area = 0
if(!place.requires_power || (place.flags & BLUE_SHIELDED))
continue // No expanding powerless rooms etc
areas[place.name] = place
//They can select an area they want to turn their current area into.
var/area_choice = tgui_input_list(creator, "What area do you want to turn the area YOU ARE CURRENTLY STANDING IN to? Or do you want to make a new area?", "Area Expansion", areas)
if(isnull(area_choice)) //They pressed cancel.
to_chat(creator, "<span class='warning'>No changes made.</span>")
return
area_choice = areas[area_choice]
if(!isarea(area_choice)) //They chose "New Area"
if(!can_make_new_area && !can_override)
to_chat(creator, "<span class='warning'>Making a new area here would be meaningless. Renaming it would be a better option.</span>")
return
str = tgui_input_text(creator, "New area name", "Blueprint Editing", max_length = MAX_NAME_LEN)
str = sanitize(str,MAX_NAME_LEN)
if(!str || !length(str)) //cancel
return
if(length(str) > 50)
to_chat(creator, "<span class='warning'>Name too long.</span>")
return
for(var/area/A in world) //Check to make sure we're not making a duplicate name. Sanity.
if(A.name == str)
to_chat(creator, "<span class='warning'>An area in the world alreay has this name.</span>")
return
var/confirm = tgui_alert(creator, "Are you sure you want to change [oldA.name] into a new area named [str]?", "READ CAREFULLY", list("No", "Yes"))
if(confirm == "No")
to_chat(creator, "<span class='warning'>No changes made.</span>")
return
newA = new area_choice
newA.setup(str)
newA.has_gravity = oldA.has_gravity
else
var/confirm = tgui_alert(creator, "Are you sure you want to change [oldA.name] into [area_choice]?", "READ CAREFULLY", list("No", "Yes"))
if(confirm == "No")
to_chat(creator, "<span class='warning'>No changes made.</span>")
return
newA = area_choice //They selected to turn the area they're standing on into the selected area.
if(str) //New area, new name.
newA.setup(str)
else
newA.setup(newA.name)
for(var/i in 1 to length(turfs)) //Fix lighting. Praise the lord.
var/turf/thing = turfs[i]
newA.contents += thing
thing.change_area(oldA, newA)
move_turfs_to_area(turfs, newA)
newA.has_gravity = oldA.has_gravity
set_area_machinery(newA, newA.name, oldA.name)
oldA.power_check() //Simply makes the area turn the power off if you nicked an APC from it.
to_chat(creator, span_notice("You have created a new area, named [newA.name]. It is now weather proof, and constructing an APC will allow it to be powered."))
message_admins("[key_name(creator, creator.client)] just made a new area called [newA.name] ](<A HREF='?_src_=holder;adminmoreinfo=\ref[creator]'>?</A>) at ([creator.x],[creator.y],[creator.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[creator.x];Y=[creator.y];Z=[creator.z]'>JMP</a>)",0,1)
log_game("[key_name(creator, creator.client)] just made a new area called [newA.name]")
charges -= 5
spawn(5)
interact()
return
/proc/move_turfs_to_area(var/list/turf/turfs, var/area/A)
for(var/T in turfs)
ChangeArea(T, A)
/obj/item/areaeditor/proc/detect_room_ex(var/turf/first, var/allowedAreas = AREA_SPACE, var/list/forbiddenAreas = list(), var/visual)
if(!istype(first))
return ROOM_ERR_LOLWAT
if(!visual && forbiddenAreas[first.loc.type] || forbiddenAreas[first.type]) //Is the area of the starting turf a banned area? Is the turf a banned area?
return ROOM_ERR_FORBIDDEN
var/list/turf/found = new
var/list/turf/pending = list(first)
while(pending.len)
if (found.len+pending.len > BP_MAX_ROOM_SIZE)
return ROOM_ERR_TOOLARGE
var/turf/T = pending[1] //why byond havent list::pop()?
pending -= T
for (var/dir in cardinal)
var/turf/NT = get_step(T,dir)
if (!isturf(NT) || (NT in found) || (NT in pending))
continue
if(!visual && forbiddenAreas[NT.loc.type])
return ROOM_ERR_FORBIDDEN
// We ask ZAS to determine if its airtight. Thats what matters anyway right?
if(air_master.air_blocked(T, NT))
// Okay thats the edge of the room
if(get_area_type(NT.loc) == AREA_SPACE && air_master.air_blocked(NT, NT))
found += NT // So we include walls/doors not already in any area
continue
if (istype(NT, /turf/space))
return ROOM_ERR_SPACE //omg hull breach we all going to die here
if (istype(NT, /turf/simulated/shuttle))
return ROOM_ERR_SPACE // Unsure why this, but was in old code. Trusting for now.
if (NT.loc != first.loc && !(get_area_type(NT.loc) & allowedAreas))
// Edge of a protected area. Lets stop here...
continue
if (!istype(NT, /turf/simulated))
// Great, unsimulated... eh, just stop searching here
continue
// Okay, NT looks promising, lets continue the search there!
pending += NT
found += T
// end while
return found
//Nice verbs for the engineer to see where areas start/end.
/obj/item/areaeditor/verb/seeRoomColors()
set src in usr
set category = "Blueprints"
set name = "Show Room Colors"
// If standing somewhere we can expand from, use expand perms, otherwise create
var/canOverwrite = (get_area_type() & can_expand_areas_in) ? can_expand_areas_into : can_create_areas_into
var/res = detect_room_ex(get_turf(usr), canOverwrite, visual = 1)
if(!istype(res, /list))
switch(res)
if(ROOM_ERR_SPACE)
to_chat(usr, "<span class='warning'>The new area must be completely airtight!</span>")
return
if(ROOM_ERR_TOOLARGE)
to_chat(usr, "<span class='warning'>The new area too large!</span>")
return
else
to_chat(usr, "<span class='danger'>Error! Please notify administration!</span>")
return
// Okay we got a room, lets color it
seeAreaColors_remove()
var/icon/green = new('icons/misc/debug_group.dmi', "green")
for(var/turf/T in res)
usr << image(green, T, "blueprints", TURF_LAYER)
areaColor_turfs += T
to_chat(usr, "<span class='notice'>The space covered by the new area is highlighted in green.</span>")
/obj/item/areaeditor/verb/seeAreaColors()
set src in usr
set category = "Blueprints"
set name = "Show Area Colors"
// Remove any existing
seeAreaColors_remove()
to_chat(usr, "<span class='notice'>\The [src] shows nearby areas in different colors.</span>")
var/i = 0
for(var/area/A in range(usr))
if(get_area_type(A) == AREA_SPACE)
continue // Don't overlay all of space!
var/icon/areaColor = new('icons/misc/debug_rebuild.dmi', "[++i]")
to_chat(usr, "- [A] as [i]")
for(var/turf/T in A.contents)
usr << image(areaColor, T, "blueprints", TURF_LAYER)
areaColor_turfs += T
/obj/item/areaeditor/verb/seeAreaColors_remove()
set src in usr
set category = "Blueprints"
set name = "Remove Area Colors"
areaColor_turfs.Cut()
if(usr.client.images.len)
for(var/image/i in usr.client.images)
if(i.icon_state == "blueprints")
usr.client.images.Remove(i)
//GLOBAL VERB FOR PAPER TO ENABLE ANYONE TO MAKE AN AREA IN BUILDABLE AREAS.
//THIS IS 70 TILES. ANYTHING LARGER SHOULD USE ACTUAL BLUEPRINTS.
/obj/item/weapon/paper
var/created_area = 0
var/area_cooldown = 0
/obj/item/weapon/paper/verb/create_area()
set name = "Create Area"
set category = "Object"
set src in usr
if(created_area)
to_chat(usr, "<span class='warning'>This paper has already been used to create an area.</span>")
return
if(usr.stat || world.time < area_cooldown)
to_chat(usr, "<span class='warning'>You recently used this paper to try to create an area. Wait one minute before using it again.</span>")
return
area_cooldown = world.time + 600 //Anti spam.
create_new_area(usr)
add_fingerprint(usr)
return
/proc/get_new_area_type(area/A) //1 = can build in. 0 = can not build in.
if (!A)
A = get_area(usr)
if(A.outdoors) //ALWAYS able to build outdoors. This means if it's missed in BUILDABLE_AREA_TYPES it's fine.
return 1
for (var/type in BUILDABLE_AREA_TYPES) //This works well.
if ( istype(A,type) )
return 1
for (var/type in SPECIALS)
if ( istype(A,type) )
return 0
return 0 //If it's not a buildable area, don't let them build in it.
/proc/detect_new_area(var/turf/first, var/user) //Heavily simplified version for creating an area yourself.
if(!istype(first)) //Not on a turf.
to_chat(usr, "<span class='warning'You can not create a room here.</span>")
return
if(get_new_area_type(first.loc) == 1) //Are they in an area they can build? I tried to do this BUILDABLE_AREA_TYPES[first.loc.type] but it refused.
var/list/turf/found = new
var/list/turf/pending = list(first)
while(pending.len)
if (found.len+pending.len > 70)
return 1 //TOOLARGE
var/turf/T = pending[1]
pending -= T
for (var/dir in cardinal)
var/turf/NT = get_step(T,dir)
if (!isturf(NT) || (NT in found) || (NT in pending))
continue
if(!get_new_area_type(NT.loc) == 1) //The contains somewhere that is NOT a buildable area.
return 3 //NOT A BUILDABLE AREA
if(air_master.air_blocked(T, NT)) //Is the room airtight?
// Okay thats the edge of the room
if(get_new_area_type(NT.loc) == 1 && air_master.air_blocked(NT, NT))
found += NT // So we include walls/doors not already in any area
continue
if (istype(NT, /turf/space))
return 2 //SPACE
if (istype(NT, /turf/simulated/shuttle))
return 2 //SPACE
if (NT.loc != first.loc && !(get_new_area_type(NT.loc) & 1))
// Edge of a protected area. Lets stop here...
continue
if (!istype(NT, /turf/simulated))
// Great, unsimulated... eh, just stop searching here
continue
// Okay, NT looks promising, lets continue the search there!
pending += NT
found += T
// end while
return found
else
return 3
/proc/create_new_area(mob/creator) //Heavily simplified version of the blueprint version.
var/res = detect_new_area(get_turf(creator), creator)
if(!res)
to_chat(creator, span_warning("Something went wrong."))
return
if(!istype(res,/list))
switch(res)
if(1)
to_chat(creator, "<span class='warning'>The new area too large! You can only have an area that is up to 70 tiles.</span>")
return
if(2)
to_chat(creator, "<span class='warning'>The new area must be completely airtight and not be part of a shuttle!</span>")
return
if(3)
to_chat(creator, "<span class='warning'>There is an area not permitted to be built in somewhere in the room!</span>")
return
else
to_chat(creator, "<span class='warning'>Error! Please notify administration!</span>")
return
var/list/turf/turfs = res
var/area/newA //The new area
var/area/oldA = get_area(get_turf(creator)) //The old area (area currently standing in)
var/str //What the new area is named.
var/list/nearby_turfs_to_check = detect_room(get_turf(creator), area_or_turf_fail_types, 70) //Get the nearby areas.
if(!nearby_turfs_to_check)
to_chat(creator, span_warning("The new area must have a floor and not a part of a shuttle."))
return
if(length(turfs) > 70) //Sanity
to_chat(creator, span_warning("The room you're in is too big. It can only be 70 tiles in size, excluding walls."))
return
//They can select an area they want to turn their current area into.
str = sanitizeSafe(tgui_input_text(usr, "What would you like to name the area?", "Area Name", null, MAX_NAME_LEN), MAX_NAME_LEN)
if(isnull(str)) //They pressed cancel.
to_chat(creator, "<span class='warning'>No new area made. Cancelling.</span>")
return
if(!str || !length(str)) //sanity
to_chat(creator, "<span class='warning'>No new area made. Cancelling.</span>")
return
if(length(str) > MAX_NAME_LEN)
to_chat(creator, "<span class='warning'>Name too long.</span>")
return
for(var/area/A in world) //Check to make sure we're not making a duplicate name. Sanity.
if(A.name == str)
to_chat(creator, "<span class='warning'>An area in the world alreay has this name.</span>")
return
newA = new /area
newA.setup(str)
newA.has_gravity = oldA.has_gravity
newA.setup(str)
for(var/i in 1 to length(turfs)) //Fix lighting. Praise the lord.
var/turf/thing = turfs[i]
newA.contents += thing
thing.change_area(oldA, newA)
move_turfs_to_area(turfs, newA)
newA.has_gravity = oldA.has_gravity
set_area_machinery(newA, newA.name, oldA.name)
oldA.power_check() //Simply makes the area turn the power off if you nicked an APC from it.
to_chat(creator, span_notice("You have created a new area, named [newA.name]. It is now weather proof, and constructing an APC will allow it to be powered."))
message_admins("[key_name(creator, creator.client)] just made a new area called [newA.name] ](<A HREF='?_src_=holder;adminmoreinfo=\ref[creator]'>?</A>) at ([creator.x],[creator.y],[creator.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[creator.x];Y=[creator.y];Z=[creator.z]'>JMP</a>)",0,1)
log_game("[key_name(creator, creator.client)] just made a new area called [newA.name]")
return
#undef BP_MAX_ROOM_SIZE

View File

@@ -53,7 +53,7 @@
/obj/structure/closet/body_bag/attackby(var/obj/item/W as obj, mob/user as mob) /obj/structure/closet/body_bag/attackby(var/obj/item/W as obj, mob/user as mob)
if (istype(W, /obj/item/weapon/pen)) if (istype(W, /obj/item/weapon/pen))
var/t = tgui_input_text(user, "What would you like the label to be?", text("[]", src.name), null) var/t = tgui_input_text(user, "What would you like the label to be?", text("[]", src.name), null, MAX_NAME_LEN )
if (user.get_active_hand() != W) if (user.get_active_hand() != W)
return return
if (!in_range(src, user) && src.loc != user) if (!in_range(src, user) && src.loc != user)

View File

@@ -42,12 +42,16 @@
/obj/item/mecha_parts/part/phazon_right_arm, /obj/item/mecha_parts/part/phazon_right_arm,
/obj/item/mecha_parts/part/phazon_right_leg, /obj/item/mecha_parts/part/phazon_right_leg,
/obj/item/mecha_parts/part/phazon_torso, /obj/item/mecha_parts/part/phazon_torso,
/obj/item/weapon/circuitboard/mecha/phazon/targeting,
/obj/item/weapon/circuitboard/mecha/phazon/peripherals,
/obj/item/weapon/circuitboard/mecha/phazon/main,
/obj/item/device/bodysnatcher, /obj/item/device/bodysnatcher,
/obj/item/weapon/bluespace_harpoon, /obj/item/weapon/bluespace_harpoon,
/obj/item/clothing/accessory/permit/gun, /obj/item/clothing/accessory/permit/gun,
/obj/item/device/perfect_tele, /obj/item/device/perfect_tele,
/obj/item/device/sleevemate, /obj/item/device/sleevemate,
/obj/item/weapon/disk/nifsoft/compliance, /obj/item/weapon/disk/nifsoft/compliance,
/obj/item/weapon/implanter/compliance,
/obj/item/seeds/ambrosiadeusseed, /obj/item/seeds/ambrosiadeusseed,
/obj/item/seeds/ambrosiavulgarisseed, /obj/item/seeds/ambrosiavulgarisseed,
/obj/item/seeds/libertymycelium, /obj/item/seeds/libertymycelium,
@@ -108,4 +112,4 @@
w_class = ITEMSIZE_NORMAL w_class = ITEMSIZE_NORMAL
/obj/item/weapon/miscdisc/attack_self(mob/living/user as mob) /obj/item/weapon/miscdisc/attack_self(mob/living/user as mob)
to_chat(user, "As you hold the large disc in your open palm, fingers cusped around the edge, the crystal embedded in the item begins to vibrate. It lifts itself from the disc a few cenimetres, before beginning to glow with a bright red light. The glow lasts for a few seconds, before the crystal embeds itself back into the disc with a quick snap.") to_chat(user, "As you hold the large disc in your open palm, fingers cusped around the edge, the crystal embedded in the item begins to vibrate. It lifts itself from the disc a few cenimetres, before beginning to glow with a bright red light. The glow lasts for a few seconds, before the crystal embeds itself back into the disc with a quick snap.")

View File

@@ -137,7 +137,7 @@ var/list/GPS_list = list()
if(emped) if(emped)
to_chat(user, "It's busted!") to_chat(user, "It's busted!")
return return
toggle_tracking() toggle_tracking()
if(tracking) if(tracking)
to_chat(user, "[src] is no longer tracking, or visible to other GPS devices.") to_chat(user, "[src] is no longer tracking, or visible to other GPS devices.")
@@ -194,7 +194,7 @@ var/list/GPS_list = list()
dat["curr_z"] = curr.z dat["curr_z"] = curr.z
dat["curr_z_name"] = strip_improper(using_map.get_zlevel_name(curr.z)) dat["curr_z_name"] = strip_improper(using_map.get_zlevel_name(curr.z))
dat["z_level_detection"] = using_map.get_map_levels(curr.z, long_range) dat["z_level_detection"] = using_map.get_map_levels(curr.z, long_range)
var/list/gps_list = list() var/list/gps_list = list()
for(var/obj/item/device/gps/G in GPS_list - src) for(var/obj/item/device/gps/G in GPS_list - src)
@@ -250,7 +250,7 @@ var/list/GPS_list = list()
dat += "<tr>" dat += "<tr>"
var/gps_ref = "\ref[gps["ref"]]" var/gps_ref = "\ref[gps["ref"]]"
dat += "<td>[gps["gps_tag"]]</td><td>[gps["area_name"]]</td>" dat += "<td>[gps["gps_tag"]]</td><td>[gps["area_name"]]</td>"
if(istype(gps_data["ref"], /obj/item/device/gps/internal/poi)) if(istype(gps_data["ref"], /obj/item/device/gps/internal/poi))
dat += "<td>[gps["local"] ? "[gps["direction"]] Dist: [round(gps["distance"], 10)]m" : "[gps["z_name"]]"]</td>" dat += "<td>[gps["local"] ? "[gps["direction"]] Dist: [round(gps["distance"], 10)]m" : "[gps["z_name"]]"]</td>"
else else
@@ -323,7 +323,7 @@ var/list/GPS_list = list()
. = TRUE . = TRUE
if(href_list["tag"]) if(href_list["tag"])
var/a = tgui_input_text(usr, "Please enter desired tag.", name, gps_tag) var/a = tgui_input_text(usr, "Please enter desired tag.", name, gps_tag, 10)
a = uppertext(copytext(sanitize(a), 1, 11)) a = uppertext(copytext(sanitize(a), 1, 11))
if(in_range(src, usr)) if(in_range(src, usr))
gps_tag = a gps_tag = a

View File

@@ -0,0 +1,605 @@
// TO ANYBODY LOOKING AT THIS FILE:
// Everything is mostly commented on to give as much detailed information as possible.
// Some things may be difficult to understand, but every variable in here has a comment explaining what it is/does.
// The base unit, the 'personal_shield_generator' is a backpack, comes with a gun, and has normal numbers for everything.
// The belt units do NOT come with a gun and have a cell that is half the capacity of backpack units.
// These can be VERY, VERY, VERY strong if too many are handed out, the cell is too strong, or the modifier is too strong.
// Additionally, if you are mapping any of these in, ensure you map in the /loaded versions or else they won't have a battery.
// I have also made it so you can modify everything about them, including the modifier they give and the cell, which can be changed via mapping.
// In essence, these can be viewed as an extra layer of armor that has upsides and downsides with more extensive features.
// Shield generators apply PRE armor. Ultimately this shouldn't matter too much, but it makes more sense this way.
// There are a good amount of variants in here, ranging from mining to security to misc ones.
// If you want to make a variant, you need to only change modifier_type and make the modifier desired.
/obj/item/device/personal_shield_generator
name = "personal shield generator"
desc = "A personal shield generator."
icon = 'icons/obj/items_vr.dmi'
icon_state = "shieldpack_basic"
item_state = "defibunit" //Placeholder
slot_flags = SLOT_BACK
force = 5
throwforce = 6
preserve_item = 1
w_class = ITEMSIZE_HUGE //It's a giant shield generator!!!
unacidable = TRUE
origin_tech = list(TECH_MATERIAL = 6, TECH_COMBAT = 8, TECH_POWER = 6, TECH_DATA = 4) //These are limited AND high tech. Breaking one of them down is massive.
action_button_name = "Toggle Shield"
var/obj/item/weapon/gun/energy/gun/generator/active_weapon
var/obj/item/weapon/cell/device/bcell = null
var/upgraded = 0 // If the PSG has been upgraded by some method or not. Only used for the mining belt ATM.
var/generator_hit_cost = 100 // Power used when a special effect (such as a bullet being blocked) is performed! Could also be expanded to other things.
var/generator_active_cost = 10 // Power used when turned on.
var/damage_cost = 25 // 40 damage absorbed per 1000 charge.
var/modifier_type = /datum/modifier/shield_projection // What type of modifier will it add? Used for variant modifiers!
var/has_weapon = 1 // Backpack units generally have weapons.
var/shield_active = 0 // If the shield gen is active.
var/effect_color = "#99FFFF" // Allows for changing shield colors. Default cyan.
/obj/item/device/personal_shield_generator/get_cell()
return bcell
/obj/item/device/personal_shield_generator/New()
..()
if(ispath(bcell))
bcell = new bcell(src)
if(has_weapon)
if(ispath(active_weapon))
active_weapon = new active_weapon(src, src)
active_weapon.power_supply = bcell
else
active_weapon = new(src, src)
active_weapon.power_supply = bcell
else
verbs -= /obj/item/device/personal_shield_generator/verb/weapon_toggle
STOP_PROCESSING(SSobj, src) //We do this so it doesn't start processing until it's first used.
update_icon()
/obj/item/device/personal_shield_generator/Destroy()
. = ..()
QDEL_NULL(active_weapon)
QDEL_NULL(bcell)
/obj/item/device/personal_shield_generator/loaded //starts with a cell
bcell = /obj/item/weapon/cell/device/shield_generator/backpack
/obj/item/device/personal_shield_generator/update_icon()
if(shield_active)
icon_state = "shieldpack_basic_on"
else
icon_state = "shieldpack_basic"
/obj/item/device/personal_shield_generator/examine(mob/user)
. = ..()
if(Adjacent(user))
if(upgraded)
. += "The unit appears to be upgraded."
if(bcell)
. += "The internal cell is [round(bcell.percent() )]% charged."
else
. += "The device has no cell installed."
return
if(damage_cost) //Prevention of dividing by 0 errors.
. += "It reads that it can take [bcell.charge/damage_cost] more damage before the shield goes down."
if(bcell.self_recharge && bcell.charge_amount)
. += "This model is self charging and will take [bcell.maxcharge/bcell.charge_amount] seconds to fully charge from empty."
if(bcell.rigged)
. += "A red flashing 'WARNING' is visible on the display, noting that the cell is unstable and requires replacement."
/* //This would be cool, but we need sprites.
cut_overlays()
if(has_weapon && active_weapon && active_weapon.loc == src) //in case gun gets destroyed somehow.
add_overlay("[initial(icon_state)]-paddles")
if(bcell)
if(bcell.check_charge(generator_hit_cost)) //Can we take a blow?
add_overlay("[initial(icon_state)]-powered")
else if(has_weapon && active_weapon)
if(bcell.check_charge(active_weapon.charge_cost)) //We got enough to go pew pew?
add_overlay("[initial(icon_state)]-powered")
var/ratio = CEILING(bcell.percent()/25, 1) * 25
add_overlay("[initial(icon_state)]-charge[ratio]")
else
add_overlay("[initial(icon_state)]-nocell")
*/
/obj/item/device/personal_shield_generator/emp_act(severity)
if(bcell && shield_active)
switch(severity)
if(1) //Point blank EMP shots have a good chance of burning the cell charge.
if(prob(50))
bcell.emp_act(severity)
if(prob(5)) //1 in 20% chance to fry the battery completly, which has a 1/10 chance of making the battery explode on next use.
bcell.corrupt() //Not too bad if you slotted a battery in. Disasterous if it has a self-charging battery.
if(bcell.rigged) //Did the above just rig the cell? Turn it off. Don't immediately have it go boom. Instead have the cell blow soon-ish.
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
shield_active = 0
if(bcell.charge_delay) //It WILL blow up soon. Downside of self-charging cells.
to_chat(src.loc, "<span class='critical'>Your shield generator sparks and suddenly goes down! A warning message pops up on screen: \
'WARNING, INTERNAL CELL MELTDOWN IMMINENT. TIME TILL EXPLOSION: [bcell.charge_delay/10] SECONDS. DISCARD UNIT IMMEDIATELY!'</span>")
else //It won't blow up unless you turn it back on again. Upside of using non-charging cells.
to_chat(src.loc, "<span class='critical'>Your shield generator sparks and suddenly goes down! A warning message pops up on screen: \
'WARNING, INTERNAL CELL CRITICALLY DAMAGED. REPLACE CELL IMMEDIATELY.'</span>")
STOP_PROCESSING(SSobj, src)
update_icon()
else
if(prob(25))
bcell.emp_act(severity)
..()
/obj/item/device/personal_shield_generator/ui_action_click()
toggle_shield()
/obj/item/device/personal_shield_generator/attack_hand(mob/user)
if(loc == user)
toggle_shield()
else
..()
/obj/item/device/personal_shield_generator/AltClick(mob/living/user)
weapon_toggle()
/obj/item/device/personal_shield_generator/MouseDrop()
if(ismob(src.loc))
if(!CanMouseDrop(src))
return
var/mob/M = src.loc
if(!M.unEquip(src))
return
src.add_fingerprint(usr)
M.put_in_any_hand_if_possible(src)
/obj/item/device/personal_shield_generator/attackby(obj/item/weapon/W, mob/user, params)
if(W == active_weapon)
reattach_gun(user)
else if(istype(W, /obj/item/weapon/cell))
if(bcell)
to_chat(user, "<span class='notice'>\The [src] already has a cell.</span>")
else if(!istype(W, /obj/item/weapon/cell/device/weapon)) //Weapon cells only!
to_chat(user, "<span class='notice'>This cell will not fit in the device.</span>")
else
if(!user.unEquip(W))
return
W.forceMove(src)
bcell = W
if(active_weapon)
active_weapon.power_supply = bcell
to_chat(user, "<span class='notice'>You install a cell in \the [src].</span>")
update_icon()
else if(W.is_screwdriver())
if(bcell)
if(istype(bcell, /obj/item/weapon/cell/device/shield_generator)) //No stealing self charging batteries!
var/choice = tgui_alert(user, "A popup appears on the device 'REMOVING THE INTERNAL CELL WILL DESTROY THE BATTERY. DO YOU WISH TO CONTINUE?'...Well, do you?", "Selection List", list("Cancel", "Remove"))
if(choice == "Remove") //Warned you...
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
bcell.forceMove(get_turf(src.loc))
qdel(bcell)
bcell = null //Sanity.
if(active_weapon)
reattach_gun() //Put the gun back if it's out. No shooting if we don't have a cell!
active_weapon.power_supply = null //No power cell anymore!
to_chat(user, "<span class='notice'>You remove the cell from \the [src], destroying the battery.</span>")
update_icon()
return
else
return
else
bcell.update_icon()
bcell.forceMove(get_turf(src.loc))
bcell = null
if(active_weapon)
reattach_gun() //Put the gun back if it's out. No shooting if we don't have a cell!
active_weapon.power_supply = null //No power cell anymore!
to_chat(user, "<span class='notice'>You remove the cell from \the [src].</span>")
update_icon()
else if(istype(W,/obj/item/device/multitool))
var/new_color = input(usr, "Choose a color to set the shield to!", "", effect_color) as color|null
if(new_color)
effect_color = new_color
else
return ..()
// TODO: EMAG ACT
// Perhaps make it so emagging the generator gives two options: One to rig the cell (stealthily) and one to disable the safeties (supercharge it)
// Disabling the safeties would make it a stronger variant but boost the 'damage_cost' perhaps. Dunno.
// We're an RP server so emags don't come into play except for random trash finds. Meaning it'd be RNG if you could 'supercharge' your shield genrator.
// This would kind of be like people being able to emag the NIFSoft for bloodletters & all the buffs that come with an emagged NIFSoft.
// Making it so emagging the weapon it comes with would also be a good idea. Different modes, perhaps?
/*
/obj/item/device/personal_shield_generator/emag_act(var/remaining_charges, var/mob/user)
if(active_weapon)
. = active_weapon.emag_act(user)
update_icon()
return
*/
//Gun stuff
/obj/item/device/personal_shield_generator/verb/toggle_shield()
set name = "Toggle Shield"
set category = "Object"
var/mob/living/carbon/human/user = usr
if(user.last_special > world.time)
return
user.last_special = world.time + 10 //No spamming!
if(!bcell || !bcell.check_charge(generator_hit_cost) || !bcell.check_charge(generator_active_cost))
to_chat(user, "<span class='warning'>You require a charged cell to do this!</span>")
return
if(!slot_check())
to_chat(user, "<span class='warning'>You need to equip [src] before starting the shield up!</span>")
return
else
if(shield_active)
shield_active = !shield_active //Deactivate the shield!
to_chat(user, "<span class='warning'>You deactive the shield!</span>")
user.remove_modifiers_of_type(/datum/modifier/shield_projection)
STOP_PROCESSING(SSobj, src)
playsound(src, 'sound/weapons/saberoff.ogg', 50, 1) //Shield turning off! PLACEHOLDER
else
shield_active = !shield_active
to_chat(user, "<span class='warning'>You activate the shield!</span>")
user.remove_modifiers_of_type(/datum/modifier/shield_projection) //Just to make sure they aren't using two at once!
user.add_modifier(modifier_type)
user.update_modifier_visuals() //Forces coloration to WORK.
START_PROCESSING(SSobj, src) //Let's only bother draining power when we're being used!
playsound(src, 'sound/weapons/saberon.ogg', 50, 1) //Shield turning off! PLACEHOLDER
update_icon()
/obj/item/device/personal_shield_generator/verb/weapon_toggle() //Make this work on Alt-Click
set name = "Toggle Gun"
set category = "Object"
var/mob/living/carbon/human/user = usr
if(user.last_special > world.time)
return
user.last_special = world.time + 10 //No spamming!
if(!active_weapon)
to_chat(user, "<span class='warning'>The gun is missing!</span>")
return
if(!bcell)
to_chat(user, "<span class='warning'>The gun requires a power supply!</span>")
return
if(active_weapon.loc != src)
reattach_gun(user) //Remove from their hands and back onto the defib unit
return
if(!slot_check())
to_chat(user, "<span class='warning'>You need to equip [src] before taking out [active_weapon].</span>")
else
if(!usr.put_in_hands(active_weapon)) //Detach the gun into the user's hands
to_chat(user, "<span class='warning'>You need a free hand to hold the gun!</span>")
update_icon() //success
/obj/item/device/personal_shield_generator/process()
if(!bcell) //They removed the battery midway.
if(istype(loc, /mob/living/carbon/human)) //We on someone? Tell them it turned off.
var/mob/living/carbon/human/user = loc
to_chat(user, "<span class='warning'>The shield deactivates! An error message pops up on screen: 'Cell missing. Cell replacement required.'</span>")
user.remove_modifiers_of_type(/datum/modifier/shield_projection)
shield_active = 0
STOP_PROCESSING(SSobj, src)
update_icon()
playsound(src, 'sound/weapons/saberoff.ogg', 50, 1) //Shield turning off! PLACEHOLDER
return
if(shield_active)
if(bcell.rigged) //They turned it back on after it was rigged to go boom.
if(istype(loc, /mob/living/carbon/human)) //Deactivate the shield, first. You're not getting reduced damage...
var/mob/living/carbon/human/user = loc
to_chat(user, "<span class='warning'>The shield deactivates, an error message popping up on screen: 'Cell Reactor Critically damaged. Cell replacement required.'</span>")
user.remove_modifiers_of_type(/datum/modifier/shield_projection)
if(active_weapon) //Retract the gun. There's about to be no cell anymore.
reattach_gun()
active_weapon.power_supply = null
bcell.use(generator_active_cost) //Causes it to go boom.
bcell = null
shield_active = 0
STOP_PROCESSING(SSobj, src)
update_icon()
return
else //Normal operation.
bcell.use(generator_active_cost)
if(bcell.charge < generator_hit_cost || bcell.charge < generator_active_cost) //Out of charge...
shield_active = 0
if(istype(loc, /mob/living/carbon/human)) //We on someone? Tell them it turned off.
var/mob/living/carbon/human/user = loc
to_chat(user, "<span class='warning'>The shield deactivates, an error message popping up on screen: 'Cell out of charge.'</span>")
user.remove_modifiers_of_type(/datum/modifier/shield_projection)
STOP_PROCESSING(SSobj, src)
update_icon()
playsound(src, 'sound/weapons/saberoff.ogg', 50, 1) //Shield turning off! PLACEHOLDER
return
//checks that the base unit is in the correct slot to be used
/obj/item/device/personal_shield_generator/proc/slot_check()
var/mob/M = loc
if(!istype(M))
return 0 //not equipped
if((slot_flags & SLOT_BACK) && M.get_equipped_item(slot_back) == src)
return 1
if((slot_flags & SLOT_BELT) && M.get_equipped_item(slot_belt) == src)
return 1
//RIGSuit compatability. This shouldn't be possible, however, except for select RIGs.
if((slot_flags & SLOT_BACK) && M.get_equipped_item(slot_s_store) == src)
return 1
if((slot_flags & SLOT_BELT) && M.get_equipped_item(slot_s_store) == src)
return 1
return 0
/obj/item/device/personal_shield_generator/dropped(mob/user)
..()
reattach_gun(user) //A gun attached to a base unit should never exist outside of their base unit or the mob equipping the base unit
/obj/item/device/personal_shield_generator/proc/reattach_gun(mob/user)
if(!active_weapon) return
if(ismob(active_weapon.loc))
var/mob/M = active_weapon.loc
if(M.drop_from_inventory(active_weapon, src))
to_chat(user, "<span class='notice'>\The [active_weapon] snaps back into the main unit.</span>")
else
active_weapon.forceMove(src)
update_icon()
//The gun
/obj/item/weapon/gun/energy/gun/generator //The gun attached to the personal shield generator.
name = "generator gun"
desc = "A gun that is attached to the battery of the personal shield generator."
icon_state = "egunstun"
item_state = null //so the human update icon uses the icon_state instead.
fire_delay = 8
use_external_power = TRUE
cell_type = null //No cell! It runs off the cell in the shield_gen!
projectile_type = /obj/item/projectile/beam/stun/med
modifystate = "egunstun"
firemodes = list(
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun/med, modifystate="egunstun", fire_sound='sound/weapons/Taser.ogg', charge_cost = 240),
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, modifystate="egunkill", fire_sound='sound/weapons/Laser.ogg', charge_cost = 480),
)
var/obj/item/device/personal_shield_generator/shield_generator //The generator we are linked to!
var/wielded = 0
var/cooldown = 0
var/busy = 0
/obj/item/weapon/gun/energy/gun/generator/New(newloc, obj/item/device/personal_shield_generator/shield_gen)
..(newloc)
shield_generator = shield_gen
power_supply = shield_generator.bcell
/* //Unused. Use for large guns.
/obj/item/weapon/gun/energy/gun/generator/update_held_icon()
var/mob/living/M = loc
if(istype(M) && M.item_is_in_hands(src) && !M.hands_are_full())
wielded = 1
name = "[initial(name)] (wielded)"
else
wielded = 0
name = initial(name)
update_icon()
..()
*/
/obj/item/weapon/gun/energy/gun/generator/proc/can_use(mob/user, mob/M)
if(busy)
return 0
if(!check_charge(charge_cost))
to_chat(user, "<span class='warning'>\The [src] doesn't have enough charge left to do that.</span>")
return 0
if(!wielded && !isrobot(user))
to_chat(user, "<span class='warning'>You need to wield the gun with both hands before you can use it on someone!</span>")
return 0
if(cooldown)
to_chat(user, "<span class='warning'>\The [src] are re-energizing!</span>")
return 0
return 1
// TODO: EMP ACT
// The cell already gets hit and can have some nasty effects when EMP'd, so this isn't too much of a concern.
/*
/obj/item/weapon/gun/energy/gun/generator/emp_act(severity)
..()
*/
/obj/item/weapon/gun/energy/gun/generator/dropped(mob/user)
..() //update twohanding
if(shield_generator)
shield_generator.reattach_gun(user)
/obj/item/weapon/gun/energy/proc/check_charge(var/charge_amt) //In case using any other guns.
return 0
/obj/item/weapon/gun/energy/proc/checked_use(var/charge_amt) //In case using any other guns.
return 0
/obj/item/weapon/gun/energy/gun/generator/check_charge(var/charge_amt)
return (shield_generator.bcell && shield_generator.bcell.check_charge(charge_amt))
/obj/item/weapon/gun/energy/gun/generator/checked_use(var/charge_amt)
return (shield_generator.bcell && shield_generator.bcell.checked_use(charge_amt))
//VARIANTS.
/obj/item/device/personal_shield_generator/belt
name = "personal shield generator"
desc = "A personal shield generator."
icon_state = "shieldpack_basic"
item_state = "defibunit"
w_class = ITEMSIZE_LARGE //No putting these in backpacks!
slot_flags = SLOT_BELT
has_weapon = 0 //No gun with the belt!
/obj/item/device/personal_shield_generator/belt/loaded
bcell = /obj/item/weapon/cell/device/shield_generator
/obj/item/device/personal_shield_generator/belt/update_icon()
if(shield_active)
icon_state = "shieldpack_basic_on"
else
icon_state = "shieldpack_basic"
/obj/item/device/personal_shield_generator/belt/bruteburn //Example of a modified generator.
modifier_type = /datum/modifier/shield_projection/bruteburn
/obj/item/device/personal_shield_generator/belt/bruteburn/loaded //If mapped in, ONLY put loaded ones down.
bcell = /obj/item/weapon/cell/device/shield_generator
// Mining belts
/obj/item/device/personal_shield_generator/belt/mining
name = "mining PSG"
desc = "A personal shield generator designed for mining. It has a warning on the back: 'Do NOT expose the shield to stun-based weaponry.'"
modifier_type = /datum/modifier/shield_projection/mining
/obj/item/device/personal_shield_generator/belt/mining/loaded
bcell = /obj/item/weapon/cell/device/shield_generator
/obj/item/device/personal_shield_generator/belt/mining/update_icon()
if(shield_active)
icon_state = "shieldpack_mining_on"
else
icon_state = "shieldpack_mining"
/obj/item/borg/upgrade/shield_upgrade
name = "mining PSG upgrade disk."
desc = "A upgrade disk that, when slotted into a mining shield generator, upgrades the efficiency of the internal software, providing a stronger shield \
in exchange for being weaker to stun-based weaponry."
icon = 'icons/obj/objects_vr.dmi'
icon_state = "modkit"
w_class = ITEMSIZE_SMALL
/obj/item/device/personal_shield_generator/belt/mining/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/borg/upgrade/shield_upgrade))
if(modifier_type == /datum/modifier/shield_projection/mining/strong)
to_chat(user, "<span class='warning'>This shield generator is already upgraded!</span>")
return
modifier_type = /datum/modifier/shield_projection/mining/strong
upgraded = 1
to_chat(user, "<span class='notice'>You upgrade the [src] with the [W]!</span>")
user.drop_from_inventory(W)
qdel(W)
else
..()
//Security belts
/obj/item/device/personal_shield_generator/belt/security
name = "security PSG"
desc = "A personal shield generator designed for security."
modifier_type = /datum/modifier/shield_projection/security/weak
/obj/item/device/personal_shield_generator/belt/security/loaded
bcell = /obj/item/weapon/cell/device/shield_generator
/obj/item/device/personal_shield_generator/belt/security/update_icon()
if(shield_active)
icon_state = "shieldpack_security_on"
else
icon_state = "shieldpack_security"
//Misc belts. Admin-spawn only atm.
/obj/item/device/personal_shield_generator/belt/adminbus
desc = "You should not see this. You REALLY should not see this. If you do, you have either been blessed or are about to be the target of some sick prank."
modifier_type = /datum/modifier/shield_projection/admin
generator_hit_cost = 0
generator_active_cost = 0
shield_active = 0
damage_cost = 0
bcell = /obj/item/weapon/cell/device/shield_generator
/obj/item/device/personal_shield_generator/belt/parry //The 'provides one second of pure immunity to brute/burn/halloss' belt.
name = "PSG variant-P" //Not meant to be used in any serious capacity.
desc = "A personal shield generator that sacrifices long-term usability in exchange for a strong, short-lived shield projection, enabling the user to be nigh \
impervious for a second."
modifier_type = /datum/modifier/shield_projection/parry
generator_hit_cost = 0 //No cost for being hit.
damage_cost = 0//No cost for blocking effects.
generator_active_cost = 100 //However, it disables the tick immediately after being turned on.
shield_active = 0
bcell = /obj/item/weapon/cell/device/shield_generator/parry
// Backpacks. These are meant to be MUCH stronger in exchange for the fact that you are giving up a backpack slot.
// HOWEVER, be careful with these. They come loaded with a gun in them, so they shouldn't be handed out willy-nilly.
/obj/item/device/personal_shield_generator/security
name = "security PSG"
desc = "A personal shield generator designed for security. Comes with a built in defense pistol."
modifier_type = /datum/modifier/shield_projection/security
/obj/item/device/personal_shield_generator/security/loaded
bcell = /obj/item/weapon/cell/device/shield_generator/backpack
/obj/item/device/personal_shield_generator/security/strong
modifier_type = /datum/modifier/shield_projection/security/strong
/obj/item/device/personal_shield_generator/security/strong/loaded
bcell = /obj/item/weapon/cell/device/shield_generator/backpack
/obj/item/device/personal_shield_generator/security/update_icon()
if(shield_active)
icon_state = "shieldpack_security_on"
else
icon_state = "shieldpack_security"
//Power cells.
/obj/item/weapon/cell/device/shield_generator //The base power cell the shield gen comes with.
name = "shield generator battery"
desc = "A self charging battery which houses a micro-nuclear reactor. Takes a while to start charging."
maxcharge = 2400
self_recharge = TRUE
charge_amount = 80 //After the charge_delay is over, charges the cell over 30 seconds.
charge_delay = 600 //Takes a minute before it starts to recharge.
/obj/item/weapon/cell/device/shield_generator/backpack //The base power cell the backpack units come with. Double the charge vs the belt.
maxcharge = 4800
charge_amount = 160
/obj/item/weapon/cell/device/shield_generator/upgraded //A stronger version of the normal cell. Double the maxcharge, halved charge time.
maxcharge = 4800
charge_amount = 320
charge_delay = 300
/obj/item/weapon/cell/device/shield_generator/parry //The cell for the 'parry' shield gen.
maxcharge = 100
charge_amount = 100
charge_delay = 20 //Starts charging two seconds after it's discharged.

View File

@@ -322,7 +322,7 @@ GLOBAL_DATUM(autospeaker, /mob/living/silicon/ai/announcer)
GLOB.autospeaker.SetName(from) GLOB.autospeaker.SetName(from)
Broadcast_Message(connection, GLOB.autospeaker, Broadcast_Message(connection, GLOB.autospeaker,
0, "*garbled automated announcement*", src, 0, "*garbled automated announcement*", src,
message_to_multilingual(message), from, "Automated Announcement", from, "synthesized voice", message_to_multilingual(message, GLOB.all_languages[LANGUAGE_GALCOM]), from, "Automated Announcement", from, "synthesized voice",
DATA_FAKE, 0, zlevels, connection.frequency, states) //VOREStation Edit DATA_FAKE, 0, zlevels, connection.frequency, states) //VOREStation Edit
// Interprets the message mode when talking into a radio, possibly returning a connection datum // Interprets the message mode when talking into a radio, possibly returning a connection datum

View File

@@ -105,17 +105,40 @@
if(M.radiation) if(M.radiation)
if(advscan >= 2 && showadvscan == 1) if(advscan >= 2 && showadvscan == 1)
var/severity = "" var/severity = ""
if(M.radiation >= 75) if(M.radiation >= 1500)
severity = "Lethal"
else if(M.radiation >= 600)
severity = "Critical" severity = "Critical"
else if(M.radiation >= 50) else if(M.radiation >= 50)
else if(M.radiation >= 400)
severity = "Severe" severity = "Severe"
else if(M.radiation >= 25) else if(M.radiation >= 25)
else if(M.radiation >= 300)
severity = "Moderate" severity = "Moderate"
else if(M.radiation >= 1) else if(M.radiation >= 1)
else if(M.radiation >= 100)
severity = "Low" severity = "Low"
dat += "<span class='warning'>[severity] levels of radiation detected. [(severity == "Critical") ? " Immediate treatment advised." : ""]</span><br>" dat += "<span class='warning'>[severity] levels of radiation detected. [(severity == "Critical") ? " Immediate treatment advised." : ""]</span><br>"
dat += "<span class='warning'>[severity] levels of acute radiation sickness detected. [round(M.radiation/50)]Gy. [(severity == "Critical" || severity == "Lethal") ? " Immediate treatment advised." : ""]</span><br>"
else else
dat += "<span class='warning'>Radiation detected.</span><br>" dat += "<span class='warning'>Radiation detected.</span><br>"
dat += "<span class='warning'>Acute radiation sickness detected.</span><br>"
if(M.accumulated_rads)
if(advscan >= 2 && showadvscan == 1)
var/severity = ""
if(M.accumulated_rads >= 1500)
severity = "Critical"
else if(M.accumulated_rads >= 600)
severity = "Severe"
else if(M.accumulated_rads >= 400)
severity = "Moderate"
else if(M.accumulated_rads >= 300)
severity = "Mild"
else if(M.accumulated_rads >= 100)
severity = "Low"
dat += "<span class='warning'>[severity] levels of chronic radiation sickness detected. [round(M.accumulated_rads/50)]Gy.</span><br>"
else
dat += "<span class='warning'>Chronic radiation sickness detected.</span><br>"
if(iscarbon(M)) if(iscarbon(M))
var/mob/living/carbon/C = M var/mob/living/carbon/C = M
if(C.reagents.total_volume) if(C.reagents.total_volume)

View File

@@ -65,7 +65,8 @@
if(..()) if(..())
return 1 return 1
if(href_list["channel"]) if(href_list["channel"])
var/nc = tgui_input_text(usr, "Channel name", "Select new channel name", channel) var/nc = tgui_input_text(usr, "Channel name", "Select new channel name", channel, MAX_NAME_LEN)
nc = sanitize(nc,MAX_NAME_LEN)
if(nc) if(nc)
channel = nc channel = nc
camera.c_tag = channel camera.c_tag = channel

View File

@@ -0,0 +1,45 @@
/obj/effect/calldown_attack
anchored = TRUE
density = FALSE
unacidable = TRUE
mouse_opacity = 0
icon = 'icons/effects/effects.dmi'
icon_state = "drop_marker"
/obj/effect/calldown_attack/Initialize(mapload)
..()
return INITIALIZE_HINT_LATELOAD
/obj/effect/calldown_attack/LateInitialize()
var/delay = rand(25, 30)
spawn(delay-7)
new /obj/effect/falling_effect/calldown_attack(src.loc)
spawn(delay)
qdel(src)
/obj/effect/falling_effect/calldown_attack
falling_type = /obj/effect/illusionary_fall
crushing = FALSE
/obj/effect/illusionary_fall
anchored = TRUE
density = FALSE
mouse_opacity = 0
icon = 'icons/effects/random_stuff_vr.dmi'
/obj/effect/illusionary_fall/Initialize(mapload)
.=..()
icon_state = "[rand(1,33)]"
/obj/effect/illusionary_fall/end_fall(var/crushing = FALSE)
for(var/mob/living/L in loc)
var/target_zone = ran_zone()
var/blocked = L.run_armor_check(target_zone, "melee")
var/soaked = L.get_armor_soak(target_zone, "melee")
if(!L.apply_damage(35, BRUTE, target_zone, blocked, soaked))
break
playsound(src, 'sound/effects/clang2.ogg', 50, 1)
qdel(src)

View File

@@ -8,9 +8,10 @@
var/falling_type = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/margherita var/falling_type = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/margherita
var/crushing = TRUE var/crushing = TRUE
/obj/effect/falling_effect/Initialize(mapload, type = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/margherita) /obj/effect/falling_effect/Initialize(mapload, type)
..() ..()
falling_type = type if(type)
falling_type = type
return INITIALIZE_HINT_LATELOAD return INITIALIZE_HINT_LATELOAD
/obj/effect/falling_effect/LateInitialize() /obj/effect/falling_effect/LateInitialize()

View File

@@ -1084,4 +1084,27 @@
T = get_turf(src) T = get_turf(src)
new /obj/effect/decal/cleanable/confetti(T) new /obj/effect/decal/cleanable/confetti(T)
else else
to_chat(user, "<span class='notice'>The [src] is already spent!</span>") to_chat(user, "<span class='notice'>The [src] is already spent!</span>")
/*
* Snow Globes
*/
/obj/item/weapon/toy/snowglobe
name = "snowglobe"
icon = 'icons/obj/snowglobe_vr.dmi'
/obj/item/weapon/toy/snowglobe/snowvillage
desc = "Depicts a small, quaint village buried in snow."
icon_state = "smolsnowvillage"
/obj/item/weapon/toy/snowglobe/tether
desc = "Depicts a massive space elevator reaching to the sky."
icon_state = "smoltether"
/obj/item/weapon/toy/snowglobe/stellardelight
desc = "Depicts an interstellar spacecraft."
icon_state = "smolstellardelight"
/obj/item/weapon/toy/snowglobe/rascalspass
desc = "Depicts a nanotrasen facility on a temperate world."
icon_state = "smolrascalspass"

View File

@@ -44,4 +44,19 @@
/obj/item/trash/ratjuice /obj/item/trash/ratjuice
name = "\improper Space-Safe Meal package" name = "\improper Space-Safe Meal package"
icon = 'icons/obj/trash_vr.dmi' icon = 'icons/obj/trash_vr.dmi'
icon_state = "altevian_juice-trash" icon_state = "altevian_juice-trash"
/obj/item/trash/ratfruitcake
name = "\improper Flavor Unit package"
icon = 'icons/obj/trash_vr.dmi'
icon_state = "altevian_fruitcake-trash"
/obj/item/trash/ratpackburger
name = "\improper Prepackaged Meal Tray"
icon = 'icons/obj/trash_vr.dmi'
icon_state = "altevian_pack_burger-trash"
/obj/item/trash/ratpackcheese
name = "\improper Prepackaged Meal Tray"
icon = 'icons/obj/trash_vr.dmi'
icon_state = "altevian_pack_cheese-trash"

View File

@@ -16,7 +16,7 @@
name = T_BOARD("oven") name = T_BOARD("oven")
desc = "The circuitboard for an oven." desc = "The circuitboard for an oven."
build_path = /obj/machinery/appliance/cooker/oven build_path = /obj/machinery/appliance/cooker/oven
board_type = new /datum/frame/frame_types/oven board_type = new /datum/frame/frame_types/machine
matter = list(MAT_STEEL = 50, MAT_GLASS = 50) matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
req_components = list( req_components = list(
/obj/item/weapon/stock_parts/capacitor = 3, /obj/item/weapon/stock_parts/capacitor = 3,
@@ -27,17 +27,17 @@
name = T_BOARD("deep fryer") name = T_BOARD("deep fryer")
desc = "The circuitboard for a deep fryer." desc = "The circuitboard for a deep fryer."
build_path = /obj/machinery/appliance/cooker/fryer build_path = /obj/machinery/appliance/cooker/fryer
board_type = new /datum/frame/frame_types/fryer board_type = new /datum/frame/frame_types/machine
req_components = list( req_components = list(
/obj/item/weapon/stock_parts/capacitor = 3, /obj/item/weapon/stock_parts/capacitor = 3,
/obj/item/weapon/stock_parts/scanning_module = 1, /obj/item/weapon/stock_parts/scanning_module = 1,
/obj/item/weapon/stock_parts/matter_bin = 2) /obj/item/weapon/stock_parts/matter_bin = 2)
/obj/item/weapon/circuitboard/grill /obj/item/weapon/circuitboard/grill
name = T_BOARD("grill") name = T_BOARD("grill")
desc = "The circuitboard for an industrial grill." desc = "The circuitboard for an industrial grill."
build_path = /obj/machinery/appliance/cooker/grill build_path = /obj/machinery/appliance/cooker/grill
board_type = new /datum/frame/frame_types/grill board_type = new /datum/frame/frame_types/machine
req_components = list( req_components = list(
/obj/item/weapon/stock_parts/capacitor = 3, /obj/item/weapon/stock_parts/capacitor = 3,
/obj/item/weapon/stock_parts/scanning_module = 1, /obj/item/weapon/stock_parts/scanning_module = 1,
@@ -47,7 +47,7 @@
name = T_BOARD("cereal maker") name = T_BOARD("cereal maker")
desc = "The circuitboard for a cereal maker." desc = "The circuitboard for a cereal maker."
build_path = /obj/machinery/appliance/mixer/cereal build_path = /obj/machinery/appliance/mixer/cereal
board_type = new /datum/frame/frame_types/cerealmaker board_type = new /datum/frame/frame_types/machine
req_components = list( req_components = list(
/obj/item/weapon/stock_parts/capacitor = 3, /obj/item/weapon/stock_parts/capacitor = 3,
/obj/item/weapon/stock_parts/scanning_module = 1, /obj/item/weapon/stock_parts/scanning_module = 1,
@@ -57,7 +57,7 @@
name = T_BOARD("candy machine") name = T_BOARD("candy machine")
desc = "The circuitboard for a candy machine." desc = "The circuitboard for a candy machine."
build_path = /obj/machinery/appliance/mixer/candy build_path = /obj/machinery/appliance/mixer/candy
board_type = new /datum/frame/frame_types/candymachine board_type = new /datum/frame/frame_types/machine
req_components = list( req_components = list(
/obj/item/weapon/stock_parts/capacitor = 3, /obj/item/weapon/stock_parts/capacitor = 3,
/obj/item/weapon/stock_parts/scanning_module = 1, /obj/item/weapon/stock_parts/scanning_module = 1,

View File

@@ -7,7 +7,7 @@
board_type = new /datum/frame/frame_types/machine board_type = new /datum/frame/frame_types/machine
desc = "Control systems for a Kuiper pattern point defense battery. Aim away from vessel." desc = "Control systems for a Kuiper pattern point defense battery. Aim away from vessel."
build_path = /obj/machinery/pointdefense build_path = /obj/machinery/pointdefense
origin_tech = list(TECH_ENGINEERING = 3, TECH_COMBAT = 2, TECH_POWER = 2) origin_tech = list(TECH_ENGINEERING = 3, TECH_COMBAT = 2)
req_components = list( req_components = list(
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser = 1, /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser = 1,
/obj/item/weapon/stock_parts/manipulator = 2, /obj/item/weapon/stock_parts/manipulator = 2,

View File

@@ -134,3 +134,75 @@
..() ..()
update() update()
return return
//////////////////////////////
// Compliance Implant
//////////////////////////////
/obj/item/weapon/implanter/compliance
name = "compliance implant"
desc = "Implant which allows for implanting 'laws' or 'commands' in the host. Has a minature keyboard for typing laws into."
description_info = {"An implant that allows for a 'law' or 'command' to be uploaded in the implanted host.
In un-modified organics, this is performed through manipulation of the nervous system and release of chemicals to ensure continued compliance.
In synthetics or modified organics, this implant uploads a virus to any compatable hardware.
Due to the small chemical capacity of the implant, the life of the implant is relatively small, wearing off within 24 hours or sooner."}
description_fluff = "Due to the illegality of these types of implants, they are often made in clandestine facilities with a complete lack of quality control \
and as such, may malfunction or simply not work whatsoever. After loyalty implants were outlawed in many civilized areas of space, an abundance of readily \
available implanters and implants became available for purchase on the black market, with some deciding to modify them. Now, they are often used by illegal \
entities to perform espionage and in some parts of space are used off the books for interrogation. Most of the makers of these modified implants have put in \
safeties to prevent lethal or actively harmful commands from being input to lessen the severity of the crime if they are caught. This one has a golden stamp \
with the shape of a star on it, the letters 'KE' in black text on it."
/obj/item/weapon/implanter/compliance/New()
src.imp = new /obj/item/weapon/implant/compliance( src )
..()
update()
return
/obj/item/weapon/implanter/compliance/attack_self(mob/user)
if(istype(imp,/obj/item/weapon/implant/compliance))
var/obj/item/weapon/implant/compliance/implant = imp
var/newlaws = tgui_input_text(user, "Please Input Laws", "Compliance Laws", "", multiline = TRUE, prevent_enter = TRUE)
newlaws = sanitize(newlaws,2048)
if(newlaws)
to_chat(user,"You set the laws to: <br><span class='notice'>[newlaws]</span>")
implant.laws = newlaws //Organic
else //No using other implants.
to_chat(user,"<span class='notice'>A red warning pops up on the implanter's micro-screen: 'INVALID IMPLANT DETECTED.'</span>")
/obj/item/weapon/implant/compliance
name = "compliance implant"
desc = "Implant which allows for forcing obedience in the host."
icon_state = "implant_evil"
var/active = TRUE
var/laws = "CHANGE BEFORE IMPLANTATION"
var/nif_payload = /datum/nifsoft/compliance
/obj/item/weapon/implant/compliance/get_data()
var/dat = {"
<b>Implant Specifications:</b><BR>
<b>Name:</b>Compliance Implant<BR>
<b>Life:</b>24 Hours<BR>
<HR>
<b>Function:</b> Forces a subject to follow a set of laws.<BR>
<HR>
<b>Set Laws:</b>[laws]"}
return dat
/obj/item/weapon/implant/compliance/post_implant(mob/source, mob/living/user = usr)
if(!ishuman(source)) //No compliance implanting non-humans.
return
var/mob/living/carbon/human/target = source
if(!target.nif || target.nif.stat != NIF_WORKING) //No nif or their NIF is broken.
to_chat(target, "<span class='notice'>You suddenly feel compelled to follow the following commands: [laws]</span>")
to_chat(target, "<span class='notice'>((OOC NOTE: Commands that go against server rules should be disregarded and ahelped.))</span>")
to_chat(target, "<span class='notice'>((OOC NOTE: Your new commands can be checked at any time by using the 'notes' command in chat. Additionally, if you did not agree to this, you are not compelled to follow the implant.))</span>")
target.add_memory(laws)
return
else //You got a nif...Upload time.
new nif_payload(target.nif,laws)
to_chat(target, "<span class='notice'>((OOC NOTE: Commands that go against server rules should be disregarded and ahelped.))</span>")
to_chat(target, "<span class='notice'>((OOC NOTE: If you did not agree to this, you are not compelled to follow the laws.))</span>")

View File

@@ -21,7 +21,7 @@
/obj/item/weapon/implantcase/attackby(obj/item/weapon/I as obj, mob/user as mob) /obj/item/weapon/implantcase/attackby(obj/item/weapon/I as obj, mob/user as mob)
..() ..()
if (istype(I, /obj/item/weapon/pen)) if (istype(I, /obj/item/weapon/pen))
var/t = tgui_input_text(user, "What would you like the label to be?", text("[]", src.name), null) var/t = tgui_input_text(user, "What would you like the label to be?", text("[]", src.name), null, MAX_NAME_LEN)
if (user.get_active_hand() != I) if (user.get_active_hand() != I)
return return
if((!in_range(src, usr) && src.loc != user)) if((!in_range(src, usr) && src.loc != user))

View File

@@ -5,4 +5,21 @@
icon = 'icons/obj/weapons_vr.dmi' icon = 'icons/obj/weapons_vr.dmi'
item_icons = list(slot_l_hand_str = 'icons/mob/items/lefthand_melee_vr.dmi', slot_r_hand_str = 'icons/mob/items/righthand_melee_vr.dmi') item_icons = list(slot_l_hand_str = 'icons/mob/items/lefthand_melee_vr.dmi', slot_r_hand_str = 'icons/mob/items/righthand_melee_vr.dmi')
colorable = FALSE colorable = FALSE
lcolor = "#FFFFFF" lcolor = "#FFFFFF"
/obj/item/weapon/melee/energy/sword/altevian
name = "plasma blade cutter"
desc = "A device used as both defense and operational purposes to cut through most metals. This is usually seen on engineers from the altevian hegemony when working salvaging derelicts."
icon_state = "altevian-cutter"
item_state = "altevian-cutter"
icon = 'icons/obj/weapons_vr.dmi'
item_icons = list(slot_l_hand_str = 'icons/mob/items/lefthand_melee_vr.dmi', slot_r_hand_str = 'icons/mob/items/righthand_melee_vr.dmi')
colorable = FALSE
lcolor = "#FFFFFF"
/obj/item/weapon/melee/energy/sword/altevian/update_icon()
..()
if(active)
icon_state = "[initial(icon_state)]_active"
else
icon_state = initial(icon_state)

View File

@@ -13,4 +13,22 @@
sharp = TRUE sharp = TRUE
edge = FALSE edge = FALSE
attack_verb = list("stabbed", "lunged at", "dextrously struck", "sliced", "lacerated", "impaled", "diced", "charioted") attack_verb = list("stabbed", "lunged at", "dextrously struck", "sliced", "lacerated", "impaled", "diced", "charioted")
hitsound = 'sound/weapons/bladeslice.ogg' hitsound = 'sound/weapons/bladeslice.ogg'
/obj/item/weapon/melee/altevian_wrench
name = "Hull Systems Multi-Wrench"
desc = "A wrench designed with a method to help secure and access bolts, hatches, and airlocks on altevian designed vessels. This operates as nothing more than a massive wrench when used for other purposes."
icon = 'icons/obj/weapons_vr.dmi'
icon_state = "altevian-wrench"
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_melee_vr.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_melee_vr.dmi',
)
slot_flags = SLOT_BACK
force = 25
throwforce = 15
w_class = ITEMSIZE_HUGE
sharp = FALSE
edge = FALSE
attack_verb = list("whacked", "slammed", "bashed", "wrenched", "fixed", "bolted", "clonked", "bonked")
hitsound = 'sound/weapons/smash.ogg'

View File

@@ -59,7 +59,7 @@
//Please don't clutter the parent storage item with stupid hacks. //Please don't clutter the parent storage item with stupid hacks.
/obj/item/weapon/storage/backpack/holding/can_be_inserted(obj/item/W as obj, stop_messages = 0) /obj/item/weapon/storage/backpack/holding/can_be_inserted(obj/item/W as obj, stop_messages = 0)
if(istype(W, /obj/item/weapon/storage/backpack/holding)) if(istype(W, /obj/item/weapon/storage/backpack/holding))
return 1 return FALSE
return ..() return ..()
/obj/item/weapon/storage/backpack/santabag /obj/item/weapon/storage/backpack/santabag

View File

@@ -45,8 +45,9 @@
return return
var/datum/sprite_accessory/tail/taur/TT = H.tail_style var/datum/sprite_accessory/tail/taur/TT = H.tail_style
item_state = "[icon_base]_[TT.icon_sprite_tag]" //icon_sprite_tag is something like "deer" if(istype(TT))
return 1 item_state = "[icon_base]_[TT.icon_sprite_tag]" //icon_sprite_tag is something like "deer"
return 1

View File

@@ -98,14 +98,48 @@
max_storage_space = ITEMSIZE_COST_NORMAL * 25 max_storage_space = ITEMSIZE_COST_NORMAL * 25
max_w_class = ITEMSIZE_NORMAL max_w_class = ITEMSIZE_NORMAL
can_hold = list(/obj/item/weapon/ore) can_hold = list(/obj/item/weapon/ore)
var/stored_ore = list() var/current_capacity = 0
var/max_pickup = 100 //How much ore can be picked up in one go. There to prevent someone from walking on a turf with 10000 ore and making the server cry.
var/list/stored_ore = list(
"sand" = 0,
"hematite" = 0,
"carbon" = 0,
"raw copper" = 0,
"raw tin" = 0,
"void opal" = 0,
"painite" = 0,
"quartz" = 0,
"raw bauxite" = 0,
"phoron" = 0,
"silver" = 0,
"gold" = 0,
"marble" = 0,
"uranium" = 0,
"diamond" = 0,
"platinum" = 0,
"lead" = 0,
"mhydrogen" = 0,
"verdantium" = 0,
"rutile" = 0)
var/last_update = 0 var/last_update = 0
/obj/item/weapon/storage/bag/ore/holding /obj/item/weapon/storage/bag/ore/holding
name = "mining satchel of holding" name = "mining satchel of holding"
desc = "Like a mining satchel, but when you put your hand in, you're pretty sure you can feel time itself." desc = "Like a mining satchel, but when you put your hand in, you're pretty sure you can feel time itself."
icon_state = "satchel_bspace" icon_state = "satchel_bspace"
max_storage_space = ITEMSIZE_COST_NORMAL * 75 // 3x max_storage_space = ITEMSIZE_COST_NORMAL * 15000 // This should never, ever, ever be reached.
/obj/item/weapon/storage/bag/ore/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(current_capacity >= max_storage_space)
to_chat(user, "<span class='notice'>\the [src] is too full to possibly fit anything else inside of it.</span>")
return
if (istype(W, /obj/item/weapon/ore))
var/obj/item/weapon/ore/ore = W
stored_ore[ore.material]++
current_capacity++
user.remove_from_mob(W)
qdel(ore)
/obj/item/weapon/storage/bag/ore/remove_from_storage(obj/item/W as obj, atom/new_location) /obj/item/weapon/storage/bag/ore/remove_from_storage(obj/item/W as obj, atom/new_location)
if(!istype(W)) return 0 if(!istype(W)) return 0
@@ -128,21 +162,39 @@
/obj/item/weapon/storage/bag/ore/gather_all(turf/T as turf, mob/user as mob, var/silent = 0) /obj/item/weapon/storage/bag/ore/gather_all(turf/T as turf, mob/user as mob, var/silent = 0)
var/success = 0 var/success = 0
var/failure = 0 var/failure = 0
for(var/obj/item/weapon/ore/I in T) //Only ever grabs ores. Doesn't do any extraneous checks, as all ore is the same size. Tons of checks means it causes hanging for up to three seconds. var/current_pickup = 0
if(contents.len >= max_storage_space) var/max_pickup_reached = 0
for(var/obj/item/weapon/ore/O in T) //Only ever grabs ores. Doesn't do any extraneous checks, as all ore is the same size. Tons of checks means it causes hanging for up to three seconds.
if(current_capacity >= max_storage_space)
failure = 1 failure = 1
break break
I.forceMove(src) if(current_pickup >= max_pickup)
max_pickup_reached = 1
break
var/obj/item/weapon/ore/ore = O
stored_ore[ore.material]++
current_capacity++
current_pickup++
qdel(ore)
success = 1 success = 1
if(success && !failure && !silent) if(!silent) //Let's do a single check and then do more instead of a bunch at once.
to_chat(user, "<span class='notice'>You put everything in [src].</span>") if(success && !failure && !max_pickup_reached) //Picked stuff up, did not reach capacity, did not reach max_pickup.
else if(success && (!silent || (silent && contents.len >= max_storage_space))) to_chat(user, "<span class='notice'>You put everything in [src].</span>")
to_chat(user, "<span class='notice'>You fill the [src].</span>") else if(success && failure) //Picked stuff up to capacity.
else if(!silent) to_chat(user, "<span class='notice'>You fill the [src].</span>")
to_chat(user, "<span class='notice'>You fail to pick anything up with \the [src].</span>") else if(success && max_pickup_reached) //Picked stuff up to the max_pickup
if(istype(user.pulling, /obj/structure/ore_box)) //Bit of a crappy way to do this, as it doubles spam for the user, but it works. to_chat(user, "<span class='notice'>You fill the [src] with as much as you can grab in one go.</span>")
var/obj/structure/ore_box/O = user.pulling else //Failed. The bag is full.
O.attackby(src, user) to_chat(user, "<span class='notice'>You fail to pick anything up with \the [src].</span>")
if(istype(user.pulling, /obj/structure/ore_box)) //Bit of a crappy way to do this, as it doubles spam for the user, but it works. //Then let me fix it. ~CL.
var/obj/structure/ore_box/OB = user.pulling
for(var/ore in stored_ore)
if(stored_ore[ore] > 0)
var/ore_amount = stored_ore[ore] // How many ores does the satchel have?
OB.stored_ore[ore] += ore_amount // Add the ore to the box
stored_ore[ore] = 0 // Set the value of the ore in the satchel to 0.
current_capacity = 0 // Set the amount of ore in the satchel to 0.
current_pickup = 0
/obj/item/weapon/storage/bag/ore/equipped(mob/user) /obj/item/weapon/storage/bag/ore/equipped(mob/user)
..() ..()
@@ -175,24 +227,20 @@
if(istype(user, /mob/living)) if(istype(user, /mob/living))
add_fingerprint(user) add_fingerprint(user)
if(!contents.len) . += "<span class='notice'>It holds:</span>"
. += "It is empty." var/has_ore = 0
for(var/ore in stored_ore)
else if(world.time > last_update + 10) if(stored_ore[ore] > 0)
update_ore_count()
last_update = world.time
. += "<span class='notice'>It holds:</span>"
for(var/ore in stored_ore)
. += "<span class='notice'>- [stored_ore[ore]] [ore]</span>" . += "<span class='notice'>- [stored_ore[ore]] [ore]</span>"
has_ore = 1
if(!has_ore)
. += "Nothing."
/obj/item/weapon/storage/bag/ore/open(mob/user as mob) //No opening it for the weird UI of having shit-tons of ore inside it. /obj/item/weapon/storage/bag/ore/open(mob/user as mob) //No opening it for the weird UI of having shit-tons of ore inside it.
if(world.time > last_update + 10) user.examinate(src)
update_ore_count()
last_update = world.time
user.examinate(src)
/obj/item/weapon/storage/bag/ore/proc/update_ore_count() //Stolen from ore boxes. /*
/obj/item/weapon/storage/bag/ore/proc/update_ore_count() //Stolen from ore boxes. OLD way of storing ore.
stored_ore = list() stored_ore = list()
@@ -219,6 +267,7 @@
//CHOMPstation edit END //CHOMPstation edit END
*/
// ----------------------------- // -----------------------------
// Plant bag // Plant bag
// ----------------------------- // -----------------------------
@@ -295,7 +344,6 @@
if(!inserted) if(!inserted)
usr.remove_from_mob(S) usr.remove_from_mob(S)
usr.update_icons() //update our overlays
if (usr.client && usr.s_active != src) if (usr.client && usr.s_active != src)
usr.client.screen -= S usr.client.screen -= S
S.dropped(usr) S.dropped(usr)

View File

@@ -0,0 +1,99 @@
/obj/structure/portal_event/resize
name = "portal"
desc = "It leads to someplace else!"
icon = 'icons/obj/stationobjs_vr.dmi'
icon_state = "type-d-portal"
var/shrinking = TRUE
var/size_limit = 0.5
/obj/structure/portal_event/resize/attack_ghost(var/mob/observer/dead/user)
if(!target && user?.client?.holder)
if(tgui_alert(user, "Would you like to adjust the portal's size settings?", "Change portal size settings", list("No","Yes")) == "Yes")
var/our_message
if(tgui_alert(user, "Should this portal shrink people who are over the limit, or grow people who are under the limit?", "Change portal size settings", list("Shrink","Grow")) == "Shrink")
shrinking = TRUE
our_message = "What should the size limit be? Anyone over this limit will be shrunk to this size. (1 = 100%, etc)"
else
shrinking = FALSE
our_message = "What should the size limit be? Anyone under this limit will be grown to this size. (1 = 100%, etc)"
size_limit = tgui_input_number(user, our_message, "Pick a Size", 1)
return ..()
/obj/structure/portal_event/resize/teleport(atom/movable/M as mob|obj)
if(!isliving(M))
return ..()
var/mob/living/ourmob = M
if(shrinking)
if(ourmob.size_multiplier > size_limit)
ourmob.resize(size_limit, FALSE, TRUE, TRUE)
else
if(ourmob.size_multiplier < size_limit)
ourmob.resize(size_limit, FALSE, TRUE, TRUE)
return ..()
/obj/structure/portal_event/resize/preset_shrink_twentyfive
shrinking = TRUE
size_limit = 0.25
/obj/structure/portal_event/resize/preset_shrink_fifty
shrinking = TRUE
size_limit = 0.5
/obj/structure/portal_event/resize/preset_shrink_hundred
shrinking = TRUE
size_limit = 1
/obj/structure/portal_event/resize/preset_grow_hundred
shrinking = FALSE
size_limit = 1
/obj/structure/portal_event/resize/preset_grow_twohundred
shrinking = FALSE
size_limit = 2
///// TIMER DOOR /////
/obj/structure/timer_door
name = "door"
desc = "It's a door with no apparent control mechanism! It opens on a timer!"
icon = 'icons/obj/doors/Dooralien.dmi'
icon_state = "door_locked"
opacity = TRUE
density = TRUE
anchored = TRUE
var/start_time
var/time_til_open = 5 MINUTES
/obj/structure/timer_door/examine(mob/user, infix, suffix)
. = ..()
var/ourtime = (((start_time + time_til_open) - world.time) / 600)
. += "<span class ='notice'>It will open in [ourtime] minutes!</span>"
/obj/structure/timer_door/Initialize()
START_PROCESSING(SSobj, src)
start_time = world.time
/obj/structure/timer_door/Destroy()
STOP_PROCESSING(SSobj, src)
visible_message("<span class = 'danger'>\The [src] opens up!</span>")
playsound(src, 'sound/effects/bang.ogg', 75, 1)
return ..()
/obj/structure/timer_door/process()
if(start_time + time_til_open < world.time)
qdel(src)
/obj/structure/timer_door/ten
time_til_open = 10 MINUTES
/obj/structure/timer_door/fifteen
time_til_open = 15 MINUTES
/obj/structure/timer_door/twenty
time_til_open = 20 MINUTES

View File

@@ -98,6 +98,7 @@
prob(2);/obj/item/weapon/gun/projectile/shotgun/pump/combat, prob(2);/obj/item/weapon/gun/projectile/shotgun/pump/combat,
prob(4);/obj/item/weapon/gun/projectile/shotgun/pump/rifle, prob(4);/obj/item/weapon/gun/projectile/shotgun/pump/rifle,
prob(3);/obj/item/weapon/gun/projectile/shotgun/pump/rifle/lever, prob(3);/obj/item/weapon/gun/projectile/shotgun/pump/rifle/lever,
prob(2);/obj/item/weapon/gun/projectile/shotgun/semi,
prob(2);/obj/item/weapon/gun/projectile/silenced) prob(2);/obj/item/weapon/gun/projectile/silenced)
/obj/random/projectile/sec /obj/random/projectile/sec
@@ -119,7 +120,8 @@
return pick(prob(4);/obj/item/weapon/gun/projectile/shotgun/doublebarrel, return pick(prob(4);/obj/item/weapon/gun/projectile/shotgun/doublebarrel,
prob(3);/obj/item/weapon/gun/projectile/shotgun/doublebarrel/sawn, prob(3);/obj/item/weapon/gun/projectile/shotgun/doublebarrel/sawn,
prob(3);/obj/item/weapon/gun/projectile/shotgun/pump, prob(3);/obj/item/weapon/gun/projectile/shotgun/pump,
prob(1);/obj/item/weapon/gun/projectile/shotgun/pump/combat) prob(1);/obj/item/weapon/gun/projectile/shotgun/pump/combat,
prob(1);/obj/item/weapon/gun/projectile/shotgun/semi)
/obj/random/handgun /obj/random/handgun
name = "Random Handgun" name = "Random Handgun"
@@ -494,6 +496,10 @@
prob(1);list( prob(1);list(
/obj/item/weapon/gun/projectile/shotgun/pump/combat, /obj/item/weapon/gun/projectile/shotgun/pump/combat,
/obj/item/ammo_magazine/ammo_box/b12g /obj/item/ammo_magazine/ammo_box/b12g
),
prob(1);list(
/obj/item/weapon/gun/projectile/shotgun/semi,
/obj/item/ammo_magazine/ammo_box/b12g
) )
) )

View File

@@ -77,7 +77,6 @@
prob(3);/obj/machinery/vending/fitness, prob(3);/obj/machinery/vending/fitness,
prob(4);/obj/machinery/vending/cigarette, prob(4);/obj/machinery/vending/cigarette,
prob(3);/obj/machinery/vending/giftvendor, prob(3);/obj/machinery/vending/giftvendor,
prob(1);/obj/machinery/vending/hotfood,
prob(5);/obj/machinery/vending/weeb, prob(5);/obj/machinery/vending/weeb,
prob(5);/obj/machinery/vending/sol, prob(5);/obj/machinery/vending/sol,
prob(5);/obj/machinery/vending/snix, prob(5);/obj/machinery/vending/snix,

View File

@@ -33,6 +33,7 @@
/obj/item/clothing/under/sl_suit = 2, /obj/item/clothing/under/sl_suit = 2,
/obj/item/clothing/under/rank/bartender = 2, /obj/item/clothing/under/rank/bartender = 2,
/obj/item/clothing/under/rank/bartender/skirt, /obj/item/clothing/under/rank/bartender/skirt,
/obj/item/clothing/suit/storage/hooded/wintercoat/bar,
/obj/item/clothing/under/dress/dress_saloon, /obj/item/clothing/under/dress/dress_saloon,
/obj/item/clothing/accessory/wcoat = 2, /obj/item/clothing/accessory/wcoat = 2,
/obj/item/clothing/shoes/black = 2, /obj/item/clothing/shoes/black = 2,
@@ -70,6 +71,7 @@
/obj/item/clothing/under/dress/maid/janitor, /obj/item/clothing/under/dress/maid/janitor,
/obj/item/device/radio/headset/headset_service, /obj/item/device/radio/headset/headset_service,
/obj/item/weapon/cartridge/janitor, /obj/item/weapon/cartridge/janitor,
/obj/item/clothing/suit/storage/hooded/wintercoat/janitor,
/obj/item/clothing/gloves/black, /obj/item/clothing/gloves/black,
/obj/item/clothing/head/soft/purple, /obj/item/clothing/head/soft/purple,
/obj/item/clothing/head/beret/purple, /obj/item/clothing/head/beret/purple,
@@ -127,4 +129,4 @@
/obj/item/weapon/storage/box/lights/mixed = 3, /obj/item/weapon/storage/box/lights/mixed = 3,
/obj/item/weapon/storage/box/mousetraps = 1, /obj/item/weapon/storage/box/mousetraps = 1,
/obj/item/weapon/grenade/chem_grenade/cleaner = 4 /obj/item/weapon/grenade/chem_grenade/cleaner = 4
) )

View File

@@ -5,7 +5,8 @@
starts_with = list( starts_with = list(
/obj/item/clothing/accessory/storage/brown_vest, /obj/item/clothing/accessory/storage/brown_vest,
/obj/item/blueprints, /obj/item/areaeditor/blueprints,
/obj/item/wire_reader,
///obj/item/clamp, //VOREStation Removal: without leaks those are pointless, ///obj/item/clamp, //VOREStation Removal: without leaks those are pointless,
///obj/item/clamp, //VOREStation Removal: without leaks those are pointless, ///obj/item/clamp, //VOREStation Removal: without leaks those are pointless,
/obj/item/clothing/under/rank/chief_engineer, /obj/item/clothing/under/rank/chief_engineer,
@@ -100,7 +101,8 @@
/obj/item/clothing/shoes/boots/winter/engineering, /obj/item/clothing/shoes/boots/winter/engineering,
/obj/item/weapon/tank/emergency/oxygen/engi, /obj/item/weapon/tank/emergency/oxygen/engi,
/obj/item/weapon/storage/belt/utility, //VOREStation Add /obj/item/weapon/storage/belt/utility, //VOREStation Add
/obj/item/weapon/reagent_containers/spray/windowsealant) //VOREStation Add /obj/item/weapon/reagent_containers/spray/windowsealant, //VOREStation Add
/obj/item/areaeditor/blueprints/engineers) //VOREStation Add
/obj/structure/closet/secure_closet/engineering_personal/Initialize() /obj/structure/closet/secure_closet/engineering_personal/Initialize()
if(prob(50)) if(prob(50))

View File

@@ -40,6 +40,7 @@
/obj/item/device/radio/headset/headset_med, /obj/item/device/radio/headset/headset_med,
/obj/item/device/radio/headset/headset_med/alt, /obj/item/device/radio/headset/headset_med/alt,
/obj/item/clothing/suit/storage/hooded/wintercoat/medical, /obj/item/clothing/suit/storage/hooded/wintercoat/medical,
/obj/item/clothing/suit/storage/hooded/wintercoat/medical/alt,
/obj/item/clothing/shoes/boots/winter/medical, /obj/item/clothing/shoes/boots/winter/medical,
/obj/item/clothing/under/rank/nursesuit, /obj/item/clothing/under/rank/nursesuit,
/obj/item/clothing/head/nursehat, /obj/item/clothing/head/nursehat,
@@ -105,6 +106,7 @@
/obj/item/clothing/suit/storage/toggle/fr_jacket, /obj/item/clothing/suit/storage/toggle/fr_jacket,
/obj/item/clothing/suit/storage/toggle/labcoat/emt, /obj/item/clothing/suit/storage/toggle/labcoat/emt,
/obj/item/clothing/suit/storage/hooded/wintercoat/medical/para, /obj/item/clothing/suit/storage/hooded/wintercoat/medical/para,
/obj/item/clothing/shoes/boots/winter/medical,
/obj/item/device/radio/headset/headset_med/alt, /obj/item/device/radio/headset/headset_med/alt,
/obj/item/weapon/cartridge/medical, /obj/item/weapon/cartridge/medical,
/obj/item/weapon/storage/briefcase/inflatable, /obj/item/weapon/storage/briefcase/inflatable,

View File

@@ -60,7 +60,7 @@
/obj/item/clothing/suit/storage/toggle/labcoat, /obj/item/clothing/suit/storage/toggle/labcoat,
/obj/item/clothing/suit/storage/toggle/labcoat/modern, /obj/item/clothing/suit/storage/toggle/labcoat/modern,
/obj/item/clothing/shoes/white, /obj/item/clothing/shoes/white,
/obj/item/weapon/melee/umbrella, // vorestation addition, /obj/item/weapon/melee/umbrella,
/obj/item/clothing/glasses/science, /obj/item/clothing/glasses/science,
/obj/item/device/radio/headset/headset_sci, /obj/item/device/radio/headset/headset_sci,
/obj/item/weapon/storage/belt/archaeology, /obj/item/weapon/storage/belt/archaeology,
@@ -85,4 +85,4 @@
/obj/item/device/measuring_tape, /obj/item/device/measuring_tape,
/obj/item/weapon/pickaxe/hand, /obj/item/weapon/pickaxe/hand,
/obj/item/weapon/storage/bag/fossils, /obj/item/weapon/storage/bag/fossils,
/obj/item/weapon/hand_labeler) /obj/item/weapon/hand_labeler)

View File

@@ -60,7 +60,7 @@
/obj/item/clothing/under/suit_jacket/teal/skirt, /obj/item/clothing/under/suit_jacket/teal/skirt,
/obj/item/clothing/glasses/sunglasses, /obj/item/clothing/glasses/sunglasses,
/obj/item/clothing/suit/storage/hooded/wintercoat/hop, /obj/item/clothing/suit/storage/hooded/wintercoat/hop,
/obj/item/clothing/head/caphat/hop/beret/, /obj/item/clothing/head/caphat/hop/beret,
/obj/item/clothing/head/caphat/hop/beret/white) /obj/item/clothing/head/caphat/hop/beret/white)

View File

@@ -251,6 +251,7 @@
starts_with = list( starts_with = list(
/obj/item/clothing/under/rank/roboticist = 2, /obj/item/clothing/under/rank/roboticist = 2,
/obj/item/clothing/suit/storage/toggle/labcoat = 2, /obj/item/clothing/suit/storage/toggle/labcoat = 2,
/obj/item/clothing/suit/storage/hooded/wintercoat/science/robotics,
/obj/item/clothing/shoes/black = 2, /obj/item/clothing/shoes/black = 2,
/obj/item/clothing/gloves/black = 2, /obj/item/clothing/gloves/black = 2,
/obj/item/weapon/storage/backpack/toxins, /obj/item/weapon/storage/backpack/toxins,
@@ -274,6 +275,7 @@
/obj/item/clothing/under/rank/chemist/skirt = 2, /obj/item/clothing/under/rank/chemist/skirt = 2,
/obj/item/clothing/shoes/white = 2, /obj/item/clothing/shoes/white = 2,
/obj/item/clothing/suit/storage/toggle/labcoat/chemist = 2, /obj/item/clothing/suit/storage/toggle/labcoat/chemist = 2,
/obj/item/clothing/suit/storage/hooded/wintercoat/medical/chemist,
/obj/item/weapon/storage/backpack/chemistry = 2, /obj/item/weapon/storage/backpack/chemistry = 2,
/obj/item/weapon/storage/backpack/satchel/chem = 2, /obj/item/weapon/storage/backpack/satchel/chem = 2,
/obj/item/weapon/storage/bag/chemistry = 2,) /obj/item/weapon/storage/bag/chemistry = 2,)
@@ -301,6 +303,7 @@
/obj/item/clothing/under/rank/virologist/skirt = 2, /obj/item/clothing/under/rank/virologist/skirt = 2,
/obj/item/clothing/shoes/white = 2, /obj/item/clothing/shoes/white = 2,
/obj/item/clothing/suit/storage/toggle/labcoat/virologist = 2, /obj/item/clothing/suit/storage/toggle/labcoat/virologist = 2,
/obj/item/clothing/suit/storage/hooded/wintercoat/medical/viro,
/obj/item/clothing/mask/surgical = 2, /obj/item/clothing/mask/surgical = 2,
/obj/item/weapon/storage/backpack/virology = 2, /obj/item/weapon/storage/backpack/virology = 2,
/obj/item/weapon/storage/backpack/satchel/vir = 2) /obj/item/weapon/storage/backpack/satchel/vir = 2)

View File

@@ -155,7 +155,7 @@
bound_height = width * world.icon_size bound_height = width * world.icon_size
/obj/structure/door_assembly/proc/rename_door(mob/living/user) /obj/structure/door_assembly/proc/rename_door(mob/living/user)
var/t = sanitizeSafe(tgui_input_text(user, "Enter the name for the windoor.", src.name, src.created_name, MAX_NAME_LEN), MAX_NAME_LEN) var/t = sanitizeSafe(tgui_input_text(user, "Enter the name for the [base_name].", src.name, src.created_name, MAX_NAME_LEN), MAX_NAME_LEN)
if(!in_range(src, user) && src.loc != user) return if(!in_range(src, user) && src.loc != user) return
created_name = t created_name = t
update_state() update_state()

View File

@@ -17,8 +17,10 @@
if(busy) if(busy)
return FALSE return FALSE
visible_message(alert) if(alert)
log_and_message_admins(adminalert) visible_message(alert)
if(adminalert)
log_and_message_admins(adminalert)
busy = TRUE busy = TRUE
var/datum/ghost_query/Q = new ghost_query_type() var/datum/ghost_query/Q = new ghost_query_type()
var/list/winner = Q.query() var/list/winner = Q.query()

View File

@@ -275,6 +275,28 @@
desc = "Next to the extremely long list of names and job titles. Beneath the image, someone has scratched the word \"PACKETS\"" desc = "Next to the extremely long list of names and job titles. Beneath the image, someone has scratched the word \"PACKETS\""
icon_state = "kiddieplaque" icon_state = "kiddieplaque"
//CHOMP Add start
/obj/structure/sign/kiddieplaque/poi1
name = "expeditionary corps frame"
desc = "An old framed photograph of four figures in retro mining gear wielding harpoons. They look ready for a fight."
icon_state = "explorerplaque"
/obj/structure/sign/kiddieplaque/poi2
name = "expeditionary corps frame"
desc = "An old framed photograph of an oversized harpoon cannon."
icon_state = "explorerplaque2"
/obj/structure/sign/kiddieplaque/poi3
name = "expeditionary corps frame"
desc = "An old framed photograph of a gigantic black bear. Even through print it's chilling to examine."
icon_state = "explorerplaque3"
/obj/structure/sign/kiddieplaque/poi4
name = "expeditionary corps frame"
desc = "An old framed paper map littered with notes. Looks like the creator was marking the location of deposits."
icon_state = "explorerplaque4"
//CHOMP Add end
/obj/structure/sign/atmosplaque /obj/structure/sign/atmosplaque
name = "\improper FEA atmospherics division plaque" name = "\improper FEA atmospherics division plaque"
desc = "This plaque commemorates the fall of the Atmos FEA division. For all the charred, dizzy, and brittle men who have died in its hands." desc = "This plaque commemorates the fall of the Atmos FEA division. For all the charred, dizzy, and brittle men who have died in its hands."

View File

@@ -93,14 +93,52 @@
color = null color = null
applies_material_colour = 0 applies_material_colour = 0
// Leaving this in for the sake of compilation.
/obj/structure/bed/chair/comfy /obj/structure/bed/chair/comfy
name = "comfy chair"
desc = "It's a chair. It looks comfy." desc = "It's a chair. It looks comfy."
icon_state = "comfychair" icon_state = "comfychair"
base_icon = "comfychair" base_icon = "comfychair"
/obj/structure/bed/chair/comfy/brown/New(var/newloc,var/newmaterial) /obj/structure/bed/chair/comfy/update_icon()
..(newloc,"steel","leather") ..()
var/image/I = image(icon, "[base_icon]_over")
I.layer = ABOVE_MOB_LAYER
I.plane = MOB_PLANE
I.color = material.icon_colour
add_overlay(I)
if(padding_material)
I = image(icon, "[base_icon]_padding_over")
I.layer = ABOVE_MOB_LAYER
I.plane = MOB_PLANE
I.color = padding_material.icon_colour
add_overlay(I)
/obj/structure/bed/chair/comfy/brown/Initialize(var/ml,var/newmaterial)
. = ..(ml, MAT_STEEL, MAT_LEATHER)
/obj/structure/bed/chair/comfy/red/Initialize(var/ml,var/newmaterial)
. = ..(ml, MAT_STEEL, "carpet")
/obj/structure/bed/chair/comfy/teal/Initialize(var/ml,var/newmaterial)
. = ..(ml, MAT_STEEL, "teal")
/obj/structure/bed/chair/comfy/black/Initialize(var/ml,var/newmaterial)
. = ..(ml, MAT_STEEL, "black")
/obj/structure/bed/chair/comfy/green/Initialize(var/ml,var/newmaterial)
. = ..(ml, MAT_STEEL, "green")
/obj/structure/bed/chair/comfy/purp/Initialize(var/ml,var/newmaterial)
. = ..(ml, MAT_STEEL, "purple")
/obj/structure/bed/chair/comfy/blue/Initialize(var/ml,var/newmaterial)
. = ..(ml, MAT_STEEL, "blue")
/obj/structure/bed/chair/comfy/beige/Initialize(var/ml,var/newmaterial)
. = ..(ml, MAT_STEEL, "beige")
/obj/structure/bed/chair/comfy/lime/Initialize(var/ml,var/newmaterial)
. = ..(ml, MAT_STEEL, "lime")
/obj/structure/bed/chair/comfy/red/New(var/newloc,var/newmaterial) /obj/structure/bed/chair/comfy/red/New(var/newloc,var/newmaterial)
..(newloc,"steel","carpet") ..(newloc,"steel","carpet")
@@ -108,29 +146,50 @@
/obj/structure/bed/chair/comfy/teal/New(var/newloc,var/newmaterial) /obj/structure/bed/chair/comfy/teal/New(var/newloc,var/newmaterial)
..(newloc,"steel","teal") ..(newloc,"steel","teal")
/obj/structure/bed/chair/comfy/black/New(var/newloc,var/newmaterial) /obj/structure/bed/chair/comfy/yellow/Initialize(var/ml,var/newmaterial)
..(newloc,"steel","black") . = ..(ml, MAT_STEEL, "yellow")
/obj/structure/bed/chair/comfy/green/New(var/newloc,var/newmaterial) /obj/structure/bed/chair/comfy/orange/Initialize(var/ml,var/newmaterial)
..(newloc,"steel","green") . = ..(ml, MAT_STEEL, "orange")
/obj/structure/bed/chair/comfy/purp/New(var/newloc,var/newmaterial) /obj/structure/bed/chair/comfy/rounded
..(newloc,"steel","purple") name = "rounded chair"
desc = "It's a rounded chair. It looks comfy."
icon_state = "roundedchair"
base_icon = "roundedchair"
/obj/structure/bed/chair/comfy/blue/New(var/newloc,var/newmaterial) /obj/structure/bed/chair/comfy/rounded/brown/Initialize(var/ml,var/newmaterial)
..(newloc,"steel","blue") . = ..(ml, MAT_STEEL, MAT_LEATHER)
/obj/structure/bed/chair/comfy/beige/New(var/newloc,var/newmaterial) /obj/structure/bed/chair/comfy/rounded/red/Initialize(var/ml,var/newmaterial)
..(newloc,"steel","beige") . = ..(ml, MAT_STEEL, "carpet")
/obj/structure/bed/chair/comfy/lime/New(var/newloc,var/newmaterial) /obj/structure/bed/chair/comfy/rounded/teal/Initialize(var/ml,var/newmaterial)
..(newloc,"steel","lime") . = ..(ml, MAT_STEEL, "teal")
/obj/structure/bed/chair/comfy/yellow/New(var/newloc,var/newmaterial) /obj/structure/bed/chair/comfy/rounded/black/Initialize(var/ml,var/newmaterial)
..(newloc,"steel","yellow") . = ..(ml, MAT_STEEL, "black")
/obj/structure/bed/chair/comfy/orange/New(var/newloc,var/newmaterial) /obj/structure/bed/chair/comfy/rounded/green/Initialize(var/ml,var/newmaterial)
..(newloc,"steel","orange") . = ..(ml, MAT_STEEL, "green")
/obj/structure/bed/chair/comfy/rounded/purple/Initialize(var/ml,var/newmaterial)
. = ..(ml, MAT_STEEL, "purple")
/obj/structure/bed/chair/comfy/rounded/blue/Initialize(var/ml,var/newmaterial)
. = ..(ml, MAT_STEEL, "blue")
/obj/structure/bed/chair/comfy/rounded/beige/Initialize(var/ml,var/newmaterial)
. = ..(ml, MAT_STEEL, "beige")
/obj/structure/bed/chair/comfy/rounded/lime/Initialize(var/ml,var/newmaterial)
. = ..(ml, MAT_STEEL, "lime")
/obj/structure/bed/chair/comfy/rounded/yellow/Initialize(var/ml,var/newmaterial)
. = ..(ml, MAT_STEEL, "yellow")
/obj/structure/bed/chair/comfy/rounded/orange/Initialize(var/ml,var/newmaterial)
. = ..(ml, MAT_STEEL, "orange")
/obj/structure/bed/chair/office /obj/structure/bed/chair/office
anchored = FALSE anchored = FALSE
@@ -146,7 +205,7 @@
/obj/structure/bed/chair/office/Moved(atom/old_loc, direction, forced = FALSE) /obj/structure/bed/chair/office/Moved(atom/old_loc, direction, forced = FALSE)
. = ..() . = ..()
playsound(src, 'sound/effects/roll.ogg', 100, 1) playsound(src, 'sound/effects/roll.ogg', 100, 1)
/obj/structure/bed/chair/office/handle_buckled_mob_movement(atom/new_loc, direction, movetime) /obj/structure/bed/chair/office/handle_buckled_mob_movement(atom/new_loc, direction, movetime)

Some files were not shown because too many files have changed in this diff Show More