Files
Bubberstation/code/game/objects/items/RCD.dm
uraniummeltdown 09be3e9b6b Airlock Construction Update (#33152)
* removed typetext and icontext vars from door assemblies, airlock painter no longer works on door assemblies
removed 'anchored = TRUE, state = 1' copypasta from door assemblies
door assemblies update their name more regularly during construction
added new airlock types to airlock painter on airlocks, and to the RCD
airlock assemblies built with metal are now in a list, you can build many more airlocks
vault door assemblies can be built with 4 plasteel
added a solid version of station2 airlocks, renamed to "public airlock"
glass and mineral sheets are now able to be welded out of door assemblies

* find n replace airlock/glass to airlock/glass_public in maps
door_assembly_glass to door_assembly_public

* made highsec airlocks built with 6 plasteel, removed from RCD and airlock painter
vault doors built with 8 plasteel
removed redundant vars in airlock_types.dm
reverts the dumb rglass 'replacement' addition in door assembly construction

* moved airlock assembly defines to construction defines file
fixed incorrectly named shuttle airlock glass_closed and maint panel protected closed overlays
improved examination message for glass/minerals present in assembly

* airlocks take their dir from the assembly when built from assembly
removed "vertical" variant of survival pod airlock, unneeded
survival pod airlock assembly can have glass applied
solid and glass overlays for survival pod airlocks

* OOPs some airlocks, removes a duplicate door assembly, removes some var edits on maps for a new glass type

* turn copied door assembly code into a proc
some feedback during door assembly construction
door assembly created airlock takes name from base_name if no custom name
moved plasma airlock proc to airlock_types.dm
2017-12-10 22:23:43 +01:00

632 lines
20 KiB
Plaintext

#define GLOW_MODE 3
#define LIGHT_MODE 2
#define REMOVE_MODE 1
/*
CONTAINS:
RCD
ARCD
*/
/obj/item/construction
name = "not for ingame use"
desc = "A device used to rapidly build and deconstruct. Reload with metal, plasteel, glass or compressed matter cartridges."
opacity = 0
density = FALSE
anchored = FALSE
flags_1 = CONDUCT_1 | NOBLUDGEON_1
force = 0
throwforce = 10
throw_speed = 3
throw_range = 5
w_class = WEIGHT_CLASS_NORMAL
materials = list(MAT_METAL=100000)
req_access_txt = "11"
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50)
resistance_flags = FIRE_PROOF
var/datum/effect_system/spark_spread/spark_system
var/matter = 0
var/max_matter = 100
var/sheetmultiplier = 4 //Controls the amount of matter added for each glass/metal sheet, triple for plasteel
var/plasteelmultiplier = 3 //Plasteel is worth 3 times more than glass or metal
var/no_ammo_message = "<span class='warning'>The \'Low Ammo\' light on the device blinks yellow.</span>"
/obj/item/construction/Initialize()
. = ..()
spark_system = new /datum/effect_system/spark_spread
spark_system.set_up(5, 0, src)
spark_system.attach(src)
/obj/item/construction/examine(mob/user)
..()
to_chat(user, "\A [src]. It currently holds [matter]/[max_matter] matter-units." )
/obj/item/construction/Destroy()
QDEL_NULL(spark_system)
. = ..()
/obj/item/construction/attackby(obj/item/W, mob/user, params)
if(iscyborg(user))
return
var/loaded = 0
if(istype(W, /obj/item/rcd_ammo))
var/obj/item/rcd_ammo/R = W
if((matter + R.ammoamt) > max_matter)
to_chat(user, "<span class='warning'>[src] can't hold any more matter-units!</span>")
return
qdel(W)
matter += R.ammoamt
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
loaded = 1
else if(istype(W, /obj/item/stack/sheet/metal) || istype(W, /obj/item/stack/sheet/glass))
loaded = loadwithsheets(W, sheetmultiplier, user)
else if(istype(W, /obj/item/stack/sheet/plasteel))
loaded = loadwithsheets(W, plasteelmultiplier*sheetmultiplier, user) //Plasteel is worth 3 times more than glass or metal
if(loaded)
to_chat(user, "<span class='notice'>[src] now holds [matter]/[max_matter] matter-units.</span>")
else
return ..()
/obj/item/construction/proc/loadwithsheets(obj/item/stack/sheet/S, value, mob/user)
var/maxsheets = round((max_matter-matter)/value) //calculate the max number of sheets that will fit in RCD
if(maxsheets > 0)
var/amount_to_use = min(S.amount, maxsheets)
S.use(amount_to_use)
matter += value*amount_to_use
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
to_chat(user, "<span class='notice'>You insert [amount_to_use] [S.name] sheets into [src]. </span>")
return 1
to_chat(user, "<span class='warning'>You can't insert any more [S.name] sheets into [src]!</span>")
return 0
/obj/item/construction/proc/activate()
playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
/obj/item/construction/attack_self(mob/user)
playsound(src.loc, 'sound/effects/pop.ogg', 50, 0)
if(prob(20))
spark_system.start()
/obj/item/construction/proc/useResource(amount, mob/user)
if(matter < amount)
if(user)
to_chat(user, no_ammo_message)
return 0
matter -= amount
update_icon()
return 1
/obj/item/construction/proc/checkResource(amount, mob/user)
. = matter >= amount
if(!. && user)
to_chat(user, no_ammo_message)
return .
/obj/item/construction/proc/range_check(atom/A, mob/user)
if(!(A in view(7, get_turf(user))))
to_chat(user, "<span class='warning'>The \'Out of Range\' light on [src] blinks red.</span>")
return FALSE
else
return TRUE
/obj/item/construction/proc/prox_check(proximity)
if(proximity)
return TRUE
else
return FALSE
/obj/item/construction/rcd
name = "rapid-construction-device (RCD)"
icon = 'icons/obj/tools.dmi'
icon_state = "rcd"
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
max_matter = 160
flags_2 = NO_MAT_REDEMPTION_2
var/mode = 1
var/ranged = FALSE
var/airlock_type = /obj/machinery/door/airlock
var/airlock_glass = FALSE // So the floor's rcd_act knows how much ammo to use
var/window_type = /obj/structure/window/fulltile
var/advanced_airlock_setting = 1 //Set to 1 if you want more paintjobs available
var/list/conf_access = null
var/use_one_access = 0 //If the airlock should require ALL or only ONE of the listed accesses.
var/delay_mod = 1
var/canRturf = FALSE //Variable for R walls to deconstruct them
/obj/item/construction/rcd/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] sets the RCD to 'Wall' and points it down [user.p_their()] throat! It looks like [user.p_theyre()] trying to commit suicide..</span>")
return (BRUTELOSS)
/obj/item/construction/rcd/verb/toggle_window_type()
set name = "Toggle Window Type"
set category = "Object"
set src in usr // What does this do?
var/window_type_name
if (window_type == /obj/structure/window/fulltile)
window_type = /obj/structure/window/reinforced/fulltile
window_type_name = "reinforced glass"
else
window_type = /obj/structure/window/fulltile
window_type_name = "glass"
to_chat(usr, "<span class='notice'>You change \the [src]'s window mode to [window_type_name].</span>")
/obj/item/construction/rcd/verb/change_airlock_access()
set name = "Change Airlock Access"
set category = "Object"
set src in usr
if (!ishuman(usr) && !usr.has_unlimited_silicon_privilege)
return ..(usr)
var/t1 = text("")
if(use_one_access)
t1 += "Restriction Type: <a href='?src=[REF(src)];access=one'>At least one access required</a><br>"
else
t1 += "Restriction Type: <a href='?src=[REF(src)];access=one'>All accesses required</a><br>"
t1 += "<a href='?src=[REF(src)];access=all'>Remove All</a><br>"
var/accesses = ""
accesses += "<div align='center'><b>Access</b></div>"
accesses += "<table style='width:100%'>"
accesses += "<tr>"
for(var/i = 1; i <= 7; i++)
accesses += "<td style='width:14%'><b>[get_region_accesses_name(i)]:</b></td>"
accesses += "</tr><tr>"
for(var/i = 1; i <= 7; i++)
accesses += "<td style='width:14%' valign='top'>"
for(var/A in get_region_accesses(i))
if(A in conf_access)
accesses += "<a href='?src=[REF(src)];access=[A]'><font color=\"red\">[replacetext(get_access_desc(A), " ", "&nbsp")]</font></a> "
else
accesses += "<a href='?src=[REF(src)];access=[A]'>[replacetext(get_access_desc(A), " ", "&nbsp")]</a> "
accesses += "<br>"
accesses += "</td>"
accesses += "</tr></table>"
t1 += "<tt>[accesses]</tt>"
t1 += "<p><a href='?src=[REF(src)];close=1'>Close</a></p>\n"
var/datum/browser/popup = new(usr, "airlock_electronics", "Access Control", 900, 500)
popup.set_content(t1)
popup.set_title_image(usr.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
onclose(usr, "airlock")
/obj/item/construction/rcd/Topic(href, href_list)
..()
if (usr.stat || usr.restrained())
return
if (href_list["close"])
usr << browse(null, "window=airlock")
return
if (href_list["access"])
toggle_access(href_list["access"])
change_airlock_access()
/obj/item/construction/rcd/proc/toggle_access(acc)
if (acc == "all")
conf_access = null
else if(acc == "one")
use_one_access = !use_one_access
else
var/req = text2num(acc)
if (conf_access == null)
conf_access = list()
if (!(req in conf_access))
conf_access += req
else
conf_access -= req
if (!conf_access.len)
conf_access = null
/obj/item/construction/rcd/verb/change_airlock_setting()
set name = "Change Airlock Setting"
set category = "Object"
set src in usr
var/airlockcat = input(usr, "Select whether the airlock is solid or glass.") in list("Solid", "Glass")
switch(airlockcat)
if("Solid")
if(advanced_airlock_setting == 1)
var/airlockpaint = input(usr, "Select the type of the airlock.") in list("Standard", "Public", "Engineering", "Atmospherics", "Security", "Command", "Medical", "Research", "Freezer", "Science", "Virology", "Mining", "Maintenance", "External", "External Maintenance", "Airtight Hatch", "Maintenance Hatch")
switch(airlockpaint)
if("Standard")
airlock_type = /obj/machinery/door/airlock
if("Public")
airlock_type = /obj/machinery/door/airlock/public
if("Engineering")
airlock_type = /obj/machinery/door/airlock/engineering
if("Atmospherics")
airlock_type = /obj/machinery/door/airlock/atmos
if("Security")
airlock_type = /obj/machinery/door/airlock/security
if("Command")
airlock_type = /obj/machinery/door/airlock/command
if("Medical")
airlock_type = /obj/machinery/door/airlock/medical
if("Research")
airlock_type = /obj/machinery/door/airlock/research
if("Freezer")
airlock_type = /obj/machinery/door/airlock/freezer
if("Science")
airlock_type = /obj/machinery/door/airlock/science
if("Virology")
airlock_type = /obj/machinery/door/airlock/virology
if("Mining")
airlock_type = /obj/machinery/door/airlock/mining
if("Maintenance")
airlock_type = /obj/machinery/door/airlock/maintenance
if("External")
airlock_type = /obj/machinery/door/airlock/external
if("External Maintenance")
airlock_type = /obj/machinery/door/airlock/maintenance/external
if("Airtight Hatch")
airlock_type = /obj/machinery/door/airlock/hatch
if("Maintenance Hatch")
airlock_type = /obj/machinery/door/airlock/maintenance_hatch
airlock_glass = FALSE
else
airlock_type = /obj/machinery/door/airlock
airlock_glass = FALSE
if("Glass")
if(advanced_airlock_setting == 1)
var/airlockpaint = input(usr, "Select the type of the airlock.") in list("Standard", "Public", "Engineering", "Atmospherics", "Security", "Command", "Medical", "Research", "Science", "Virology", "Mining", "Maintenance", "External", "External Maintenance")
switch(airlockpaint)
if("Standard")
airlock_type = /obj/machinery/door/airlock/glass
if("Public")
airlock_type = /obj/machinery/door/airlock/public/glass
if("Engineering")
airlock_type = /obj/machinery/door/airlock/glass_engineering
if("Atmospherics")
airlock_type = /obj/machinery/door/airlock/glass_atmos
if("Security")
airlock_type = /obj/machinery/door/airlock/glass_security
if("Command")
airlock_type = /obj/machinery/door/airlock/glass_command
if("Medical")
airlock_type = /obj/machinery/door/airlock/glass_medical
if("Research")
airlock_type = /obj/machinery/door/airlock/glass_research
if("Science")
airlock_type = /obj/machinery/door/airlock/glass_science
if("Virology")
airlock_type = /obj/machinery/door/airlock/glass_virology
if("Mining")
airlock_type = /obj/machinery/door/airlock/glass_mining
if("Maintenance")
airlock_type = /obj/machinery/door/airlock/glass_maintenance
if("External")
airlock_type = /obj/machinery/door/airlock/external/glass
if("External Maintenance")
airlock_type = /obj/machinery/door/airlock/maintenance/external/glass
airlock_glass = TRUE
else
airlock_type = /obj/machinery/door/airlock/glass
airlock_glass = TRUE
else
airlock_type = /obj/machinery/door/airlock
airlock_glass = FALSE
/obj/item/construction/rcd/proc/rcd_create(atom/A, mob/user)
var/list/rcd_results = A.rcd_vals(user, src)
if(!rcd_results)
return FALSE
if(do_after(user, rcd_results["delay"] * delay_mod, target = A))
if(checkResource(rcd_results["cost"], user))
if(A.rcd_act(user, src, rcd_results["mode"]))
useResource(rcd_results["cost"], user)
activate()
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
return TRUE
/obj/item/construction/rcd/New()
..()
GLOB.rcd_list += src
/obj/item/construction/rcd/Destroy()
GLOB.rcd_list -= src
. = ..()
/obj/item/construction/rcd/attack_self(mob/user)
..()
switch(mode)
if(1)
mode = 2
to_chat(user, "<span class='notice'>You change RCD's mode to 'Airlock'.</span>")
if(2)
mode = 3
to_chat(user, "<span class='notice'>You change RCD's mode to 'Deconstruct'.</span>")
if(3)
mode = 4
to_chat(user, "<span class='notice'>You change RCD's mode to 'Grilles & Windows'.</span>")
if(4)
mode = 1
to_chat(user, "<span class='notice'>You change RCD's mode to 'Floor & Walls'.</span>")
/obj/item/construction/rcd/proc/target_check(atom/A, mob/user) // only returns true for stuff the device can actually work with
if((isturf(A) && A.density && mode==RCD_DECONSTRUCT) || (isturf(A) && !A.density) || (istype(A, /obj/machinery/door/airlock) && mode==RCD_DECONSTRUCT) || istype(A, /obj/structure/grille) || (istype(A, /obj/structure/window) && mode==RCD_DECONSTRUCT) || istype(A, /obj/structure/girder))
return TRUE
else
return FALSE
/obj/item/construction/rcd/afterattack(atom/A, mob/user, proximity)
if(!prox_check(proximity))
return
rcd_create(A, user)
/obj/item/construction/rcd/proc/detonate_pulse()
audible_message("<span class='danger'><b>[src] begins to vibrate and \
buzz loudly!</b></span>","<span class='danger'><b>[src] begins \
vibrating violently!</b></span>")
// 5 seconds to get rid of it
addtimer(CALLBACK(src, .proc/detonate_pulse_explode), 50)
/obj/item/construction/rcd/proc/detonate_pulse_explode()
explosion(src, 0, 0, 3, 1, flame_range = 1)
qdel(src)
/obj/item/construction/rcd/borg
no_ammo_message = "<span class='warning'>Insufficient charge.</span>"
desc = "A device used to rapidly build walls and floors."
canRturf = TRUE
/obj/item/construction/rcd/borg/useResource(amount, mob/user)
if(!iscyborg(user))
return 0
var/mob/living/silicon/robot/borgy = user
if(!borgy.cell)
if(user)
to_chat(user, no_ammo_message)
return 0
. = borgy.cell.use(amount * 72) //borgs get 1.3x the use of their RCDs
if(!. && user)
to_chat(user, no_ammo_message)
return .
/obj/item/construction/rcd/borg/checkResource(amount, mob/user)
if(!iscyborg(user))
return 0
var/mob/living/silicon/robot/borgy = user
if(!borgy.cell)
if(user)
to_chat(user, no_ammo_message)
return 0
. = borgy.cell.charge >= (amount * 72)
if(!. && user)
to_chat(user, no_ammo_message)
return .
/obj/item/construction/rcd/loaded
matter = 160
/obj/item/construction/rcd/combat
name = "industrial RCD"
max_matter = 500
matter = 500
canRturf = TRUE
/obj/item/rcd_ammo
name = "compressed matter cartridge"
desc = "Highly compressed matter for the RCD."
icon = 'icons/obj/ammo.dmi'
icon_state = "rcd"
item_state = "rcdammo"
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
materials = list(MAT_METAL=12000, MAT_GLASS=8000)
var/ammoamt = 40
/obj/item/rcd_ammo/large
materials = list(MAT_METAL=48000, MAT_GLASS=32000)
ammoamt = 160
/obj/item/construction/rcd/combat/admin
name = "admin RCD"
max_matter = INFINITY
matter = INFINITY
// Ranged RCD
/obj/item/construction/rcd/arcd
name = "advanced rapid-construction-device (ARCD)"
desc = "A prototype RCD with ranged capability and extended capacity. Reload with metal, plasteel, glass or compressed matter cartridges."
max_matter = 300
matter = 300
delay_mod = 0.6
ranged = TRUE
icon_state = "arcd"
item_state = "rcd"
/obj/item/construction/rcd/arcd/afterattack(atom/A, mob/user)
if(!range_check(A,user))
return
if(target_check(A,user))
user.Beam(A,icon_state="rped_upgrade",time=30)
rcd_create(A,user)
// RAPID LIGHTING DEVICE
/obj/item/construction/rld
name = "rapid-light-device (RLD)"
desc = "A device used to rapidly provide lighting sources to an area. Reload with metal, plasteel, glass or compressed matter cartridges."
icon = 'icons/obj/tools.dmi'
icon_state = "rld-5"
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
matter = 200
max_matter = 200
var/mode = LIGHT_MODE
actions_types = list(/datum/action/item_action/pick_color)
var/wallcost = 10
var/floorcost = 15
var/launchcost = 5
var/deconcost = 10
var/walldelay = 10
var/floordelay = 10
var/decondelay = 15
var/color_choice = null
/obj/item/construction/rld/ui_action_click(mob/user, var/datum/action/A)
if(istype(A, /datum/action/item_action/pick_color))
color_choice = input(user,"Choose Color") as color
else
..()
/obj/item/construction/rld/update_icon()
icon_state = "rld-[round(matter/35)]"
..()
/obj/item/construction/rld/attack_self(mob/user)
..()
switch(mode)
if(REMOVE_MODE)
mode = LIGHT_MODE
to_chat(user, "<span class='notice'>You change RLD's mode to 'Permanent Light Construction'.</span>")
if(LIGHT_MODE)
mode = GLOW_MODE
to_chat(user, "<span class='notice'>You change RLD's mode to 'Light Launcher'.</span>")
if(GLOW_MODE)
mode = REMOVE_MODE
to_chat(user, "<span class='notice'>You change RLD's mode to 'Deconstruct'.</span>")
/obj/item/construction/rld/proc/checkdupes(var/target)
. = list()
var/turf/checking = get_turf(target)
for(var/obj/machinery/light/dupe in checking)
if(istype(dupe, /obj/machinery/light))
. |= dupe
/obj/item/construction/rld/afterattack(atom/A, mob/user)
if(!range_check(A,user))
return
var/turf/start = get_turf(src)
switch(mode)
if(REMOVE_MODE)
if(istype(A, /obj/machinery/light/))
if(checkResource(deconcost, user))
to_chat(user, "<span class='notice'>You start deconstructing [A]...</span>")
user.Beam(A,icon_state="nzcrentrs_power",time=15)
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
if(do_after(user, decondelay, target = A))
if(!useResource(deconcost, user))
return 0
activate()
qdel(A)
return TRUE
return FALSE
if(LIGHT_MODE)
if(iswallturf(A))
var/turf/closed/wall/W = A
if(checkResource(floorcost, user))
to_chat(user, "<span class='notice'>You start building a wall light...</span>")
user.Beam(A,icon_state="nzcrentrs_power",time=15)
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
playsound(src.loc, 'sound/effects/light_flicker.ogg', 50, 0)
if(do_after(user, floordelay, target = A))
if(!istype(W))
return FALSE
var/list/candidates = list()
var/turf/open/winner = null
var/winning_dist = null
for(var/direction in GLOB.cardinals)
var/turf/C = get_step(W, direction)
var/list/dupes = checkdupes(C)
if(start.CanAtmosPass(C) && !dupes.len)
candidates += C
if(!candidates.len)
to_chat(user, "<span class='warning'>Valid target not found...</span>")
playsound(src.loc, 'sound/misc/compiler-failure.ogg', 30, 1)
return FALSE
for(var/turf/open/O in candidates)
if(istype(O))
var/x0 = O.x
var/y0 = O.y
var/contender = cheap_hypotenuse(start.x, start.y, x0, y0)
if(!winner)
winner = O
winning_dist = contender
else
if(contender < winning_dist) // lower is better
winner = O
winning_dist = contender
activate()
if(!useResource(wallcost, user))
return FALSE
var/light = get_turf(winner)
var/align = get_dir(winner, A)
var/obj/machinery/light/L = new /obj/machinery/light(light)
L.dir = align
L.color = color_choice
L.light_color = L.color
return TRUE
return FALSE
if(isfloorturf(A))
var/turf/open/floor/F = A
if(checkResource(floorcost, user))
to_chat(user, "<span class='notice'>You start building a floor light...</span>")
user.Beam(A,icon_state="nzcrentrs_power",time=15)
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
playsound(src.loc, 'sound/effects/light_flicker.ogg', 50, 1)
if(do_after(user, floordelay, target = A))
if(!istype(F))
return 0
if(!useResource(floorcost, user))
return 0
activate()
var/destination = get_turf(A)
var/obj/machinery/light/floor/FL = new /obj/machinery/light/floor(destination)
FL.color = color_choice
FL.light_color = FL.color
return TRUE
return FALSE
if(GLOW_MODE)
if(useResource(launchcost, user))
activate()
to_chat(user, "<span class='notice'>You fire a glowstick!</span>")
var/obj/item/device/flashlight/glowstick/G = new /obj/item/device/flashlight/glowstick(start)
G.color = color_choice
G.light_color = G.color
G.throw_at(A, 9, 3, user)
G.on = TRUE
G.update_brightness()
return TRUE
return FALSE
#undef GLOW_MODE
#undef LIGHT_MODE
#undef REMOVE_MODE