mirror of
https://github.com/goonstation/goonstation-2020.git
synced 2026-07-10 22:52:21 +01:00
425 lines
11 KiB
Plaintext
425 lines
11 KiB
Plaintext
/obj/grille
|
|
desc = "A sturdy metal mesh. Blocks large objects, but lets small items, gas, or energy beams through."
|
|
name = "grille"
|
|
icon = 'icons/obj/grille.dmi'
|
|
icon_state = "grille"
|
|
density = 1
|
|
stops_space_move = 1
|
|
var/health = 30
|
|
var/health_max = 30
|
|
var/ruined = 0
|
|
var/blunt_resist = 0
|
|
var/cut_resist = 0
|
|
var/corrode_resist = 0
|
|
var/temp_resist = 0
|
|
var/shock_when_entered = 1
|
|
anchored = 1
|
|
flags = FPRINT | CONDUCT | USEDELAY
|
|
pressure_resistance = 5*ONE_ATMOSPHERE
|
|
layer = GRILLE_LAYER
|
|
event_handler_flags = USE_HASENTERED | USE_FLUID_ENTER | USE_CANPASS
|
|
|
|
New()
|
|
..()
|
|
update_icon()
|
|
|
|
steel
|
|
New()
|
|
..()
|
|
var/datum/material/M = getMaterial("steel")
|
|
src.setMaterial(M)
|
|
|
|
steel/broken
|
|
desc = "Looks like its been in this sorry state for quite some time."
|
|
icon_state = "grille-cut"
|
|
ruined = 1
|
|
|
|
New()
|
|
..()
|
|
damage_slashing(1000)
|
|
update_icon()
|
|
|
|
catwalk
|
|
name = "catwalk surface"
|
|
icon_state = "catwalk"
|
|
density = 0
|
|
desc = "This doesn't look very safe at all!"
|
|
layer = CATWALK_LAYER
|
|
shock_when_entered = 0
|
|
|
|
cross //HEY YOU! YEAH, YOU LOOKING AT THIS. Use these for the corners of your catwalks!
|
|
name = "catwalk surface" //Or I'll murder you since you are making things ugly on purpose.
|
|
icon_state = "catwalk_cross" //(Statement does not apply when you actually want to use the other ones.)
|
|
|
|
onMaterialChanged()
|
|
..()
|
|
if (istype(src.material))
|
|
health_max = material.hasProperty("density") ? round(material.getProperty("density")) : 25
|
|
health = health_max
|
|
|
|
cut_resist = material.hasProperty("hard") ? material.getProperty("hard") : cut_resist
|
|
blunt_resist = material.hasProperty("density") ? material.getProperty("density") : blunt_resist
|
|
corrode_resist = material.hasProperty("corrosion") ? material.getProperty("corrosion") : corrode_resist
|
|
//temp_resist = material.hasProperty(PROP_MELTING) ? material.getProperty(PROP_MELTING) : temp_resist
|
|
if (blunt_resist != 0) blunt_resist /= 2
|
|
|
|
damage_blunt(var/amount)
|
|
if (!isnum(amount) || amount <= 0)
|
|
return
|
|
|
|
if (src.ruined)
|
|
if (amount >= health_max / 2)
|
|
qdel(src)
|
|
return
|
|
|
|
var/armor = 0
|
|
|
|
if (src.material)
|
|
armor = blunt_resist
|
|
|
|
if (src.material.quality >= 25)
|
|
armor += src.material.quality * 0.25
|
|
else if (src.quality < 10)
|
|
armor = 0
|
|
//amount += rand(1,3)
|
|
|
|
amount -= armor
|
|
|
|
src.health = max(0,min(src.health - amount,src.health_max))
|
|
if (src.health == 0)
|
|
update_icon("cut")
|
|
src.set_density(0)
|
|
src.ruined = 1
|
|
else
|
|
update_icon()
|
|
|
|
damage_slashing(var/amount)
|
|
if (!isnum(amount) || amount <= 0)
|
|
return
|
|
|
|
if (src.ruined)
|
|
drop_rods(1)
|
|
qdel(src)
|
|
return
|
|
|
|
amount = get_damage_after_percentage_based_armor_reduction(cut_resist,amount)
|
|
|
|
src.health = max(0,min(src.health - amount,src.health_max))
|
|
if (src.health == 0)
|
|
drop_rods(1)
|
|
update_icon("cut")
|
|
src.set_density(0)
|
|
src.ruined = 1
|
|
else
|
|
update_icon()
|
|
|
|
damage_corrosive(var/amount)
|
|
if (!isnum(amount) || amount <= 0)
|
|
return
|
|
|
|
if (src.ruined)
|
|
qdel(src)
|
|
return
|
|
|
|
amount = get_damage_after_percentage_based_armor_reduction(corrode_resist,amount)
|
|
src.health = max(0,min(src.health - amount,src.health_max))
|
|
if (src.health == 0)
|
|
update_icon("corroded")
|
|
src.set_density(0)
|
|
src.ruined = 1
|
|
else
|
|
update_icon()
|
|
|
|
damage_heat(var/amount)
|
|
if (!isnum(amount) || amount <= 0)
|
|
return
|
|
|
|
if (src.ruined)
|
|
qdel(src)
|
|
return
|
|
|
|
if (src.material)
|
|
if (amount * 100000 <= temp_resist)
|
|
// Not applying enough heat to melt it
|
|
return
|
|
|
|
src.health = max(0,min(src.health - amount,src.health_max))
|
|
if (src.health == 0)
|
|
update_icon("melted")
|
|
src.set_density(0)
|
|
src.ruined = 1
|
|
else
|
|
update_icon()
|
|
|
|
meteorhit(var/obj/M)
|
|
if (istype(M, /obj/newmeteor/massive))
|
|
qdel(src)
|
|
return
|
|
|
|
src.damage_blunt(5)
|
|
|
|
return
|
|
|
|
blob_act(var/power)
|
|
src.damage_blunt(3 * power / 20)
|
|
|
|
ex_act(severity)
|
|
switch(severity)
|
|
if(1.0)
|
|
src.damage_blunt(40)
|
|
src.damage_heat(40)
|
|
|
|
if(2.0)
|
|
src.damage_blunt(15)
|
|
src.damage_heat(15)
|
|
|
|
if(3.0)
|
|
src.damage_blunt(7)
|
|
src.damage_heat(7)
|
|
return
|
|
|
|
reagent_act(var/reagent_id,var/volume)
|
|
if (..())
|
|
return
|
|
switch(reagent_id)
|
|
if("acid")
|
|
damage_corrosive(volume / 2)
|
|
if("pacid")
|
|
damage_corrosive(volume)
|
|
if("phlogiston")
|
|
damage_heat(volume)
|
|
if("infernite")
|
|
damage_heat(volume * 2)
|
|
if("foof")
|
|
damage_heat(volume * 3)
|
|
|
|
hitby(AM as mob|obj)
|
|
..()
|
|
src.visible_message("<span style=\"color:red\"><B>[src] was hit by [AM].</B></span>")
|
|
playsound(src.loc, 'sound/impact_sounds/Metal_Hit_Light_1.ogg', 100, 1)
|
|
if (ismob(AM))
|
|
damage_blunt(5)
|
|
else if (isobj(AM))
|
|
var/obj/O = AM
|
|
if (O.throwforce)
|
|
damage_blunt(max(0.5, O.throwforce / blunt_resist)) // we don't want people screaming right through these and you can still get through them by kicking/cutting/etc
|
|
return
|
|
|
|
attack_hand(obj/M, mob/user)
|
|
if (!islist(user)) //mbc : what the fuck. who is passing a list as an arg here. WHY. WHY i cant find it
|
|
user.lastattacked = src
|
|
if(!shock(usr, 70))
|
|
var/damage = 1
|
|
var/dam_type = "blunt"
|
|
var/text = "[usr.kickMessage] [src]"
|
|
|
|
if (usr.is_hulk() && damage < 5)
|
|
damage = 10
|
|
text = "smashes [src] with incredible strength"
|
|
|
|
src.visible_message("<span style=\"color:red\"><b>[usr]</b> [text]!</span>")
|
|
playsound(src.loc, 'sound/impact_sounds/Metal_Hit_Light_1.ogg', 80, 1)
|
|
|
|
if (dam_type == "slashing")
|
|
damage_slashing(damage)
|
|
else
|
|
damage_blunt(damage)
|
|
|
|
attackby(obj/item/W, mob/user)
|
|
// Things that won't electrocute you
|
|
|
|
if (ispulsingtool(W) || istype(W, /obj/item/device/t_scanner))
|
|
var/net = get_connection()
|
|
if(!net)
|
|
boutput(user, "<span style=\"color:blue\">No electrical current detected.</span>")
|
|
else
|
|
boutput(user, "<span style=\"color:red\">CAUTION: Dangerous electrical current detected.</span>")
|
|
return
|
|
|
|
else if(istype(W, /obj/item/sheet/))
|
|
var/obj/item/sheet/S = W
|
|
if (S.material && S.material.material_flags & MATERIAL_CRYSTAL)
|
|
var/obj/window/WI
|
|
var/win_thin = 0
|
|
var/win_dir = 2
|
|
// var/turf/UT = get_turf(user)
|
|
var/turf/ST = get_turf(src)
|
|
|
|
/*
|
|
if (UT && isturf(UT) && ST && isturf(ST))
|
|
// We're inside the grill.
|
|
if (UT == ST)
|
|
win_dir = usr.dir
|
|
win_thin = 1
|
|
// We're trying to install a window while standing on an adjacent tile, so make it face the mob.
|
|
else
|
|
win_dir = turn(usr.dir, 180)
|
|
if (win_dir in list(NORTH, EAST, SOUTH, WEST))
|
|
win_thin = 1
|
|
|
|
win_thin = 0 //mbc : nah this is annoying. you can just make a thindow using the popup menu and push it into place anyway.
|
|
singh : if you're gonna disable it like this why not just comment out the entire thing and save the pointless checks
|
|
*/
|
|
|
|
if (ST && isturf(ST))
|
|
if (S.reinforcement)
|
|
if (map_settings)
|
|
if (win_thin)
|
|
WI = new map_settings.rwindows_thin (ST)
|
|
else
|
|
WI = new map_settings.rwindows (ST)
|
|
else
|
|
WI = new /obj/window/reinforced(ST)
|
|
|
|
else
|
|
if (map_settings)
|
|
if (win_thin)
|
|
WI = new map_settings.windows_thin (ST)
|
|
else
|
|
WI = new map_settings.windows(ST)
|
|
else
|
|
WI = new /obj/window(ST)
|
|
|
|
if (WI && istype(WI))
|
|
if (S.material)
|
|
WI.setMaterial(S.material)
|
|
WI.dir = win_dir
|
|
WI.ini_dir = win_dir
|
|
logTheThing("station", usr, null, "builds a [WI.name] (<b>Material:</b> [WI.material && WI.material.mat_id ? "[WI.material.mat_id]" : "*UNKNOWN*"]) at ([showCoords(usr.x, usr.y, usr.z)] in [usr.loc.loc])")
|
|
else
|
|
user.show_text("<b>Error:</b> Couldn't spawn window. Try again and please inform a coder if the problem persists.", "red")
|
|
return
|
|
|
|
S.amount--
|
|
if (S.amount < 1)
|
|
qdel(S)
|
|
return
|
|
else
|
|
..()
|
|
return
|
|
|
|
// electrocution check
|
|
|
|
var/OSHA_is_crying = 1
|
|
var/dmg_mod = 0
|
|
if ((src.material && src.material.hasProperty("electrical") && src.material.getProperty("electrical") < 30))
|
|
OSHA_is_crying = 0
|
|
|
|
if ((src.material && src.material.hasProperty("electrical") && src.material.getProperty("electrical") > 30))
|
|
dmg_mod = 60 - src.material.getProperty("electrical")
|
|
|
|
if (OSHA_is_crying && shock(user, 100 - dmg_mod))
|
|
return
|
|
|
|
// Things that will electrocute you
|
|
|
|
if (issnippingtool(W))
|
|
damage_slashing(src.health_max)
|
|
src.visible_message("<span style=\"color:red\"><b>[usr]</b> cuts apart the [src] with [W].</span>")
|
|
playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1)
|
|
|
|
else if (isscrewingtool(W) && (istype(src.loc, /turf/simulated) || src.anchored))
|
|
playsound(src.loc, 'sound/items/Screwdriver.ogg', 100, 1)
|
|
src.anchored = !( src.anchored )
|
|
src.visible_message("<span style=\"color:red\"><b>[usr]</b> [src.anchored ? "fastens" : "unfastens"] [src].</span>")
|
|
return
|
|
|
|
else
|
|
user.lastattacked = src
|
|
attack_particle(user,src)
|
|
src.visible_message("<span style=\"color:red\"><b>[usr]</b> attacks [src] with [W].</span>")
|
|
playsound(src.loc, 'sound/impact_sounds/Metal_Hit_Light_1.ogg', 80, 1)
|
|
switch(W.damtype)
|
|
if("fire")
|
|
damage_heat(W.force)
|
|
if("brute")
|
|
damage_blunt(W.force * 0.5)
|
|
return
|
|
|
|
proc/update_icon(var/special_icon_state)
|
|
if (ruined)
|
|
return
|
|
|
|
if (istext(special_icon_state))
|
|
icon_state = initial(icon_state) + "-" + special_icon_state
|
|
else
|
|
var/diff = get_fraction_of_percentage_and_whole(health,health_max)
|
|
switch(diff)
|
|
if(-INFINITY to 25)
|
|
icon_state = initial(icon_state) + "-3"
|
|
if(26 to 50)
|
|
icon_state = initial(icon_state) + "-2"
|
|
if(51 to 75)
|
|
icon_state = initial(icon_state) + "-1"
|
|
if(76 to INFINITY)
|
|
icon_state = initial(icon_state) + "-0"
|
|
|
|
proc/drop_rods(var/amount)
|
|
if (!isnum(amount))
|
|
return
|
|
var/obj/item/rods/R = new /obj/item/rods(get_turf(src))
|
|
R.amount = amount
|
|
if(src.material)
|
|
R.setMaterial(src.material)
|
|
else
|
|
var/datum/material/M = getMaterial("steel")
|
|
R.setMaterial(M)
|
|
|
|
proc/get_connection()
|
|
//returns the netnum of a stub cable at this grille loc, or 0 if none
|
|
var/turf/T = src.loc
|
|
if(!istype(T, /turf/simulated/floor))
|
|
return
|
|
|
|
for(var/obj/cable/C in T)
|
|
if(C.d1 == 0)
|
|
return C.netnum
|
|
|
|
return 0
|
|
|
|
proc/shock(mob/user, prb, var/ignore_gloves = 0)
|
|
// shock user with probability prb (if all connections & power are working)
|
|
// returns 1 if shocked, 0 otherwise
|
|
|
|
if (!anchored)// || ruined) // allowing ruined grilles to still be connected so people have to move carefully through them
|
|
// unanchored/ruined grilles are never connected
|
|
return 0
|
|
|
|
if (!prob(prb))
|
|
return 0
|
|
|
|
var/net = get_connection()
|
|
// find the powernet of the connected cable
|
|
|
|
if (!net)
|
|
// cable is unpowered
|
|
return 0
|
|
|
|
return src.electrocute(user, prb, net, ignore_gloves)
|
|
|
|
CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
|
|
if (istype(mover, /obj/projectile))
|
|
if (density)
|
|
return prob(50)
|
|
return 1
|
|
|
|
if (density && istype(mover, /obj/window))
|
|
return 1
|
|
|
|
return ..()
|
|
|
|
HasEntered(AM as mob|obj)
|
|
..()
|
|
if (src.shock_when_entered)
|
|
if (ismob(AM))
|
|
if (!isliving(AM) || isintangible(AM)) // I assume this was left out by accident (Convair880).
|
|
return
|
|
var/mob/M = AM
|
|
if (M.client && M.client.flying) // noclip
|
|
return
|
|
var/s_chance = 10
|
|
if (M.m_intent != "walk") // move carefully
|
|
s_chance += 50
|
|
if (shock(M, s_chance, rand(0,1))) // you get a 50/50 shot to accidentally touch the grille with something other than your hands
|
|
M.show_text("<b>You brush against [src] while moving past it and it shocks you!</b>", "red")
|